文章目录
写在前面
JWT(JSON Web Token),看到Token,估计都能猜出他是干啥的了,对,就是用来登录验证的,为啥会聊到JWT呢,之前我做登录验证用的是Cookie和Session,感觉没啥问题,现在我要对我的新闻博客项目做一个版本更新,也就是更新为前后端分离的,这样一改,Cookie不行了,查阅了点资料,并问了问老师,才明白,原来是浏览器为了安全起见,不支持第三方的Cookie了,被迫,把登录验证改用了JWT。
如何使用
学以致用,如何在我们的代码中使用JWT呢,很简单,只需要引入JWT的依赖就可以了,JWT能干什么呢,JWT可以把你需要传的信息封装到一个由.
分割的字符串中,当我们进行登录验证的时候,只需要对该字符串验证即可。
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
引入之后,我们就可以使用JWT提供的API了,为了方便起见,我们一般会封装一个JWTUtils工具类。
public class JWTUtils {
private static String SIGN = "TOKEN!@FE123";
/**
* 传入payload信息,生成token,默认保存7天
* @param map
* @return
*/
public static String getToken(Map<String, String> map) {
JWTCreator.Builder builder = JWT.create();
map.forEach((k,v) -> {
builder.withClaim(k,v);
});
Calendar instance = Calendar.getInstance();
instance.add(Calendar.DATE,7);
builder.withExpiresAt(instance.getTime());
return builder.sign(Algorithm.HMAC256(SIGN));
}
/**
* 验证token
* @param token
*/
public static void verify(String token) {
JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
}
/**
* 获取token中的信息
* @param token
* @return
*/
public static DecodedJWT getToken(String token) {
return JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
}
}
该工具类的使用也很nice,如果我们要把用户的一些信息封装起来,放到header里响应给前端。
Map<String, String> payload = new HashMap<>();
payload.put("userId",String.valueOf(user.getUserId()));
payload.put("username",user.getUsername());
payload.put("headUrl",user.getHeadUrl());
payload.put("userType",String.valueOf(user.getUserType()));
String token = JWTUtils.getToken(payload);
response.addHeader("token",token);
而当我们要对用户进行验证的时候,只需要调用verify方法
String token = request.getHeader("token");
try {
JWTUtils.verify(token);// 验证令牌
return true;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return false;
还有一个重要的点
由于是前后端分离的,在进行配置跨域访问的时候,我们还需要指定一下那个header里的token
/**
* 配置跨域访问
* @return
*/
private CorsConfiguration corsConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");// 同源配置,*表示任何请求都视为同源,若需指定ip和端口可以改为如“localhost:8080”,多个以“,”分隔;
corsConfiguration.addAllowedHeader("*"); // header,允许哪些header
corsConfiguration.addAllowedMethod("*"); // 允许的请求方法,PSOT、GET、PUT等
corsConfiguration.addExposedHeader("token");// 拓展header 浏览器放过redponse的token 不然跨域登录收不到token
corsConfiguration.setAllowCredentials(true);// 允许浏览器携带cookie
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig());
return new CorsFilter(source);
}
写在后面
很多问题的解决方案,并不是你不会,而是你不知道。