JWT的实战
JWT我们可以将它用来授权,我们登陆用户后,我们将我们的用户名密码都存入jwt中,我们得到该jwt,后续我们需要时,可以传入jwt,当我们需要该数据时,我们可以解析该jwt,将我们需要的数据全部解析出来,而且jwt的数据量很小,传输速度十分的快
我们一般封装三个方法,一个方法是生成jwt,一个方法就验证jwt,还有一个方法就解析jwt,获取jwt中的payload
pom依赖:
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
封装类:
public class JWTuntils {
private static final String SING="!Q@W#E$R";//公共使用,生成需要,解析需要
/**
* 生成token header.payload.sing
*/
public static String getToken(Map<String,String> map) {
//令牌的生成,获取
Calendar instance =Calendar.getInstance();
instance.add(Calendar.DATE,7);//从现在开始7天
//创建jwt builder
JWTCreator.Builder builder =JWT.create();
//payload,拉姆达表达式
map.forEach((k,v)->{
builder.withClaim(k,v);
});
//sign
String token = builder.withExpiresAt(instance.getTime())
.sign(Algorithm.HMAC256(SING));
System.out.println("令牌生成成功:"+ token);
return token;
}
/**
* 验证token 合法性
*/
public static void verify(String token){
JWT.require(Algorithm.HMAC256(SING)).build().verify(token);
}
/**
* 获取token信息方法
*/
public static DecodedJWT getTokenInfo(String token){
DecodedJWT verify =JWT.require(Algorithm.HMAC256(SING)).build().verify(token);
int id = verify.getClaim("id").asInt();
System.out.println(id);
return verify;
}
}
这是一种封装的方法,还有一个我自己觉得比较好用的,不会拉姆达表达式的可以选择这种方法
方法不一样,所有引入maven依赖也不一样
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
/**
* jwt封装类
*/
public class JWTUntils{
public static final String SUBJECT ="xdclass";
public static final long EXPIRE=1000*60*60*24*7;//过期时间,毫秒,一周
public static final String APPSECRET="xd666"; //秘钥
/**
* 生成 Jwt
* @param userBean
* @return
*/
public static String geneJsonWebToken(UserBean userBean){
if(userBean==null||userBean.getId()==0||userBean.getName()==null||userBean.getPassword()==null){
return null;
}
String token = Jwts.builder().setSubject(SUBJECT)
.claim("id",userBean.getId())//申明id
.claim("name",userBean.getName())//申明name
.claim("password",userBean.getPassword())//申明password
.setIssuedAt(new Date()) //SetIsuseAt发行时间
.setExpiration(new Date(System.currentTimeMillis()+EXPIRE)) //setExpiration:过期时间,
.signWith(SignatureAlgorithm.HS256,APPSECRET).compact(); //signWith里面定义算法和密钥,最后compact使字符串紧密一下
return token; //最终返回的是一个字符串
}
/**
* 校检
* @param token
* @return
*/
public static Claims checkJWT(String token){
try {
final Claims claims=Jwts.parser().setSigningKey(APPSECRET).parseClaimsJws(token).getBody();
return claims;
}catch (Exception e){}
return null;
}
}
我们传入的是UserBean的对象,所以我们一开始在方法中就需要出入UserBean
一开始我们申明了一些通用的静态资源,我这里有个问题就是,我把我的密码也存入了payload中,这是不被允许的,你们快要注意一下
if(userBean==null||userBean.getId()==0||userBean.getName()==null||userBean.getPassword()==null){
return null;
}
就是这里
然后,后面的话就是我们创建jwt的整个过程了,我都是有注释的,大家应该看得明白,
后面就是我们解析我们生成的Jwt
我们将我们生成的jwt传入到该方法中,返回得到Claims类型的值claims,这个解析就是通过我们的秘钥解析的,他们生成jwt的秘钥必须和解析秘钥相同才能解析
我的拦截器:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//getHeader 传入数据
System.out.println(request.getServletPath());
String logintoken =request.getHeader("jwt");
if (logintoken!=null){
Claims claims = JWTUntils.checkJWT(logintoken);
int id =(Integer) claims.get("id");
request.setAttribute("userid", id);
System.out.println(id);
return true;
} else {
System.out.println("获取权限失败");
// response.sendRedirect("/user/login?name=zhangsan&password=123");
return false;
}
}
我简单写了一个拦截器,来使用它,就是这样使用的,放行成功后,我们获取到该用户的id,来提供后续的需要。
大致jwt就是这样的,写的不好,勿喷,都是个人理解,希望对大家有帮助,程序小白留…