From f865cdae190edac151c038aed0ab45c7ae1f945f Mon Sep 17 00:00:00 2001 From: rain <3363779424@qq.com> Date: Thu, 14 Aug 2025 11:24:02 +0800 Subject: [PATCH] Changes --- .idea/vcs.xml | 6 + .idea/webContexts.xml | 1 + pom.xml | 22 ++-- ...erController.java => UsersController.java} | 71 ++++++++++-- src/main/java/cn/star/dao/UsersDao.java | 5 +- src/main/java/cn/star/domian/Users.java | 12 ++ .../cn/star/interceptor/TokenInterceptor.java | 96 +++++----------- src/main/java/cn/star/util/JwtUtil.java | 104 +++++++----------- src/main/resources/spring-mvc.xml | 13 ++- .../webapp/WEB-INF/{pages => jsp}/Users.jsp | 0 .../WEB-INF/{pages => jsp}/falselogin.jsp | 0 src/main/webapp/{ => WEB-INF/jsp}/index.jsp | 5 +- .../webapp/WEB-INF/{pages => jsp}/success.jsp | 0 .../WEB-INF/{pages => jsp}/successlogin.jsp | 0 src/main/webapp/WEB-INF/web.xml | 2 + src/main/webapp/images | 0 src/main/webapp/static/css/styles.css | 33 +++++- 17 files changed, 203 insertions(+), 167 deletions(-) create mode 100644 .idea/vcs.xml rename src/main/java/cn/star/controller/{UserController.java => UsersController.java} (70%) rename src/main/webapp/WEB-INF/{pages => jsp}/Users.jsp (100%) rename src/main/webapp/WEB-INF/{pages => jsp}/falselogin.jsp (100%) rename src/main/webapp/{ => WEB-INF/jsp}/index.jsp (96%) rename src/main/webapp/WEB-INF/{pages => jsp}/success.jsp (100%) rename src/main/webapp/WEB-INF/{pages => jsp}/successlogin.jsp (100%) delete mode 100644 src/main/webapp/images diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/webContexts.xml b/.idea/webContexts.xml index f4124c7..4e4906c 100644 --- a/.idea/webContexts.xml +++ b/.idea/webContexts.xml @@ -3,6 +3,7 @@ diff --git a/pom.xml b/pom.xml index c0c32e3..4c5d69c 100644 --- a/pom.xml +++ b/pom.xml @@ -174,17 +174,23 @@ spring-data-redis 2.7.11 - + - com.auth0 - java-jwt - 3.4.0 + io.jsonwebtoken + jjwt-api + 0.11.2 + + + io.jsonwebtoken + jjwt-impl + 0.11.2 + runtime - - com.alibaba - fastjson - 1.2.76 + io.jsonwebtoken + jjwt-jackson + 0.11.2 + runtime diff --git a/src/main/java/cn/star/controller/UserController.java b/src/main/java/cn/star/controller/UsersController.java similarity index 70% rename from src/main/java/cn/star/controller/UserController.java rename to src/main/java/cn/star/controller/UsersController.java index a3516c3..9819983 100644 --- a/src/main/java/cn/star/controller/UserController.java +++ b/src/main/java/cn/star/controller/UsersController.java @@ -3,16 +3,20 @@ package cn.star.controller; //创建用户控制层UserController类 +import cn.star.dao.UsersDao; import cn.star.domian.Users; import cn.star.service.UsersService; +import cn.star.util.JwtUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.mvc.support.RedirectAttributes; @@ -27,16 +31,21 @@ import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import javax.servlet.ServletOutputStream; import java.io.IOException; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Random; @Controller @RequestMapping("/users") -public class UserController { +public class UsersController { @Autowired private UsersService usersService; - private static final Logger logger = LoggerFactory.getLogger(UserController.class); + private static final Logger logger = LoggerFactory.getLogger(UsersController.class); + @Qualifier("usersDao") + @Autowired + private UsersDao usersDao; @RequestMapping("/findUsers") /*public String findUsers() { @@ -59,9 +68,12 @@ public class UserController { return "success"; } + //region login(8.14改) @RequestMapping("/login") - public String login(HttpServletRequest request, HttpSession session, RedirectAttributes redirectAttributes) + @ResponseBody // + public Map login(HttpServletRequest request, HttpSession session) { + Map result = new HashMap<>(); //先获取请求参数-验证码、账号、密码 String verifyCode = request.getParameter("verifyCode"); String username = request.getParameter("username"); @@ -70,14 +82,49 @@ public class UserController { //获取session中存储的验证码 String sessionVerifyCode = (String) session.getAttribute("verifyCodeValue"); + //判断session中的验证码是否存在 + //执行你的验证码校验 - if (!verifyCode.equals(sessionVerifyCode)) { - logger.info("登陆失败,验证码输入有误"); + if (verifyCode == null || !verifyCode.equals(sessionVerifyCode)) { + /*logger.info("登陆失败,验证码输入有误"); redirectAttributes.addFlashAttribute("message", "验证码输入有误"); - return "falselogin"; + return "falselogin";*/ + result.put("success",false); + result.put("message","验证码输入有误"); + return result;//返回JSON; + } + + //通过用户名查询用户,并且查询用户是否存在 + Users users = usersDao.findByUsername(username); + if(users==null) { + result.put("success",false); + result.put("message","用户名不存在"); + return result; + } + + //验证密码是否存在 + if(!password.equals(users.getPassword())) { + result.put("success",false); + result.put("message","密码错误"); + return result; + } + + if(users.getId() != null) { + String token = JwtUtil.generateToken(users.getId().longValue(),users.getRole()); + + result.put("success",true); + result.put("token",token); + result.put("role",users.getRole()); + return result; + } + else { + result.put("success",false); + result.put("message","用户名和密码错误"); + return result; } + //验证用户名密码 - Users users = new Users(); + /* Users users = new Users(); users.setUsername(username); users.setPassword(password); if(usersService.login(users)) { @@ -87,9 +134,15 @@ public class UserController { else { redirectAttributes.addFlashAttribute("message","用户名或密码错误"); return "falselogin"; - } + }*/ + //生成Token(包含用户Id和角色) + /*String token = JwtUtil.generateToken(users.getId(),users.getRole()); + result.put("success",true); + result.put("token",token); + result.put("role",users.getRole()); + return result;*/ } /*System.out.println("登录"); @@ -99,7 +152,7 @@ public class UserController { else { return "falselogin"; }*/ - +//endregion /* 获取校验码 */ @RequestMapping("/getVerifyCode") diff --git a/src/main/java/cn/star/dao/UsersDao.java b/src/main/java/cn/star/dao/UsersDao.java index f37f3bd..674d92f 100644 --- a/src/main/java/cn/star/dao/UsersDao.java +++ b/src/main/java/cn/star/dao/UsersDao.java @@ -18,7 +18,10 @@ public interface UsersDao { @Insert("INSERT INTO USERS (username,password) VALUES(#{username},#{password})") public void insertUsers(Users users); //用户登录 - @Select("select * from users where username=#{username} and password=#{password}") + @Select("select * from users where username=#{username} and password=#{password} ") public Users login(Users users); + //通过用户名查询用户-用于登陆验证(8.14改) + @Select("select * from users where username=#{username}") + public Users findByUsername(String username); } diff --git a/src/main/java/cn/star/domian/Users.java b/src/main/java/cn/star/domian/Users.java index 8eab617..2e7a99f 100644 --- a/src/main/java/cn/star/domian/Users.java +++ b/src/main/java/cn/star/domian/Users.java @@ -6,6 +6,17 @@ public class Users implements Serializable { private Integer id; private String username; private String password; + private String role; + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } + + public String getPassword() { return password; @@ -42,4 +53,5 @@ public class Users implements Serializable { ", password='" + password + '\'' + '}'; } + } diff --git a/src/main/java/cn/star/interceptor/TokenInterceptor.java b/src/main/java/cn/star/interceptor/TokenInterceptor.java index d60b01c..22249c0 100644 --- a/src/main/java/cn/star/interceptor/TokenInterceptor.java +++ b/src/main/java/cn/star/interceptor/TokenInterceptor.java @@ -1,91 +1,47 @@ -/*package cn.star.interceptor; +package cn.star.interceptor; -import cn.star.common.ApiResponse; import cn.star.util.JwtUtil; -import com.alibaba.fastjson.JSONObject; -import org.springframework.web.method.HandlerMethod; +import io.jsonwebtoken.Claims; import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.ModelAndView; - -import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; import java.io.PrintWriter; -import java.util.HashMap; -import java.util.Map; public class TokenInterceptor implements HandlerInterceptor { - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException { - - // 只处理HandlerMethod类型的处理器(排除静态资源等) - if (!(handler instanceof HandlerMethod)) { - return true; - } - - System.out.println("执行方法之前执行这步操作"); - response.setCharacterEncoding("utf-8"); - - Cookie cookie = getCookieByName(request,"COOKIE_NAME"); + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + //获取请求头中的token - if(null != cookie) { - boolean result = JwtUtil.verify(cookie.getValue()); - if(!result) { - response.sendRedirect(request.getContextPath() + "/login"); - return false; - } - return true; - } - else { - response.sendRedirect(request.getContextPath() + "/login"); + String token = request.getHeader("Authorization"); + //验证token格式 + if(token == null || !token.startsWith("Bearer")) { + returnError(response,"请先登录"); return false; } - } - - @Override - public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) - throws Exception { - } + token = token.substring(7); - @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {} - - //根据名字获取cookie - public static Cookie getCookieByName(HttpServletRequest request , String name) { - Map cookieMap = ReadCookieMap(request); - if (cookieMap.containsKey(name)) { - Cookie cookie = cookieMap.get(name); - return cookie; - } - else { - return null; + //验证token有效性 + if (!JwtUtil.isTokenValid(token)) { + returnError(response,"登录已过期,请重新登录"); + return false; } - } - private static Map ReadCookieMap(HttpServletRequest request) { - Map cookieMap = new HashMap(); - Cookie[] cookies = request.getCookies(); - if (cookies != null) { - for (Cookie cookie : cookies) { - cookieMap.put(cookie.getName(), cookie); - } - } - return cookieMap; + //解析token获取角色,存入request继续使用 + Claims claims = JwtUtil.parseToken(token); + request.setAttribute("userId",claims.get("userId",Long.class)); + request.setAttribute("role",claims.get("role",Long.class)); + return true; } - private void responseMessage(HttpServletRequest request, HttpServletResponse response, PrintWriter out, ApiResponse apiResponse) - throws IOException - { - response.setContentType("text/html;charset=utf-8"); - out.print(JSONObject.toJSONString(apiResponse));//这个ApiResponse需要创建一个类然后调用 + //返回错误信息 + private void returnError(HttpServletResponse response, String message) throws Exception { + response.setContentType("text/html;charset=UTF-8"); + PrintWriter out = response.getWriter(); + out.write(""); out.flush(); out.close(); - } - - - - -}*/ + } +} \ No newline at end of file diff --git a/src/main/java/cn/star/util/JwtUtil.java b/src/main/java/cn/star/util/JwtUtil.java index dd3b155..0ec75a3 100644 --- a/src/main/java/cn/star/util/JwtUtil.java +++ b/src/main/java/cn/star/util/JwtUtil.java @@ -1,79 +1,49 @@ package cn.star.util; -import com.auth0.jwt.JWT; -import com.auth0.jwt.JWTVerifier; -import com.auth0.jwt.algorithms.Algorithm; -import com.auth0.jwt.interfaces.DecodedJWT; -import java.io.UnsupportedEncodingException; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; +import javax.crypto.SecretKey; import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import static java.lang.System.currentTimeMillis; public class JwtUtil { + //密钥-实际项目应该存在配置文件(?怎么弄 + private static final SecretKey SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256); + //Token 有效时间 + private static final long EXPIRATION_TIME = 2 * 60 * 60 * 1000; + + //生成token + public static String generateToken(Long userId,String role) { + + Date now = new Date(); + Date expiration = new Date(now.getTime() + EXPIRATION_TIME); + + return Jwts.builder().claim("usersId",userId) + .claim("role",role) + .setIssuedAt(now) + .setExpiration(expiration) + .signWith(SECRET_KEY) + .compact(); +} - private static final long EXPIRE_TIME = 24 * 60 * 60 * 1000; //expire-到期时间 - - // token私匙 - private static final String TOKEN_SECRET = "f26e587c28064d0e855e72c0a6a0e618";//只是模拟自己设置的? - - //校验token是否正确 - public static boolean verify(String token) { - try { - Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET); - JWTVerifier verifier = JWT.require(algorithm).build(); - DecodedJWT jwt = verifier.verify(token); - return true; - } catch (Exception e) { - return false; - } - } +// 解析Token获取信息 - //return token包含的用户名 - public static String getUsername(String token) { - try { - DecodedJWT jwt = JWT.decode(token); - return jwt.getClaim("username").asString(); - } catch (Exception e) { - return null; - } + public static Claims parseToken(String token) { + return Jwts.parserBuilder() + .setSigningKey(SECRET_KEY) + .build() + .parseClaimsJws(token) + .getBody(); } - - //获取登录用户id - public static String getUserId(String token) { +//解析token是否有效 + public static boolean isTokenValid(String token) { try { - DecodedJWT jwt = JWT.decode(token); - return jwt.getClaim("userId").asString(); - } catch (Exception e) { - return null; + Claims claims = parseToken(token); + return !claims.getExpiration().before(new Date()); + }catch (Exception e) { + return false;//无效或过期 } } - - //生成签名,15min后过期 - public static String sign(String username,String userId) { - // 过期时间 - Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME); -// 私钥及加密算法 - Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET); -// 设置头部信息 - Map header = new HashMap<>(2); - header.put("typ", "JWT"); - header.put("alg", "HS256"); - // 附带username,userId信息,生成签名 - return JWT.create() - .withHeader(header) - .withClaim("loginName", username) - .withClaim("userId",userId) - .withExpiresAt(date) - .sign(algorithm); - } - - - - - - -} - +} \ No newline at end of file diff --git a/src/main/resources/spring-mvc.xml b/src/main/resources/spring-mvc.xml index 9a7f56d..20bcdaa 100644 --- a/src/main/resources/spring-mvc.xml +++ b/src/main/resources/spring-mvc.xml @@ -18,7 +18,7 @@ - + @@ -30,12 +30,15 @@ - - - + + + + + - --> + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/pages/Users.jsp b/src/main/webapp/WEB-INF/jsp/Users.jsp similarity index 100% rename from src/main/webapp/WEB-INF/pages/Users.jsp rename to src/main/webapp/WEB-INF/jsp/Users.jsp diff --git a/src/main/webapp/WEB-INF/pages/falselogin.jsp b/src/main/webapp/WEB-INF/jsp/falselogin.jsp similarity index 100% rename from src/main/webapp/WEB-INF/pages/falselogin.jsp rename to src/main/webapp/WEB-INF/jsp/falselogin.jsp diff --git a/src/main/webapp/index.jsp b/src/main/webapp/WEB-INF/jsp/index.jsp similarity index 96% rename from src/main/webapp/index.jsp rename to src/main/webapp/WEB-INF/jsp/index.jsp index 5e28d3d..c5d113d 100644 --- a/src/main/webapp/index.jsp +++ b/src/main/webapp/WEB-INF/jsp/index.jsp @@ -1,9 +1,10 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> 主界面 - +