主要代码
1 //JWT 默认过期时间,3600L,单位秒 2 Long expireSecond = 3600L; 3 //盐值 4 String newSalt = 666; 5 String token = JwtUtil.generateToken(user.getUsername(), newSalt, 6 Duration.ofSeconds(expireSecond));
JwtUtil.generateToken方法
1 /** 2 * 生成JWT Token 3 * 4 * @param username 用户名 5 * @param salt 盐值 6 * @param expireDuration 过期时间和单位 7 * @return token 8 */ 9 public static String generateToken(String username, String salt, Duration expireDuration) { 10 try { 11 if (StringUtils.isBlank(username)) { 12 log.error("username不能为空"); 13 return null; 14 } 15 log.debug("username:{}", username); 16 17 // 如果盐值为空,则使用默认值:666666 18 if (StringUtils.isBlank(salt)) { 19 salt = "666666; 20 } 21 22 // 过期时间,单位:秒 23 Long expireSecond; 24 // 默认过期时间为1小时 3600L 单位秒 25 if (expireDuration == null) { 26 expireSecond = "3600L"; 27 } else { 28 expireSecond = expireDuration.getSeconds(); 29 } 30 Date expireDate = DateUtils.addSeconds(new Date(), expireSecond.intValue()); 31 32 // 生成token 33 Algorithm algorithm = Algorithm.HMAC256(salt); 34 String token = JWT.create() 35 .withClaim(CommonConstant.JWT_USERNAME, username) 36 // jwt唯一id 37 .withJWTId(UUIDUtil.getUuid()) 38 // 签发人 39 .withIssuer("") 40 // 主题 41 .withSubject("") 42 // 签发的目标 43 .withAudience("") 44 // 签名时间 45 .withIssuedAt(new Date()) 46 // token过期时间 47 .withExpiresAt(expireDate) 48 // 签名 49 .sign(algorithm); 50 return token; 51 } catch (Exception e) { 52 log.error("generateToken exception", e); 53 } 54 return null; 55 }
一些概念
JSON Web Token(JWT),是目前最流行的跨域认证解决方案。
JWT的原理
服务器认证以后,生成一个JSON格式的对象返回给客户端。之后客户端与服务端通信的时候,都要发回这个JSON对象。服务器完全根据这个对象认证用户身份。
JWT的组成
JWT 由三部分组成,它们之间圆点(.)连接。这个三部分分别是:
Header
Payload
Signature
一个典型的JWT看起来是这个样子的: xxxxx.yyyyy.zzzzz
Header
header典型的由两部分组成:token的类型比如JWT、算法名称比如HMAC SHA256。
Payload
载荷,它包含声明(要求)。声明是关于实体和其他数据的声明。声明有三种类型:registered、public和private。
- Registered claims : 这里有一组预定义的声明,它们不是强制的,但是推荐。比如:iss (issuer), exp (expiration time), sub (subject), aud (audience)等。
- Public claims : 可以随意定义。
- Private claims : 用于在同意使用它们的各方之间共享信息,并且不是注册的或公开的声明。
{ "iss": "Online JWT Builder", "iat": 1416797419, "exp": 1448333419, "aud": "www.example.com", "sub": "jrocket@example.com", "GivenName": "Johnny", "Surname": "Rocket", "Email": "jrocket@example.com", "Role": [ "Manager", "Project Administrator" ] }
iss: 该JWT的签发者,是否使用是可选的;
sub: 该JWT所面向的用户,是否使用是可选的;
aud: 接收该JWT的一方,是否使用是可选的;
exp(expires): 什么时候过期,这里是一个Unix时间戳,是否使用是可选的;
iat(issued at): 在什么时候签发的(UNIX时间),是否使用是可选的;
其他还有:nbf (Not Before):如果当前时间在nbf里的时间之前,则Token不被接受;一般都会留一些余地,比如几分钟,是否使用是可选的
将上面的JSON对象进行[base64编码]可以得到下面的字符串。这个字符串我们将它称作JWT的Payload(载荷)。
eyJpc3MiOiJKb2huIFd1IEpXVCIsImlhdCI6MTQ0MTU5MzUwMiwiZXhwIjoxNDQxNTk0NzIyLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiZnJvbV91c2VyIjoiQiIsInRhcmdldF91c2VyIjoiQSJ9
注意,不要在JWT的payload或header中放置敏感信息,除非它们是加密的。
Signature
将上面Header、Payload编码后的字符串都用.依次连接起来后用一个密钥,就形成了签名。
具体如下图所示:
可学习的相关博客(学习更深的知识)