山东掌趣网络科技
1、支持跨域访问,将token置于请求头中,而cookie是不支持跨域访问的;
2、无状态化,服务端无需存储token,只需要验证token信息是否正确即可,而session需要在服务端存储,一般是通过cookie中的sessionID在服务端查找对应的session;
3、无需绑定到一个特殊的身份验证方案(传统的用户名密码登陆),只需要生成的token是符合我们预期设定的即可;
4、更适用于移动端(Android,IOS,小程序等等),像这种原生平台不支持cookie,比如说微信小程序,每一次请求都是一次会话,当然我们可以每次去手动为他添加cookie,详情请查看博主另一篇博客;
5、避免CSRF跨站伪造攻击,还是因为不依赖cookie;
6、非常适用于RESTful API,这样可以轻易与各种后端(JAVA,.net,Python......)相结合,去耦合
还有一些优势这里就不一一列举了。
JWT:JSON Web Token,其实token就是一段字符串,由三部分组成:Header,Payload,Signature。详细情况请自行百度,现在,上代码。
山东掌趣网络科技
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
</dependency>
//加密的数据
int userId = 51;
//加密的签名
Algorithm algorithm = Algorithm.Hmac256("eyJhbGciO");
//加密头
Map<String, Object> header = new HashMap<String, Object>();
header.put("typ", "JWT");
header.put("alg", "HS256");
try {
//超时时间
Date date = new Date(System.currentTimeMillis() + 30 * 1000);
//令牌token
String token = JWT.create().withHeader(header).withClaim("userId", userId).withExpiresAt(date)
.sign(algorithm);
System.out.println(token);
} catch (Exception e) {
// TODO: handle exception
}
//前端传过来的令牌
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1Nzg1NTEyOTgsInVzZXJJZCI6ImhlbGxvIn0.mVXwBkBMO-Sr3FJPZSVLezUuxdvMwNsGgRqTCVufH8o";
//和上面一样的签名
Algorithm algorithm = Algorithm.HMAC256("eyJhbGciO");
JWTVerifier verifier = JWT.require(algorithm).build();
//开始解密,失败的话会出现异常
DecodedJWT jwt = verifier.verify(token);
System.out.println(jwt.getClaim("userId").asInt());
山东掌趣网络科技
public class JWTUtil {
private static final String TOKEN_SECRET = "eyJhbGciO";
private static final String CLAIM_NAME = "sign";
private static final long EXPIRE_TIME = 15 * 60 * 1000;
public static String sign(String sign) {
try {
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
Map<String, Object> header = new HashMap<String, Object>();
header.put("typ", "JWT");
header.put("alg", "HS256");
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
String token = JWT.create().withHeader(header).withClaim(CLAIM_NAME, sign).withExpiresAt(date)
.sign(algorithm);
return token;
} catch (Exception e) {
return null;
}
}
public static String verify(String token) {
try {
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT jwt = verifier.verify(token);
return jwt.getClaim(CLAIM_NAME).asString();
} catch (Exception e) {
return null;
}
}
}
山东掌趣网络科技