完成了没有Redis情况下的登录和Token验证
parent
d4ef6ea2cf
commit
1397496bc3
|
@ -2,6 +2,7 @@ package cn.edu.hfut.rmdjzz.projectmanagement.config;
|
|||
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.interceptor.CorsInterceptor;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.interceptor.TokenInterceptor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
@ -14,7 +15,7 @@ import javax.annotation.Resource;
|
|||
*/
|
||||
@Configuration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
@Resource
|
||||
@Autowired
|
||||
private CorsInterceptor corsInterceptor;
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package cn.edu.hfut.rmdjzz.projectmanagement.controller;
|
||||
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.exception.LoginException;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.service.impl.StaffServiceImpl;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author 张韬
|
||||
* created at 2022/6/28 21:59
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
public class StaffController {
|
||||
@Autowired
|
||||
private StaffServiceImpl staffServiceImpl;
|
||||
|
||||
@PostMapping("/login")
|
||||
public ResponseMap login(@RequestBody Staff staff) throws LoginException, JsonProcessingException {
|
||||
return staffServiceImpl.login(staff.getStaffUsername(), staff.getStaffPassword());
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package cn.edu.hfut.rmdjzz.projectmanagement.entity;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author 张韬
|
||||
* created at 2022/6/28 18:32
|
||||
*/
|
||||
@Data
|
||||
public class Response implements Serializable {
|
||||
private int code;
|
||||
private String msg;
|
||||
Map<String,Object> data = new HashMap<>();
|
||||
public void put(String key,Object value){
|
||||
data.put(key,value);
|
||||
}
|
||||
public String JsonString() throws JsonProcessingException {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
return objectMapper.writeValueAsString(this);
|
||||
}
|
||||
}
|
|
@ -16,4 +16,5 @@ public class Staff {
|
|||
private String staffPassword;
|
||||
private String staffFullname;
|
||||
private String staffGender;
|
||||
private String staffSalt;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package cn.edu.hfut.rmdjzz.projectmanagement.exception;
|
||||
|
||||
/**
|
||||
* @author 张韬
|
||||
* created at 2022/6/28 21:24
|
||||
*/
|
||||
public class LoginException extends Exception{
|
||||
public LoginException(String message){super(message);}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package cn.edu.hfut.rmdjzz.projectmanagement.exception;
|
||||
|
||||
/**
|
||||
* @author 张韬
|
||||
* created at 2022/6/28 23:34
|
||||
*/
|
||||
public class TokenException extends Exception{
|
||||
public TokenException(String message){super(message);}
|
||||
}
|
|
@ -1,14 +1,20 @@
|
|||
package cn.edu.hfut.rmdjzz.projectmanagement.interceptor;
|
||||
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Response;
|
||||
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.exception.TokenException;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author 张韬
|
||||
|
@ -16,31 +22,31 @@ import javax.servlet.http.HttpServletResponse;
|
|||
*/
|
||||
@Component
|
||||
public class TokenInterceptor implements HandlerInterceptor {
|
||||
@Resource
|
||||
private ObjectMapper objectMapper;
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
|
||||
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws TokenException, IOException {
|
||||
System.out.println(httpServletRequest.getRequestURL()+" "+httpServletRequest.getMethod());
|
||||
if (!(object instanceof HandlerMethod)) {
|
||||
return false;
|
||||
}
|
||||
String token = httpServletRequest.getHeader("token");
|
||||
String token = httpServletRequest.getHeader("Token");
|
||||
if (null == token || "".equals(token.trim())) {
|
||||
Response res=new Response();
|
||||
res.setMsg("缺少Token");
|
||||
res.setCode(HttpStatus.UNAUTHORIZED.value());
|
||||
httpServletResponse.getWriter().print(res.JsonString());
|
||||
ResponseMap res= ResponseMap.of(HttpStatus.UNAUTHORIZED.value(),"缺少Token");
|
||||
httpServletResponse.getWriter().print(objectMapper.writeValueAsString(res));
|
||||
return false;
|
||||
}
|
||||
if(token.charAt(0)=='"'||token.charAt(0)=='\'')
|
||||
token=token.substring(1,token.length()-1);
|
||||
System.out.println(token);
|
||||
if(!TokenUtils.checkToken(token)){
|
||||
Response res=new Response();
|
||||
res.setMsg("无效的Token");
|
||||
res.setCode(HttpStatus.UNAUTHORIZED.value());
|
||||
httpServletResponse.getWriter().print(res.JsonString());
|
||||
ResponseMap res= ResponseMap.of(HttpStatus.UNAUTHORIZED.value(),"无效的Token");
|
||||
httpServletResponse.getWriter().print(objectMapper.writeValueAsString(res));
|
||||
return false;
|
||||
}
|
||||
httpServletRequest.setAttribute("token", TokenUtils.autoRequire(token));
|
||||
if(TokenUtils.checkTimeOut(token)){
|
||||
ResponseMap res= ResponseMap.of(HttpStatus.UNAUTHORIZED.value(),"Token已过期");
|
||||
httpServletResponse.getWriter().print(objectMapper.writeValueAsString(res));
|
||||
return false;
|
||||
}
|
||||
httpServletResponse.setHeader("Token",TokenUtils.autoRequire(token));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
package cn.edu.hfut.rmdjzz.projectmanagement.service;
|
||||
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.exception.LoginException;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
|
||||
/**
|
||||
* @author 佘语殊
|
||||
* @since 2022/6/28 17:28
|
||||
*/
|
||||
public interface IStaffService extends IService<Staff> {
|
||||
ResponseMap login(String username, String password) throws LoginException, JsonProcessingException;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,20 @@
|
|||
package cn.edu.hfut.rmdjzz.projectmanagement.service.impl;
|
||||
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.exception.LoginException;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.mapper.StaffMapper;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.service.IStaffService;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils;
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.DigestUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* @author 佘语殊
|
||||
|
@ -12,4 +22,25 @@ import org.springframework.stereotype.Service;
|
|||
*/
|
||||
@Service
|
||||
public class StaffServiceImpl extends ServiceImpl<StaffMapper, Staff> implements IStaffService {
|
||||
|
||||
@Override
|
||||
public ResponseMap login(String username, String password) throws LoginException, JsonProcessingException {
|
||||
if(username==null||username.trim().length()==0)
|
||||
throw new LoginException("用户名为空");
|
||||
else if(!username.equals(username.replaceAll("[^a-zA-Z0-9]", "")))
|
||||
throw new LoginException("用户名格式错误");
|
||||
else if(password==null||password.trim().length()!=32)
|
||||
throw new LoginException("密码格式错误");
|
||||
Staff staff = getOne(Wrappers.<Staff>lambdaQuery().eq(Staff::getStaffUsername,username));
|
||||
if(staff==null)
|
||||
throw new LoginException("用户不存在");
|
||||
password= DigestUtils.md5DigestAsHex((password+staff.getStaffSalt()).getBytes());
|
||||
if(!staff.getStaffPassword().equals(password))
|
||||
throw new LoginException("密码错误");
|
||||
ResponseMap res=ResponseMap.ofSuccess("ok").put("username",username);
|
||||
res.put("Token",TokenUtils.getToken(staff.getStaffUsername(),staff.getStaffId()));
|
||||
res.put("staffFullname",staff.getStaffFullname());
|
||||
res.put("staffId",staff.getStaffId());
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package cn.edu.hfut.rmdjzz.projectmanagement.utils;
|
||||
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.exception.TokenException;
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.JWTVerifier;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
|
@ -12,40 +13,46 @@ import java.util.Date;
|
|||
* @author 张韬
|
||||
* created at 2022/6/28 18:20
|
||||
*/
|
||||
//TODO: 演示的时候把expireTime改短点儿
|
||||
public final class TokenUtils {
|
||||
public final static String pvKey="SignedByRMDJZZ";
|
||||
public static String getToken(String username){
|
||||
public static String getToken(String username,Integer staffId){
|
||||
return JWT.create()
|
||||
.withClaim("username", username)
|
||||
.withClaim("staffId", staffId)
|
||||
.withIssuedAt(new Date())
|
||||
.withExpiresAt(new Date(System.currentTimeMillis() + 5*60*60*1000))
|
||||
.sign(Algorithm.HMAC256(pvKey));
|
||||
|
||||
}
|
||||
public static boolean checkToken(String token) {
|
||||
public static boolean checkToken(String token) throws TokenException {
|
||||
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(pvKey)).build();
|
||||
try {
|
||||
verifier.verify(token);
|
||||
return true;
|
||||
} catch (JWTVerificationException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
throw new TokenException("非法的Token");
|
||||
}
|
||||
}
|
||||
public static boolean checkTimeOut(String token){
|
||||
public static boolean checkTimeOut(String token) throws TokenException {
|
||||
if(!checkToken(token))
|
||||
return true;
|
||||
return JWT.decode(token).getClaim("exp").asLong()<(System.currentTimeMillis()/1000);
|
||||
}
|
||||
public static String getUsername(String token){
|
||||
public static String getUsername(String token) throws TokenException {
|
||||
if(!checkToken(token))
|
||||
return "";
|
||||
return null;
|
||||
return JWT.decode(token).getClaim("username").asString();
|
||||
}
|
||||
public static String refreshToken(String token) {
|
||||
return getToken(getUsername(token));
|
||||
public static Integer getStaffId(String token) throws TokenException {
|
||||
if(!checkToken(token))
|
||||
return null;
|
||||
return JWT.decode(token).getClaim("staffId").asInt();
|
||||
}
|
||||
public static String autoRequire(String token) {
|
||||
public static String refreshToken(String token) throws TokenException {
|
||||
return getToken(getUsername(token),getStaffId(token));
|
||||
}
|
||||
public static String autoRequire(String token) throws TokenException {
|
||||
boolean check = checkToken(token);
|
||||
if (check) {
|
||||
DecodedJWT jwt = JWT.decode(token);
|
||||
|
|
|
@ -2,12 +2,14 @@ package cn.edu.hfut.rmdjzz.projectmanagement.utils.response;
|
|||
|
||||
import cn.edu.hfut.rmdjzz.projectmanagement.utils.BeanUtils;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import org.springframework.core.serializer.support.SerializationFailedException;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -18,13 +20,12 @@ import java.util.Map;
|
|||
* @author 佘语殊
|
||||
* @since 2022/6/28 21:29
|
||||
*/
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
@AllArgsConstructor(access = AccessLevel.PUBLIC)
|
||||
@Data
|
||||
public class ResponseMap {
|
||||
private Integer code;
|
||||
private String msg;
|
||||
private Map<String, Object> data;
|
||||
|
||||
/**
|
||||
* 静态构造方法
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue