diff --git a/pom.xml b/pom.xml
index 2f72140..c7566ea 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,17 +60,50 @@
2.6
+
+
+ com.google.guava
+ guava
+ 31.0.1-jre
+
+
+
+ com.auth0
+ java-jwt
+ 3.4.0
+
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.22
+
+
+
+
+ com.alibaba
+ druid
+ 1.2.6
+
- com.auth0
- java-jwt
- 3.5.0
+ io.jsonwebtoken
+ jjwt-api
+ 0.11.5
io.jsonwebtoken
- jjwt
- 0.6.0
+ jjwt-impl
+ 0.11.5
+
+ io.jsonwebtoken
+ jjwt-jackson
+ 0.11.5
+
+
+
@@ -219,6 +252,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/com/lovenav/configuration/MyWebConfigurer.java b/src/main/java/com/lovenav/configuration/MyWebConfigurer.java
index b13b3a7..f366cba 100644
--- a/src/main/java/com/lovenav/configuration/MyWebConfigurer.java
+++ b/src/main/java/com/lovenav/configuration/MyWebConfigurer.java
@@ -8,7 +8,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
public class MyWebConfigurer implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
-// registry.addInterceptor(new UserInterceptor()).addPathPatterns("/*/**").excludePathPatterns("/error","/login","/register","/findThePassword","/verifyCode","/sendActiveCode");
+ registry.addInterceptor(new UserInterceptor()).addPathPatterns("/*/**").excludePathPatterns("/error","/login","/register","/findThePassword","/verifyCode","/sendActiveCode");
WebMvcConfigurer.super.addInterceptors(registry);
}
}
diff --git a/src/main/java/com/lovenav/controller/UserController.java b/src/main/java/com/lovenav/controller/UserController.java
index 4c42103..a488015 100644
--- a/src/main/java/com/lovenav/controller/UserController.java
+++ b/src/main/java/com/lovenav/controller/UserController.java
@@ -81,41 +81,42 @@ public class UserController {
}
@RequestMapping(value = "/login",produces = {"application/json;charset=UTF-8"})
public Maplogin(User user,String code,HttpSession session){
+ Map result=new HashMap<>();
Map map=new HashMap<>();
String sessionCode = (String) session.getAttribute(RandomValidateCode.RANDOMVALIDATECODE);
if (sessionCode==null){
- map.put("msg","验证码空的");
- return map;
+ result.put("msg","验证码空的");
+ return result;
}
if (!sessionCode.equals(code)){
- map.put("msg","验证码错误");
- return map;
+ result.put("msg","验证码错误");
+ return result;
}
if(StringUtils.isEmpty(user.getUserLogin())||StringUtils.isEmpty(user.getUserPassword())){
- map.put("msg","用户或密码为空!");
- return map;
+ result.put("msg","用户或密码为空!");
+ return result;
}
User user1 = userService.userLogin(user);
if(user1!=null){
- map.put("code",200);
- String token= tokenUtils.sign(user1);
+ result.put("code",200);
map.put("userEmail",user1.getUserEmail());
map.put("userLogin",user1.getUserLogin());
- map.put("user",user1.getUserEmail());
- map.put("userStatus",user1.getUserStatus());
- map.put("Id",user1.getId());
- map.put("nickname",user1.getNickname());
- map.put("roleId",user1.getRoleId());
- map.put("userRegistered",user1.getUserRegistered());
- map.put("token",token);
+ String token= TokenUtils.createJWT(map,10000000L);
+ result.put("user",user1.getUserEmail());
+ result.put("userStatus",user1.getUserStatus());
+ result.put("Id",user1.getId());
+ result.put("nickname",user1.getNickname());
+ result.put("roleId",user1.getRoleId());
+ result.put("userRegistered",user1.getUserRegistered());
+ result.put("token",token);
}else {
- map.put("msg","用户名或密码错误!");
+ result.put("msg","用户名或密码错误!");
}
- return map;
+ return result;
}
/*图片验证码*/
@RequestMapping("/verifyCode")
diff --git a/src/main/java/com/lovenav/filter/UserInterceptor.java b/src/main/java/com/lovenav/filter/UserInterceptor.java
index 5a8d224..88cf02f 100644
--- a/src/main/java/com/lovenav/filter/UserInterceptor.java
+++ b/src/main/java/com/lovenav/filter/UserInterceptor.java
@@ -2,22 +2,29 @@ package com.lovenav.filter;
import com.alibaba.fastjson.JSON;
+import com.auth0.jwt.exceptions.AlgorithmMismatchException;
+import com.auth0.jwt.exceptions.SignatureVerificationException;
+import com.auth0.jwt.exceptions.TokenExpiredException;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.lovenav.utils.TokenUtils;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
+import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
-
+@Configuration
public class UserInterceptor implements HandlerInterceptor {
//Controller逻辑执行之前
- @Autowired
+@Autowired
private TokenUtils tokenUtils;
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object obj, Exception e)
@@ -31,29 +38,36 @@ public class UserInterceptor implements HandlerInterceptor {
}
// 拦截每个请求
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) {
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws IOException {
Map map=new HashMap<>();
System.out.println("开始进入拦截器检验jwt头部是否含有Authorization方法!");
// 通过url得到token请求头是否包含Authorization
response.setCharacterEncoding("UTF-8");
String jwt = request.getHeader("Authorization");
- System.out.println(jwt);
+ if (jwt==null){
+ map.put("msg","请求头中不含token");
+ response.getWriter().print(JSON.toJSONString(map));
+ return false;
+ }
try {
+ Claims c = TokenUtils.verifyJwt(jwt);
+ return true;
// 检测请求头是否为空
- if (jwt == null) {
- System.out.println("用户未登录,验证失败");
- map.put("msg","用户未登录,验证失败");
- response.getWriter().print(JSON.toJSONString(map));
- return false;
- } else {
- Claims c = tokenUtils.parseJWT(jwt);
- System.out.println("用户[ " + c.get("userLogin") + " ]已是登录状态");
- System.out.println("结束进入拦截器检验jwt头部是否含有Authorization方法!");
- return true;
- }
+ } catch (TokenExpiredException e) {
+ map.put("state", false);
+ map.put("msg", "Token已经过期!!!");
+ } catch (SignatureVerificationException e){
+ map.put("state", false);
+ map.put("msg", "签名错误!!!");
+ } catch (AlgorithmMismatchException e){
+ map.put("state", false);
+ map.put("msg", "加密算法不匹配!!!");
} catch (Exception e) {
e.printStackTrace();
+ map.put("state", false);
+ map.put("msg", "无效token");
}
+ response.getWriter().print(JSON.toJSONString(map));
return false;
}
diff --git a/src/main/java/com/lovenav/service/serviceImpl/UserServiceImpl.java b/src/main/java/com/lovenav/service/serviceImpl/UserServiceImpl.java
index 25c3a4c..7528b37 100644
--- a/src/main/java/com/lovenav/service/serviceImpl/UserServiceImpl.java
+++ b/src/main/java/com/lovenav/service/serviceImpl/UserServiceImpl.java
@@ -32,6 +32,7 @@ public class UserServiceImpl implements UserService {
return null;
}
else if (user1.getUserPassword().equals(user.getUserPassword())){
+
return user1;
}else {
return null;
diff --git a/src/main/java/com/lovenav/utils/TokenUtils.java b/src/main/java/com/lovenav/utils/TokenUtils.java
index 00eb4a5..0a0fc88 100644
--- a/src/main/java/com/lovenav/utils/TokenUtils.java
+++ b/src/main/java/com/lovenav/utils/TokenUtils.java
@@ -1,125 +1,122 @@
package com.lovenav.utils;
-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.DecodedJWT;
-import com.lovenav.entity.User;
-import com.lovenav.service.UserService;
-
-
-
-import io.jsonwebtoken.*;
-import org.apache.tomcat.util.codec.binary.Base64;
-import org.springframework.beans.factory.annotation.Autowired;
+import com.google.common.io.BaseEncoding;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.JwtBuilder;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
-import org.springframework.stereotype.Service;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
-import java.util.UUID;
@Component
public class TokenUtils {
+ private static long tokenExpiredTime;
- private static final long EXPIRE_TIME = 60 * 1000; // 1分钟
-// private static final long EXPIRE_TIME = 15 * 60 * 1000; // 15分钟
+ private static String jwtId;
- // 加密密文,私钥
- private static final String TOKEN_SECRET = "jiamimiwen";
+ private static String jwtSecret;
- // 由字符串生成加密key
- public SecretKey generalKey() {
- System.out.println("进入由字符串生成加密key方法!");
- // 本地的密码解码
- byte[] encodedKey = Base64.decodeBase64(TOKEN_SECRET);
- // 根据给定的字节数组使用AES加密算法构造一个密钥
- SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
- return key;
+ /**
+ * 创建JWT
+ */
+ public static String createJWT(Map claims, Long time) {
+ //指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。
+ SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
+ Date now = new Date(System.currentTimeMillis());
+
+ SecretKey secretKey = generalKey();
+ //生成JWT的时间
+ long nowMillis = System.currentTimeMillis();
+ //下面就是在为payload添加各种标准声明和私有声明了
+ //这里其实就是new一个JwtBuilder,设置jwt的body
+ JwtBuilder builder = Jwts.builder()
+ //如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
+ .setClaims(claims)
+ //设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。
+ .setId(jwtId)
+ //iat: jwt的签发时间
+ .setIssuedAt(now)
+ //设置签名使用的签名算法和签名使用的秘钥
+ .signWith(signatureAlgorithm, secretKey);
+ if (time >= 0) {
+ long expMillis = nowMillis + time;
+ Date exp = new Date(expMillis);
+ //设置过期时间
+ builder.setExpiration(exp);
+ }
+ return builder.compact();
}
- // 生成签名
- public String sign(User user) {
- System.out.println("生成签名方法开始执行!");
+
+ /**
+ * 验证jwt
+ */
+ public static Claims verifyJwt(String token) {
+ //签名秘钥,和生成的签名的秘钥一模一样
+ SecretKey key = generalKey();
+ Claims claims;
try {
- // 设置过期时间,单位毫秒
- Date expTime = new Date(System.currentTimeMillis() + EXPIRE_TIME);
- // 私钥和加密算法
- Algorithm algorithm = Algorithm.HMAC256(user.getUserPassword()); //使用用户输入的密码
-// Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
- // 设置头部信息,也可以不用设置头部信息jwt会自动生成
-// Map header = new HashMap();
-// header.put("typ", "JWT");
-// header.put("alg", "HS256");
- // 或
- // header.put("Type", "JWT");
- // header.put("alg", "HS256");
- // 生成JWT的时间
- Date issuedAt = new Date(System.currentTimeMillis());
- // 返回token字符串
- System.out.println("生成签名方法结束执行!");
- return JWT.create() // 表示new一个Jwt,设置jwt的body
-// .withHeader(header) // 设置头部信息
- .withClaim("userLogin", user.getUserLogin()) // 数据库中用户的id
- .withClaim("email", user.getUserEmail()) // 前端输入的用户名
- .withIssuedAt(issuedAt) // jwt的签发时间
- .withExpiresAt(expTime) // jwt过期时间
- .sign(algorithm);
+ claims = Jwts.parser() //得到DefaultJwtParser
+ .setSigningKey(key) //设置签名的秘钥
+ .parseClaimsJws(token).getBody();
} catch (Exception e) {
- e.printStackTrace();
- return null;
- }
+ claims = null;
+ }//设置需要解析的jwt
+ return claims;
+
}
/**
+ * 由字符串生成加密key
*
- * @Title: verify
- * @Description: 检验token是否正确
- * @param: @param token 密钥
- * @param: @param username 登录名
- * @param: @param password 密码
- * @param: @return
- * @return: boolean
- * @throws
+ * @return SecretKey
*/
- public boolean verify(String token, String username, String password) {
- System.out.println("进入检验token是否正确方法!");
- try {
- Algorithm algorithm = Algorithm.HMAC256(password); //使用用户输入的密码
-// Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
- JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build();
-// JWTVerifier verifier = JWT.require(algorithm).build();
- verifier.verify(token);
- return true;
- } catch (Exception e) {
- return false;
- }
+ public static SecretKey generalKey() {
+ String stringKey = jwtSecret;
+ byte[] encodedKey = BaseEncoding.base64().decode(stringKey);
+ SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "HmacSHA256");
+ return key;
}
- // 获取登录名
- public String getUsername(String token) {
- System.out.println("进入获取登录名方法!");
- try {
- DecodedJWT jwt = JWT.decode(token);
- return jwt.getClaim("username").asString();
- } catch (JWTDecodeException e) {
- return null;
- }
+ /**
+ * 根据userId和openid生成token
+ */
+ public static String generateToken(String openId) {
+ Map map = new HashMap<>();
+ map.put("openId", openId);
+ return createJWT(map, tokenExpiredTime);
}
- // 解密jwt
- public Claims parseJWT(String jwt) throws Exception {
- System.out.println("进入解密jwt方法!");
- SecretKey key = generalKey(); // 签名秘钥,和生成的签名的秘钥一模一样
- Claims claims = Jwts.parser() // 得到DefaultJwtParser
- .setSigningKey(key) // 设置签名的秘钥
- .parseClaimsJws(jwt).getBody(); // 设置需要解析的jwt
- return claims;
+ @Value("${jwt.token-expired-time}")
+ public void setTokenExpiredTime(long tokenExpiredTime) {
+ TokenUtils.tokenExpiredTime = tokenExpiredTime;
}
+ @Value("${jwt.id}")
+ public void setJwtId(String jwtId) {
+ TokenUtils.jwtId = jwtId;
+ }
-}
+ @Value("${jwt.secret}")
+ public void setJwtSecret(String jwtSecret) {
+ TokenUtils.jwtSecret = jwtSecret;
+ }
+
+ public static long getTokenExpiredTime() {
+ return tokenExpiredTime;
+ }
+
+ public static String getJwtId() {
+ return jwtId;
+ }
+
+ public static String getJwtSecret() {
+ return jwtSecret;
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 1ee784d..332ae23 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -2,7 +2,7 @@ spring:
datasource:
url: jdbc:mysql://localhost:3306/love-nav
username: root
- password: 1611
+ password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
redis:
host: localhost
@@ -16,6 +16,18 @@ spring:
min-idle: 0
max-wait: -1
timeout: 10000
+mybatis:
+ type-aliases-package: com.lovenav.entity
+ mapper-locations: classpath:mybatis/*.xml
+
+jwt:
+ #设置token的过期时间,单位为秒
+ token-expired-time: 36000 #10小时
+ #设置token的id
+ id: tokenId
+ #设置密钥
+ secret: aPbOBbnH4gnZBzIYEY7mxWNu49kYljNPMeva9Fjrwwqzw0bFlO0kPXZTCGaVcw0j
+#