溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

SpringBoot 使用jwt進(jìn)行身份驗(yàn)證的方法示例

發(fā)布時(shí)間:2020-10-26 09:44:42 來源:腳本之家 閱讀:177 作者:hongda''s blog 欄目:編程語言

這里只供參考,比較使用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;
  }

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

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI