package com.atguigu.spzx.manager.interceptor;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.atguigu.spzx.model.entity.system.SysUser;
import com.atguigu.spzx.model.vo.common.Result;
import com.atguigu.spzx.model.vo.common.ResultCodeEnum;
import com.atguigu.spzx.utils.AuthContextUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;
@Component
public class LoginAuthInterceptor implements HandlerInterceptor {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//1.获取请求方式
//请求方式未options 预检请求
String method = request.getMethod();
if ("OPTIONS".equals(method)) {
return true;
}
//2.从请求头获取token
String token = request.getHeader("token");
//3.如果为空,返回错误信息
if (StrUtil.isEmpty(token)) {
responseNoLoginInfo(response);
return false;
}
//4.如果token不为空,拿着token去redis查询
String userInfo = redisTemplate.opsForValue().get("user:login" + token);
//5.如果redis查不到信息,返回错误信息
if (StrUtil.isEmpty(userInfo)) {
responseNoLoginInfo(response);
return false;
}
//6.如果redis查到信息,把信息存到threadLocal里
SysUser sysUser = JSON.parseObject(userInfo, SysUser.class);
AuthContextUtil.set(sysUser);
//7.把redis用户信息数据过期过期时间
redisTemplate.expire("user:login" + token, 30, TimeUnit.MINUTES);
//8.放行
return true;
}
//响应208状态码给前端
private void responseNoLoginInfo(HttpServletResponse response) {
Result<Object> result = Result.build(null, ResultCodeEnum.LOGIN_AUTH);
PrintWriter writer = null;
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=utf-8");
try {
writer = response.getWriter();
writer.print(JSON.toJSONString(result));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null) writer.close();
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//删除threadLocal信息
AuthContextUtil.remove();
}
}
# 自定义配置
spzx:
auth:
noAuthUrls:
- /admin/system/index/login
- /admin/system/index/generateValidateCode
package com.atguigu.spzx.manager.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
@Data
@ConfigurationProperties(prefix = "spzx.auth")
public class UserProperties {
private List<String> noAuthUrls;
}
package com.atguigu.spzx.manager.config;
import com.atguigu.spzx.manager.interceptor.LoginAuthInterceptor;
import com.atguigu.spzx.manager.properties.UserProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Component
public class WebMvcConfiguration implements WebMvcConfigurer {
@Autowired
private LoginAuthInterceptor loginAuthInterceptor;
@Autowired
private UserProperties userProperties;
//拦截器注册
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginAuthInterceptor)
// .excludePathPatterns("/admin/system/index/login" ,
// "/admin/system/index/generateValidateCode")
.excludePathPatterns(userProperties.getNoAuthUrls())
.addPathPatterns("/**");
}
//跨域问题
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 添加路径规则
.allowCredentials(true) // 是否允许在跨域的情况下传递Cookie
.allowedOriginPatterns("*") // 允许请求来源的域规则
.allowedMethods("*")
.allowedHeaders("*"); // 允许所有的请求头
}
}
package com.atguigu.spzx.manager;
import com.atguigu.spzx.manager.properties.UserProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = {"com.atguigu.spzx"})
@EnableConfigurationProperties(value = {UserProperties.class})
public class ManagerApplication {
public static void main(String[] args) {
SpringApplication.run(ManagerApplication.class,args);
}
}