1、Token
Token英文直译过去是“令牌”的意思,什么是令牌,在现代你要通过城门须要的也是令牌,而在计算机系统中要通过的是计算机的大门。
现代的大门由士兵守卫,而计算机系统的大门也有“士兵”,如果你没有一个无效的令牌就无奈通过,只能从哪来回哪去。
2、POM依赖
<dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.10.3</version></dependency>
3、生成Token
public static String getAdminToken(Admin admin) { long time = System.currentTimeMillis() + (1000 * 60 * 60 * 24); Date date = new Date(); date.setTime(time); return JWT.create() .withAudience(admin.getId()) // 将用户ID存入token中 .withExpiresAt(date) // 设置过期工夫 .sign(Algorithm.HMAC256(admin.getId()));// 设置私钥为用户ID}
如上办法会返回一个一段字符串:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIxIiwiZXhwIjoxNjUyMDAzMjM4fQ.cEkaKlNiA7OMJAv5hZI9hmRksujg08l00BwzpwwfhpE
如上Token中含有两个英文点,这两个英文点可将字符串分为三段。
第一段-头部(Header)
咱们通过应用Base64解码第一段后失去如下内容:
{ "typ":"JWT", "alg":"HS256"}
下面形容了咱们应用了HS256算法对Token进行了签名。
第二段-负载(Payload)
咱们通过应用Base64解码第二段后失去如下内容:
{ "aud":"1", "exp":1652003238}
这里的内容不是必须的,是之前咱们在生成Token时设置的一些内容。
aud(audience)能够了解为读者,如果客户端有多个类型,那么咱们在散发Token时就能够约定一个类型,以便在验证时进行辨别。
exp(expiration time)是过期工夫,也是咱们在生成Token时做的约定。
第二段负载中的内容能够自定义,然而这段内容并没有被加密,所以不要将明码等敏感信息放在这里。
第三段-签名(Signature)
咱们通过应用Base64解码第三段后失去如下内容:
pI*Sb$=ddt3
是一段乱码,须要应用第一段中加密形式并配合私钥才能够解码其中的内容。
4、验证Token
String token = request.getHeader("token");String adminID = request.getHeader("adminID");if (token == null ) { returnJson(response, "申请未受权"); return false;}// 解码DecodedJWT decode = JWT.decode(token);// 验证密钥是否正确Algorithm algorithm = Algorithm.HMAC256(adminID);algorithm.verify(decode);// 有效期是否超时Date expiresAt = decode.getExpiresAt();if(expiresAt.getTime()<System.currentTimeMillis()){ returnJson(response, "Token未受权或已超时"); return false;}return true;
验证Token是否正确倡议在拦截器或过滤器中进行,这里返回true示意Token无效,false为有效,有效的Token会被拦挡,不会持续向下执行,管制层不会解决该申请。
5、降级Token安全性
咱们能够在下面看出,在验证Token时会判断Token是否生效,然而Token过期工夫在Payload中是非加密状态,也就是能够被批改,所以咱们能够在服务端设置一个验证机制。
咱们能够应用Redis作为存储Token时效的容器,在验证Token是否无效时能够对Redis进行拜访验证;如果不想增加Redis的依赖,能够本地封装一个有时效的Map汇合对Token进行保留。
本文由博客一文多发平台 OpenWrite 公布!