SpringBoot 使用jwt进行身份验证的方法示例

 更新时间:2018年12月21日 10:47:10   作者:hongda''s blog  
这篇文章主要介绍了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里,后续根据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;
  }

https://www.jb51.net/article/153172.htm
https://gitee.com/renrenio/renren-fast

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot整合SpringSecurityOauth2实现鉴权动态权限问题

    SpringBoot整合SpringSecurityOauth2实现鉴权动态权限问题

    这篇文章主要介绍了SpringBoot整合SpringSecurityOauth2实现鉴权-动态权限,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • Java一致性Hash算法的实现详解

    Java一致性Hash算法的实现详解

    这篇文章主要介绍了Java一致性Hash算法的实现详解,hash的意思是散列,目的将一组输入的数据均匀的分开、打散,往往用来配合路由算法做负载均衡,多用在分布式系统中,需要的朋友可以参考下
    2024-01-01
  • springboot Long 精度丢失问题解决

    springboot Long 精度丢失问题解决

    这篇文章主要为大家介绍了解决springboot Long 精度丢失问题的方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • Java基础教程之组合(composition)

    Java基础教程之组合(composition)

    这篇文章主要介绍了Java基础教程之组合(composition),组合是在Java中实现程序复用(reusibility)的基本手段之一,需要的朋友可以参考下
    2014-08-08
  • java使用tess4j进行图片文字识别功能

    java使用tess4j进行图片文字识别功能

    Tess4J 是Java (JNA) 对 Tesseract OCR API 的封装,Tess4J是java直接可使用的jar包,而Tesseract OCR是支持Tess4J进文件文字识别的基础,Tess4J可直接使用Maven方式引入,这篇文章主要介绍了java使用tess4j进行图片文字识别,需要的朋友可以参考下
    2023-04-04
  • 使用游长编码对字符串压缩 Run Length编码示例

    使用游长编码对字符串压缩 Run Length编码示例

    这篇文章主要介绍了Run Length编码的一个示例,大家参考使用吧
    2014-01-01
  • Java指令重排引发问题及解决方案

    Java指令重排引发问题及解决方案

    指令重排是JVM在解释执行Java代码时对指令顺序进行重新排列的一种优化技术,本文主要介绍了Java指令重排引发问题及解决方案,感兴趣的可以了解一下
    2023-08-08
  • Java使用Spring JdbcTemplate向in语句中传递参数的教程详解

    Java使用Spring JdbcTemplate向in语句中传递参数的教程详解

    这篇文章主要给大家介绍Java如何使用Spring JdbcTemplate向in语句中传递参数,文中有详细的流程步骤和代码示例,需要的朋友可以参考下
    2023-07-07
  • Hibernate基于ThreadLocal管理Session过程解析

    Hibernate基于ThreadLocal管理Session过程解析

    这篇文章主要介绍了Hibernate基于ThreadLocal管理Session过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Java实战之飞翔的小鸟小游戏

    Java实战之飞翔的小鸟小游戏

    这篇文章主要介绍了Java实战之飞翔的小鸟小游戏,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-04-04

最新评论