SpringBoot 使用jwt進(jìn)行身份驗(yàn)證的方法示例
這里只供參考,比較使用jwt方式進(jìn)行身份驗(yàn)證感覺不好,最不行的就是不能退出
登陸時(shí)設(shè)定多長過期時(shí)間,只能等這個(gè)時(shí)間過了以后才算退出,服務(wù)端只能驗(yàn)證請(qǐng)求過來的token是否通過驗(yàn)證
Code:
/**
* Created by qhong on 2018/6/7 15:34
* 標(biāo)注該注解的,就不需要登錄
**/
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AuthIgnore {
}
LoginUser:
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginUser {
}
JwtUtil:
@ConfigurationProperties(prefix = "jwt")
@Component
public class JwtUtils {
private Logger logger = LoggerFactory.getLogger(getClass());
private String secret;
private long expire;
private String header;
/**
* 生成jwt token
*/
public String generateToken(long userId) {
Date nowDate = new Date();
//過期時(shí)間
Date expireDate = new Date(nowDate.getTime() + expire * 1000);
return Jwts.builder()
.setHeaderParam("typ", "JWT")
.setSubject(userId+"")
.setIssuedAt(nowDate)
.setExpiration(expireDate)
.signWith(io.jsonwebtoken.SignatureAlgorithm.HS512, secret)
.compact();
}
public Claims getClaimByToken(String token) {
try {
return Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
}catch (Exception e){
logger.debug("validate is token error ", e);
return null;
}
}
/**
* token是否過期
* @return true:過期
*/
public boolean isTokenExpired(Date expiration) {
return expiration.before(new Date());
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public long getExpire() {
return expire;
}
public void setExpire(long expire) {
this.expire = expire;
}
public String getHeader() {
return header;
}
public void setHeader(String header) {
this.header = header;
}
}
application.properties配置:
# 加密秘鑰 jwt.secret=f4e2e52034348f86b67cde581c0f9eb5 # token有效時(shí)長,單位秒 jwt.expire=60000 jwt.header=token
攔截器:
/**
* Created by qhong on 2018/6/7 15:36
**/
@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
@Autowired
private JwtUtils jwtUtils;
public static final String USER_KEY = "userId";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
AuthIgnore annotation;
if(handler instanceof HandlerMethod) {
annotation = ((HandlerMethod) handler).getMethodAnnotation(AuthIgnore.class);
}else{
return true;
}
//如果有@AuthIgnore注解,則不驗(yàn)證token
if(annotation != null){
return true;
}
//獲取用戶憑證
String token = request.getHeader(jwtUtils.getHeader());
if(StringUtils.isBlank(token)){
token = request.getParameter(jwtUtils.getHeader());
}
//token憑證為空
if(StringUtils.isBlank(token)){
throw new AuthException(jwtUtils.getHeader() + "不能為空", HttpStatus.UNAUTHORIZED.value());
}
Claims claims = jwtUtils.getClaimByToken(token);
if(claims == null || jwtUtils.isTokenExpired(claims.getExpiration())){
throw new AuthException(jwtUtils.getHeader() + "失效,請(qǐng)重新登錄", HttpStatus.UNAUTHORIZED.value());
}
//設(shè)置userId到request里,后續(xù)根據(jù)userId,獲取用戶信息
request.setAttribute(USER_KEY, Long.parseLong(claims.getSubject()));
return true;
}
}
注解攔截:
@Component
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
private UserService userService;
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().isAssignableFrom(User.class) && parameter.hasParameterAnnotation(LoginUser.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
NativeWebRequest request, WebDataBinderFactory factory) throws Exception {
//獲取用戶ID
Object object = request.getAttribute(AuthorizationInterceptor.USER_KEY, RequestAttributes.SCOPE_REQUEST);
if(object == null){
return null;
}
//獲取用戶信息
User user = userService.selectById((Long)object);
return user;
}
}
WebConfig:
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Autowired
private AuthorizationInterceptor authorizationInterceptor;
@Autowired
private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authorizationInterceptor).addPathPatterns("/**");
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(loginUserHandlerMethodArgumentResolver);
}
}
Login:
@PostMapping("/login")
@AuthIgnore
public R login2(@RequestBody User u){
//用戶登錄
long userId =userService.addUser(u);
//生成token
String token = jwtUtils.generateToken(userId);
Map<String, Object> map = new HashMap<>();
map.put("token", token);
map.put("expire", jwtUtils.getExpire());
return R.ok(map);
}
LoginUser注解使用:
@RequestMapping(value="/query2",method= RequestMethod.POST)
public User Query2(@LoginUser User u){
return u;
}
http://chabaoo.cn/article/153172.htm
https://gitee.com/renrenio/renren-fast
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
MyEclipse去除網(wǎng)上復(fù)制下來的代碼帶有的行號(hào)(正則去除行號(hào))
這篇文章主要介紹了MyEclipse去除網(wǎng)上復(fù)制下來的代碼帶有的行號(hào)(正則去除行號(hào))的相關(guān)資料,需要的朋友可以參考下2017-10-10
Java設(shè)計(jì)模式中的代理設(shè)計(jì)模式詳細(xì)解析
這篇文章主要介紹了Java設(shè)計(jì)模式中的代理設(shè)計(jì)模式詳細(xì)解析,代理模式,重要的在于代理二字,何為代理,我們可以聯(lián)想到生活中的例子,比如秘書、中介這類職業(yè),我們可以委托中介去幫我們完成某些事情,而我們自己只需要關(guān)注我們必須完成的事情,需要的朋友可以參考下2023-12-12
SpringMVC接收前臺(tái)傳遞過來的值的實(shí)例
下面小編就為大家分享一篇SpringMVC接收前臺(tái)傳遞過來的值的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-03-03
Java中ThreadLocal?導(dǎo)致內(nèi)存?OOM?的原因分析
這篇文章主要介紹了Java中ThreadLocal導(dǎo)致內(nèi)存OOM的原因分析,文章基于Java的相關(guān)內(nèi)容展開ThreadLocal導(dǎo)致內(nèi)存OOM的原因分析,需要的小伙v阿布可以參考一下2022-05-05
使用游長編碼對(duì)字符串壓縮 Run Length編碼示例
這篇文章主要介紹了Run Length編碼的一個(gè)示例,大家參考使用吧2014-01-01

