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

时间:2021-07-28 12:17:19

这里只供参考,比较使用jwt方式进行身份验证感觉不好,最不行的就是不能退出

登陆时设定多长过期时间,只能等这个时间过了以后才算退出,服务端只能验证请求过来的token是否通过验证

code:

?
1
2
3
4
5
6
7
8
9
10
/**
 * created by qhong on 2018/6/7 15:34
 * 标注该注解的,就不需要登录
 **/
@target({elementtype.method,elementtype.type})
@retention(retentionpolicy.runtime)
@documented
public @interface authignore {
 
}

loginuser:

?
1
2
3
4
5
@target(elementtype.parameter)
@retention(retentionpolicy.runtime)
public @interface loginuser {
 
}

jwtutil:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
@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配置:

?
1
2
3
4
5
# 加密秘钥
jwt.secret=f4e2e52034348f86b67cde581c0f9eb5
# token有效时长,单位秒
jwt.expire=60000
jwt.header=token

拦截器:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**
 * 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;
  }
}

注解拦截:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@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注解使用:

?
1
2
3
4
@requestmapping(value="/query2",method= requestmethod.post)
  public user query2(@loginuser user u){
     return u;
  }

http://www.zzvips.com/article/172755.html
https://gitee.com/renrenio/renren-fast

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

原文链接:https://www.cnblogs.com/hongdada/p/9152291.html