欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-03-03 21:09:40
这里只供参考,比较使用jwt方式进行身份验证感觉不好,最不行的就是不能退出 登陆时设定多长过期时间,只能等这个时间过了以后才算退出,服务端只能验证请求过来的token是否...

这里只供参考,比较使用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;
  }



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