最近在弄前后端的项目,涉及到token验证的问题,记录一下。
shiro框架是公司提前配好的,详细的可以去看下配置文档,我这边只记录一下如何配置jwt。
首先添加maven的依赖包:
<dependency>
<!-- JSON Web Token Support -->
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
<!--ceshi-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
创建filter类:
package com.qiyuansoft.unicorn.common.filter;
import com.qiyuansoft.unicorn.common.BusiException;
import com.qiyuansoft.unicorn.common.tools.JWTTool;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
/**
* 自定义token验证
*/
public class CustomerLogoutFilter extends LogoutFilter {
private final static Logger log = LoggerFactory.getLogger(CustomerLogoutFilter.class);
@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
String errmsg = "";
try {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String token = httpServletRequest.getHeader("Token");
String appUID = JWTTool.getAppUID(token);
return true;
} catch ( BusiException ex) {
return false;
}
}
}
jwt的工具类:
package com.qiyuansoft.unicorn.common.tools;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.util.StringUtils;
import java.util.*;
/**
* APP登录Token的生成和解析
*
*/
public class JWTTool {
/** token秘钥,请勿泄露,请勿随便修改 */
public static final String SECRET = "自己的私钥,随便设置";
/** token 过期时间: 15 分钟 */
public static final int CALENDARFIELD = Calendar.MINUTE;
public static final int CALENDARINTERVAL = 1;
/**
* JWT生成Token.<br/>
*
* JWT构成: header, payload, signature
*
* @param userId
* 登录成功后用户userId, 参数userId不可传空
*/
public static String createToken(String userId) {
Date iatDate = new Date();
// expire time
Calendar nowTime = Calendar.getInstance();
nowTime.add(CALENDARFIELD, CALENDARINTERVAL);
Date expiresDate = nowTime.getTime();
// header Map
Map<String, Object> map = new HashMap<>();
map.put("alg", "HS256");
map.put("typ", "JWT");
/**
* build token
* param backups {iss:Service, aud:APP}
*
* withHeader : header
* withClaim : payload
* withIssuedAt : sign time
* withExpiresAt : expire time
* sign :signature
*/
String token = JWT.create().withHeader(map)
.withClaim("iss", "Service")
.withClaim("aud", "APP")
.withClaim("user_id", null == userId ? null : userId.toString())
.withIssuedAt(iatDate)
.withExpiresAt(expiresDate)
.sign(Algorithm.HMAC256(SECRET));
return token;
}
/**
* 解密Token
*
* @param token
* @return
* @throws Exception
*/
public static Map<String, Claim> verifyToken(String token) {
DecodedJWT jwt = null;
Map<String, Claim> claims = null;
try {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
jwt = verifier.verify(token);
claims = jwt.getClaims();
Optional.ofNullable(claims).orElseThrow(IllegalArgumentException::new);
} catch (Exception e) {
// e.printStackTrace();
// token 校验失败, 抛出Token验证非法异常
System.out.println("IllegalArgumentException : token 校验失败");
}
return claims;
}
/**
* 根据Token获取user_id
*
* @param token
* @return user_id
*/
public static String getAppUID(String token) {
Map<String, Claim> claims = verifyToken(token);
Claim userIdClaim = claims.get("user_id");
if (null == userIdClaim || StringUtils.isEmpty(userIdClaim.asString())) {
// token 校验失败, 抛出Token验证非法异常
}
return userIdClaim.asString();
}
}
在shiro中配置filter过滤器:
拦截
filterChainDefinitionMap.put("/*", "logout");// 拦截验证token
filterChainDefinitionMap.put("/**", "logout");
filterChainDefinitionMap.put("/*.*", "logout");
进入filter
包 import javax.servlet.Filter;
Map<String, Filter> filters = new HashMap<>();
filters.put("logout", new CustomerLogoutFilter());
filterFactoryBean.setFilters(filters);
上边是jwt验证token,token的创建在登陆成功的时候调用工具类生成返回前端,后续发送请求的时候前台带过来。
生成token需要带上你的用户id
token = JWTTool.createToken(user.getId());
token是根据你的用户id加上秘钥还有时间戳生成的,解密的时候回返回给你用户id。判断一下这个用户id不为空并且和你的当前用户的id一样就可以了。
辛勤的汗水换来的肯定是美好的未来,加油哦。