SpringBoot 使用jwt進行身份驗證的方法示例
這里只供參考,比較使用jwt方式進行身份驗證感覺不好,最不行的就是不能退出
登陸時設定多長過期時間,只能等這個時間過了以后才算退出,服務端只能驗證請求過來的token是否通過驗證
Code:
/**
* Created by qhong on 2018/6/7 15:34
* 標注該注解的,就不需要登錄
**/
@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();
//過期時間
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有效時長,單位秒 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注解,則不驗證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() + "失效,請重新登錄", HttpStatus.UNAUTHORIZED.value());
}
//設置userId到request里,后續(xù)根據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://www.dhdzp.com/article/153172.htm
https://gitee.com/renrenio/renren-fast
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
SpringBoot整合SpringSecurityOauth2實現鑒權動態(tài)權限問題
這篇文章主要介紹了SpringBoot整合SpringSecurityOauth2實現鑒權-動態(tài)權限,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-06-06
Java使用Spring JdbcTemplate向in語句中傳遞參數的教程詳解
這篇文章主要給大家介紹Java如何使用Spring JdbcTemplate向in語句中傳遞參數,文中有詳細的流程步驟和代碼示例,需要的朋友可以參考下2023-07-07
Hibernate基于ThreadLocal管理Session過程解析
這篇文章主要介紹了Hibernate基于ThreadLocal管理Session過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-10-10

