Browse Source

Changes

master
rain 4 months ago
parent
commit
f865cdae19
  1. 6
      .idea/vcs.xml
  2. 1
      .idea/webContexts.xml
  3. 22
      pom.xml
  4. 71
      src/main/java/cn/star/controller/UsersController.java
  5. 5
      src/main/java/cn/star/dao/UsersDao.java
  6. 12
      src/main/java/cn/star/domian/Users.java
  7. 96
      src/main/java/cn/star/interceptor/TokenInterceptor.java
  8. 102
      src/main/java/cn/star/util/JwtUtil.java
  9. 13
      src/main/resources/spring-mvc.xml
  10. 0
      src/main/webapp/WEB-INF/jsp/Users.jsp
  11. 0
      src/main/webapp/WEB-INF/jsp/falselogin.jsp
  12. 3
      src/main/webapp/WEB-INF/jsp/index.jsp
  13. 0
      src/main/webapp/WEB-INF/jsp/success.jsp
  14. 0
      src/main/webapp/WEB-INF/jsp/successlogin.jsp
  15. 2
      src/main/webapp/WEB-INF/web.xml
  16. 0
      src/main/webapp/images
  17. 33
      src/main/webapp/static/css/styles.css

6
.idea/vcs.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

1
.idea/webContexts.xml

@ -3,6 +3,7 @@
<component name="WebContextManager">
<option name="state">
<map>
<entry key="file://$PROJECT_DIR$/src/main/webapp/WEB-INF/pages/index.html" value="file://$PROJECT_DIR$/src/main/webapp" />
<entry key="file://$PROJECT_DIR$/src/main/webapp/index.jsp" value="file://$PROJECT_DIR$/src/main/webapp" />
</map>
</option>

22
pom.xml

@ -174,17 +174,23 @@
<artifactId>spring-data-redis</artifactId>
<version>2.7.11</version>
</dependency>
<!--token生成-->
<!--JWT(token)相关依赖生成-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>

src/main/java/cn/star/controller/UserController.java → 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 login8.14改
@RequestMapping("/login")
public String login(HttpServletRequest request, HttpSession session, RedirectAttributes redirectAttributes)
@ResponseBody //
public Map<String,Object> login(HttpServletRequest request, HttpSession session)
{
Map<String,Object> 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")

5
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);
}

12
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 + '\'' +
'}';
}
}

96
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<String,Cookie> 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<String,Cookie> ReadCookieMap(HttpServletRequest request) {
Map<String,Cookie> cookieMap = new HashMap<String,Cookie>();
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("<script>alert('" + message + "'); window.location.href='/login.html';</script>");
out.flush();
out.close();
}
}*/
}
}

102
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<String, Object> header = new HashMap<>(2);
header.put("typ", "JWT");
header.put("alg", "HS256");
// 附带usernameuserId信息生成签名
return JWT.create()
.withHeader(header)
.withClaim("loginName", username)
.withClaim("userId",userId)
.withExpiresAt(date)
.sign(algorithm);
}
}

13
src/main/resources/spring-mvc.xml

@ -18,7 +18,7 @@
<!--配置的视图解析器对象-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
<property name="suffix" value=".html"/>
</bean>
<!--过滤静态资源-->
@ -30,12 +30,15 @@
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
<!--自定义拦截器
<!--自定义拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="checkLogin"/>
<!--拦截需要权限的接口-->
<mvc:mapping path="/user/**"/>
<mvc:mapping path="/admin/**"/>
<!--排除登录接口-->
<mvc:exclude-mapping path="/login"/>
<bean class="cn.star.interceptor.TokenInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>-->
</mvc:interceptors>
</beans>

src/main/webapp/WEB-INF/pages/Users.jsp → src/main/webapp/WEB-INF/jsp/Users.jsp

src/main/webapp/WEB-INF/pages/falselogin.jsp → src/main/webapp/WEB-INF/jsp/falselogin.jsp

src/main/webapp/index.jsp → 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" %>
<html>
<head>
<title>主界面</title>
<link rel="stylesheet" href="static/css/styles.css">
<link rel="stylesheet" href="../static/css/styles.css">
<style>
.my-class {
text-align: center;

src/main/webapp/WEB-INF/pages/success.jsp → src/main/webapp/WEB-INF/jsp/success.jsp

src/main/webapp/WEB-INF/pages/successlogin.jsp → src/main/webapp/WEB-INF/jsp/successlogin.jsp

2
src/main/webapp/WEB-INF/web.xml

@ -3,6 +3,7 @@
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<!-- 1. 过滤器(必须在 servlet 之前) -->
<context-param>
<param-name>contextConfigLocation</param-name>
@ -44,4 +45,5 @@
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

0
src/main/webapp/images

33
src/main/webapp/static/css/styles.css

@ -1,7 +1,30 @@
a {
color: #f80d43;
}
.center-text {
.my-class {
text-align: center;
}
/* 新增样式:登录表单容器 */
.login-container {
position: relative; /* 相对定位,用于子元素绝对定位 */
width: 300px; /* 固定宽度 */
margin: 20px auto; /* 居中显示 */
padding: 20px;
border: 1px solid #eee; /* 轻微边框 */
}
/* 按钮容器样式 */
.button-group {
display: flex; /* 弹性布局 */
justify-content: space-between; /* 两端对齐 */
margin-top: 15px; /* 与上方内容间距 */
}
/* 基础按钮样式 */
.base-btn {
padding: 6px 12px;
border: 1px solid #ccc;
background-color: #f5f5f5;
cursor: pointer; /* 鼠标悬停显示手型 */
text-decoration: none; /* 去除链接下划线 */
color: #333; /* 文字颜色 */
font-size: 14px;
}
.base-btn:hover {
background-color: #e0e0e0; /* 悬停效果 */
}
Loading…
Cancel
Save