前端处理:
- 在request.js中添加如下代码,允许跨域携带cookie
import axios from 'axios'
axios.defaults.withCredentials = true // 添加代码:允许跨域携带cookie
- 请求拦截添加token
service.interceptors.request.use(
config => {
if (store.getters.token) {
//添加token到Header的Authorization中
config.headers['Authorization'] = 'Bearer ' + getToken()
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
后端处理:
- 添加SessionInterceptor拦截器,来控制登录的逻辑判断
@Component
public class SessionInterceptor extends HandlerInterceptorAdapter {
/**
* @param request 请求对象
* @param response 响应对象
* @param handler 前置对象
* @return 返回false=拦截 返回true=继续执行请求
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if ("OPTIONS".equals(request.getMethod())) {
return true;
}
// session expire
if (request.getSession(false) == null || request.getHeader("Authorization") == null) {
response.sendError(HttpStatus.UNAUTHORIZED.value(), "登录超时,请重新登录");
return false;
}
// validate token in session
else if (request.getSession().getAttribute("token") != null) {
String token = request.getHeader("Authorization");
if (token.equals("Bearer " + request.getSession().getAttribute("token").toString())) {
return true;
} else {
response.sendError(HttpStatus.UNAUTHORIZED.value(), "登录令牌无效,请重新登录");
return false;
}
}
// invalid session
else {
response.sendError(HttpStatus.UNAUTHORIZED.value(), "登录会话异常,请重新登录");
return false;
}
}
}
- 将拦截器注入到配置,并添加跨域处理
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
/**
* SessionInterceptor 处理登录逻辑判断
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//白名单地址 注意:不要添加server.servlet.servcontext-path:的目录
List<String> excludeUrl = Arrays.asList("/user/login", "/error",
"/webjars/**", "/swagger-resources/**", "/swagger-ui.html");
registry.addInterceptor(new SessionInterceptor())
// 这里用/**表示拦截所有请求
.addPathPatterns("/**")
// 排除白名单地址
.excludePathPatterns(excludeUrl);
}
/**
* 前后端跨域,解决session为空
*
* @return
*/
@Bean
public WebMvcConfigurer webMvcConfigurer2() {
return new WebMvcConfigurer() {
/**
* 设置头 使可以跨域访问
* @param registry
* @since 4.2
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.maxAge(3600)
.allowCredentials(true);
}
};
}
}
- 在登录成功时设置session中的token并下发
@Autowired
private HttpSession session;
/**
* 登录
*/
public LoginVO login(LoginDTO dto) {
User user = baseMapper.login(dto.getUsername());
LoginVO loginVO = Optional.ofNullable(user).map(x -> {
String slatPassword = SecureUtil.md5(dto.getPassword() + x.getSlat());
if (!x.getPassword().equals(slatPassword)) {
throw new AppException("用户名或密码错误");
}
LoginVO u = LoginVO.builder().build();
BeanUtils.copyProperties(user, u);
u.setRole(x.getRoleId().equals(1) ? "管理员" : "审计员");
return u;
}).orElseThrow(resolver("用户名或密码错误"));
String token = UUID.randomUUID().toString();
session.setAttribute("token", token);
loginVO.setToken(token);
return loginVO;
}
/*
* api接口返回
*/
@ApiOperation(value = "用户-登录")
@PostMapping(value = "/login")
@UserLog(module = SystemLogModuleEnum.USER, type = "登录")
public R login(@RequestBody @Valid LoginDTO loginDTO) {
LoginVO loginVO = userService.login(loginDTO);
return R.ok(loginVO);
}
使用 vue + springboot 前后端分离 跨域、cookie、session 问题,全套配置一篇就够了
前后端分离 vue+springboot 跨域 session+cookie失效问题