Browse Source

jwt注入拦截器

master
xyiege 4 years ago
parent
commit
eb6e039ead
  1. 13
      pom.xml
  2. 80
      src/main/java/cn/chjyj/szwh/Interceptor/ChInterceptor.java
  3. 235
      src/main/java/cn/chjyj/szwh/utils/JwtUtils.java
  4. 2
      szwh.iml

13
pom.xml

@ -93,11 +93,18 @@
</dependency>
<!-- jwt-->
<!-- <dependency>-->
<!-- <groupId>io.jsonwebtoken</groupId>-->
<!-- <artifactId>jjwt</artifactId>-->
<!-- <version>0.9.1</version>-->
<!-- </dependency>-->
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.3</version>
</dependency>
</dependencies>
<build>

80
src/main/java/cn/chjyj/szwh/Interceptor/ChInterceptor.java

@ -1,14 +1,18 @@
package cn.chjyj.szwh.Interceptor;
import cn.chjyj.szwh.annotation.PassToken;
import cn.chjyj.szwh.exception.ChException;
import cn.chjyj.szwh.utils.JwtUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
@Component
public class ChInterceptor implements HandlerInterceptor {
@ -16,42 +20,56 @@ public class ChInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//输出头
setHeader(response,request);
//如果非login页面,则判断header 中是否有 chtoken
String url=request.getRequestURI().trim();
if(!url.contains("/login")){
String chtoken = request.getHeader("chtoken");
if(StringUtils.isEmpty(chtoken)){
throw new ChException("token记录不存在,请确认是否已经登录成功");
// 从请求头中获取token
String token = request.getHeader("token");
// 如果不是映射到方法直接通过
if(!(handler instanceof HandlerMethod)){
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
//检查是否有passtoken注释,有则跳过认证
if (method.isAnnotationPresent(PassToken.class)) {
PassToken passToken = method.getAnnotation(PassToken.class);
if (passToken.required()) {
return true;
}
//String token = request.getParameter("token");
// if(StringUtils.isBlank(token)){
// throw new ChException("token没有传入,禁止使用");
// }
//调用验证
// if(rsaService.chkToken(token)){
// return true;
}
//默认全部检查
else {
// 执行认证
if (token == null) {
throw new ChException("请登录重试");
}
// 获取 token 中的 user Name
String userId = JwtUtils.getAudience(token);
//找找看是否有这个user 因为我们需要检查用户是否存在,读者可以自行修改逻辑
// todo
// AccountDTO user = accountService.getByUserName(userId);
//
// if (user == null) {
// //这个错误也是我自定义的
// throw new ChException("用户不存在");
// }
// 验证 token
JwtUtils.verifyToken(token, userId);
//获取载荷内容
String userName = JwtUtils.getClaimByName(token, "userName").asString();
String realName = JwtUtils.getClaimByName(token, "realName").asString();
//放入attribute以便后面调用
request.setAttribute("userName", userName);
request.setAttribute("realName", realName);
return true;
}
return false;
return true;
}
/**
* 设置输出头,添加跨域
* @param response
*/
private void setHeader(HttpServletResponse response,HttpServletRequest request){
//跨域的header设置
response.setHeader("Access-control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Methods", request.getMethod());
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
// 个性化主机设置
response.setHeader("chhong","true");
// 防止乱码
response.setHeader("Content-Type","application/json;charset=UTF-8");
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

235
src/main/java/cn/chjyj/szwh/utils/JwtUtils.java

@ -1,212 +1,79 @@
package cn.chjyj.szwh.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.CompressionCodecs;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import cn.chjyj.szwh.exception.ChException;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Calendar;
import java.util.Date;
/**
* jwt工具类
*/
public class JwtUtils {
/**
* 实例
*/
private static JwtUtils instance;
/**
* 发行者
*/
private String subObject = "owner";
/**
* 过期时间默认7天
* 签发对象这个用户的id
* 签发时间现在
* 有效时间30分钟
* 载荷内容暂时设计为这个人的名字这个人的昵称
* 加密密钥这个人的id加上一串字符串
*/
private long expired = 1000 * 60 * 60 * 24 * 7;
/**
* jwt构造
*/
private static JwtBuilder jwtBuilder;
/**
* 密钥
*/
private String secret = "secret";// 密钥
/**
* 获取实例
* @return
*/
public static JwtUtils getInstance(){
if (instance == null){
instance = new JwtUtils();
}
jwtBuilder = Jwts.builder();
return instance;
public static String createToken(String userId, String realName, String userName) {
Calendar nowTime = Calendar.getInstance();
nowTime.add(Calendar.MINUTE, 30);
Date expiresDate = nowTime.getTime();
return JWT.create().withAudience(userId) //签发对象
.withIssuedAt(new Date()) //发行时间
.withExpiresAt(expiresDate) //有效时间
.withClaim("userName", userName) //载荷,随便写几个都可以
.withClaim("realName", realName)
.sign(Algorithm.HMAC256(userId + "HelloLehr")); //加密
}
/**
* 荷载信息(通常是一个User信息还包括一些其他的元数据)
* @param key
* @param val
* @return
*/
public JwtUtils setClaim(String key,Object val){
jwtBuilder.claim(key,val);
return this;
}
/**
* 生成 jwt token
* @return
*/
public String generateToken(){
String token = jwtBuilder
.setSubject(subObject) // 发行者
//.claim("id","121") // 参数
.setIssuedAt(new Date()) // 发行时间
.setExpiration(new Date(System.currentTimeMillis() + expired))
.signWith(SignatureAlgorithm.HS256,secret) // 签名类型 与 密钥
.compressWith(CompressionCodecs.DEFLATE)// 对载荷进行压缩
.compact(); // 压缩一下
return token;
}
/**
* 解析 token
* 检验合法性其中secret参数就应该传入的是用户的id
*
* @param token
* @return
*/
public Claims check(String token){
try{
final Claims claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
return claims;
}catch (Exception e){}
return null;
}
public String getSubObject() {
return subObject;
}
/**
* 设置发行者
* @param subObject
* @return
*/
public JwtUtils setSubObject(String subObject) {
this.subObject = subObject;
return this;
}
public long getExpired() {
return expired;
public static void verifyToken(String token, String secret) {
DecodedJWT jwt = null;
try {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret + "HelloLehr")).build();
jwt = verifier.verify(token);
} catch (Exception e) {
//效验失败
//这里抛出的异常是我自定义的一个异常,你也可以写成别的
throw new ChException("token验证失败");
}
}
/**
* 设置过期时间
* @param expired
* @return
* 获取签发对象
*/
public JwtUtils setExpired(long expired) {
this.expired = expired;
return this;
public static String getAudience(String token) {
String audience = null;
try {
audience = JWT.decode(token).getAudience().get(0);
} catch (JWTDecodeException j) {
//这里是token解析失败
throw new ChException("token解析失败");
}
return audience;
}
public String getSecret() {
return secret;
}
/**
* 设置密钥
* @param secret
* @return
* 通过载荷名字获取载荷的值
*/
public JwtUtils setSecret(String secret) {
this.secret = secret;
return this;
public static Claim getClaimByName(String token, String name) {
return JWT.decode(token).getClaim(name);
}
}
// import com.auth0.jwt.JWT;
// import com.auth0.jwt.JWTVerifier;
// import com.auth0.jwt.algorithms.Algorithm;
// import com.auth0.jwt.exceptions.JWTDecodeException;
// import com.auth0.jwt.interfaces.Claim;
// import com.auth0.jwt.interfaces.DecodedJWT;
//
// import java.io.Serializable;
// import java.util.Calendar;
// import java.util.Date;
//
//public class JwtUtils {
//
// /**
// 签发对象:这个用户的id
// 签发时间:现在
// 有效时间:30分钟
// 载荷内容:暂时设计为:这个人的名字,这个人的昵称
// 加密密钥:这个人的id加上一串字符串
// */
// public static String createToken(String userId,String realName, String userName) {
//
// Calendar nowTime = Calendar.getInstance();
// nowTime.add(Calendar.MINUTE,30);
// Date expiresDate = nowTime.getTime();
//
// return JWT.create().withAudience(userId) //签发对象
// .withIssuedAt(new Date()) //发行时间
// .withExpiresAt(expiresDate) //有效时间
// .withClaim("userName", userName) //载荷,随便写几个都可以
// .withClaim("realName", realName)
// .sign(Algorithm.HMAC256(userId+"HelloLehr")); //加密
// }
//
// /**
// * 检验合法性,其中secret参数就应该传入的是用户的id
// * @param token
// * @throws TokenUnavailable
// */
// public static void verifyToken(String token, String secret) throws TokenUnavailable {
// DecodedJWT jwt = null;
// try {
// JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret+"HelloLehr")).build();
// jwt = verifier.verify(token);
// } catch (Exception e) {
// //效验失败
// //这里抛出的异常是我自定义的一个异常,你也可以写成别的
// throw new TokenUnavailable();
// }
// }
//
// /**
// * 获取签发对象
// */
// public static String getAudience(String token) throws TokenUnavailable {
// String audience = null;
// try {
// audience = JWT.decode(token).getAudience().get(0);
// } catch (JWTDecodeException j) {
// //这里是token解析失败
// throw new TokenUnavailable();
// }
// return audience;
// }
//
//
// /**
// * 通过载荷名字获取载荷的值
// */
// public static Claim getClaimByName(String token, String name){
// return JWT.decode(token).getClaim(name);
// }
//}

2
szwh.iml

@ -102,7 +102,7 @@
<orderEntry type="library" name="Maven: com.alibaba:druid:1.2.6" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.9" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.15" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: com.auth0:java-jwt:3.8.3" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.13.3" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.13.3" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.13.3" level="project" />

Loading…
Cancel
Save