一、准备
- 依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.10.7</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.10.7</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.10.7</version>
</dependency>
- 使用Md5工具对数据库密码加密
@Slf4j
public class Md5Utils {
public static String getMD5String(String str) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes());
return new BigInteger(1, md.digest()).toString(16);
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("{}计算md5异常:{}",stackTraceElement,e.getMessage());
return null;
}
}
}
- 生成rsa的私钥和公钥,可以在线生成,不要空格不要换行,不要其他的字符
- 从数据库获取用户名和使用md5加密的密码
@Override
public ResultVo login(ManagerDto managerDto) {
if (ObjectUtils.isEmpty(managerDto)){
return new ResultVo().failure(ResultCode.PARAMETER_INVALID);
}
try {
String userName = managerDto.getUserName();
String password = managerDto.getPassword();
IdleManagerEntity manager = managerMapper.getManager(userName);
if (manager == null){
log.info("用户名为空");
return new ResultVo().failure(ResultCode.USER_NULL);
}
String md5String = Md5Utils.getMD5String(password);
if (!md5String.equals(manager.getMd5Password())){
log.info("密码错误");
return new ResultVo().failure(ResultCode.PASSWORD_ERROR);
}
log.info(" {} already login",userName);
manager.setMd5Password("");
try {
PrivateKey privateKey = RsaUtils.getPrivateKey(ResourceUtils.getFile("src/main/resources/rsa.pri").getPath());
String token = JwtUtils.generateTokenExpireInMinutes(manager, privateKey, 1);
return new ResultVo().success(token);
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("{}token error:{}",stackTraceElement,e.getMessage());
return new ResultVo().failure(ResultCode.SYSTEM_ERROR);
}
} catch (Exception e) {
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("登录异常");
return new ResultVo().failure(ResultCode.SYSTEM_ERROR);
}
}
二、需要对请求方法进行拦截,判断是否携带token或者是否过期
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
String method = request.getMethod();
if(method.equals("OPTIONS")){
return true;
}
String token = request.getHeader("token");
PublicKey publicKey = RsaUtils.getPublicKey(
ResourceUtils.getFile("src/main/resources/rsa.pub").getPath());
try {
IdleManagerEntity manager = (IdleManagerEntity) JwtUtils.getInfoFromToken(token, publicKey, IdleManagerEntity.class);
return true;
}catch (Exception e){
StackTraceElement stackTraceElement = e.getStackTrace()[0];
log.error("{}token error:{}",stackTraceElement,e.getMessage());
}
response.sendRedirect(request.getContextPath()+"/login");
return false;
}
}
三、需要将拦截器注册到springmvc中,放行登录请求
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor)
.excludePathPatterns("/login")
.addPathPatterns("/**");
}
}