一、token解决问题的背景:
1、 单点登录,
2、分布式登录状态,
3、在信任期内 避免 重新输入用户名密码登录。
4、跨系统免登陆等。
5、一些接口的请求权限验证。
总结以上token最终都是为了解决在在分布式系统中信任期内 避免 重新输入用户名密码登录。
二、token的常见验证流程:
1、用户提交用户名、密码到服务器后台。
2、后台验证用户信息的正确性。
3、若用户验证通过,服务器端生成Token,返回到客户端。
4、客户端保存Token,再下一次请求资源时,附带上Token信息。
5、服务器端 验证Token是否由服务器签发的。
6、若Token验证通过,则返回需要的资源。
三、那么如何处理token:
1、解决安全问题,就需要加密,和有效期
2、解决信任问题,就要生产包含用户账号,密码相关的信息
3、解决唯一性问题,就要用到签名
4、解决体验问题,就要使用到自动刷新。
上面4点就是实现token的需求。
四、现在以JWTUtil工具类为例看源码是如何现实的:
1、创建token
源码赏析,一共有4种token生产方式。
从传入参数方式中可以看出主要有两个重要信息。
一个是秘钥(或者签名),一个荷载信息(用户登录的相关信息)。那它就可以成为一个凭证了 。
/**
* 创建HS256(HmacSHA256) JWT Token
*
* @param payload 荷载信息
* @param key HS256(HmacSHA256)密钥
* @return JWT Token
*/
public static String createToken(Map<String, Object> payload, byte[] key) {
return createToken(null, payload, key);
}
/**
* 创建HS256(HmacSHA256) JWT Token
*
* @param headers 头信息
* @param payload 荷载信息
* @param key HS256(HmacSHA256)密钥
* @return JWT Token
*/
public static String createToken(Map<String, Object> headers, Map<String, Object> payload, byte[] key) {
return JWT.create()
.addHeaders(headers)
.addPayloads(payload)
.setKey(key)
.sign();
}
/**
* 创建JWT Token
*
* @param payload 荷载信息
* @param signer 签名算法
* @return JWT Token
*/
public static String createToken(Map<String, Object> payload, JWTSigner signer) {
return createToken(null, payload, signer);
}
/**
* 创建JWT Token
*
* @param headers 头信息
* @param payload 荷载信息
* @param signer 签名算法
* @return JWT Token
*/
public static String createToken(Map<String, Object> headers, Map<String, Object> payload, JWTSigner signer) {
return JWT.create()
.addHeaders(headers)
.addPayloads(payload)
.setSigner(signer)
.sign();
}
2、token和转换成可解析对象。
这一步是为了能从token转化出可解析的对象信息。
/**
* 解析JWT Token
*
* @param token token
* @return {@link JWT}
*/
public static JWT parseToken(String token) {
return JWT.of(token);
}
3、检验token,对应的有两种。分别是根据秘钥和签名
/**
* 验证JWT Token有效性
*
* @param token JWT Token
* @param key HS256(HmacSHA256)密钥
* @return 是否有效
*/
public static boolean verify(String token, byte[] key) {
return JWT.of(token).setKey(key).verify();
}
/**
* 验证JWT Token有效性
*
* @param token JWT Token
* @param signer 签名器
* @return 是否有效
*/
public static boolean verify(String token, JWTSigner signer) {
return JWT.of(token).verify(signer);
}
整个工具类完整源码:
package cn.hutool.jwt;
import cn.hutool.jwt.signers.JWTSigner;
import java.util.Map;
/**
* JSON Web Token (JWT)工具类
*/
public class JWTUtil {
/**
* 创建HS256(HmacSHA256) JWT Token
*
* @param payload 荷载信息
* @param key HS256(HmacSHA256)密钥
* @return JWT Token
*/
public static String createToken(Map<String, Object> payload, byte[] key) {
return createToken(null, payload, key);
}
/**
* 创建HS256(HmacSHA256) JWT Token
*
* @param headers 头信息
* @param payload 荷载信息
* @param key HS256(HmacSHA256)密钥
* @return JWT Token
*/
public static String createToken(Map<String, Object> headers, Map<String, Object> payload, byte[] key) {
return JWT.create()
.addHeaders(headers)
.addPayloads(payload)
.setKey(key)
.sign();
}
/**
* 创建JWT Token
*
* @param payload 荷载信息
* @param signer 签名算法
* @return JWT Token
*/
public static String createToken(Map<String, Object> payload, JWTSigner signer) {
return createToken(null, payload, signer);
}
/**
* 创建JWT Token
*
* @param headers 头信息
* @param payload 荷载信息
* @param signer 签名算法
* @return JWT Token
*/
public static String createToken(Map<String, Object> headers, Map<String, Object> payload, JWTSigner signer) {
return JWT.create()
.addHeaders(headers)
.addPayloads(payload)
.setSigner(signer)
.sign();
}
/**
* 解析JWT Token
*
* @param token token
* @return {@link JWT}
*/
public static JWT parseToken(String token) {
return JWT.of(token);
}
/**
* 验证JWT Token有效性
*
* @param token JWT Token
* @param key HS256(HmacSHA256)密钥
* @return 是否有效
*/
public static boolean verify(String token, byte[] key) {
return JWT.of(token).setKey(key).verify();
}
/**
* 验证JWT Token有效性
*
* @param token JWT Token
* @param signer 签名器
* @return 是否有效
*/
public static boolean verify(String token, JWTSigner signer) {
return JWT.of(token).verify(signer);
}
}