这两天用sa-token做业务发现,如果使用前端ajax请求到认证中心的话,会导致跨域问题,而跨域问题解决后悔导致认证中心的token失效了,我debug了一下发现在获取token的时候request已经变成新的了,所以存在Cookie里的token就会丢失,不知道怎么防止丢失,我避开了这个问题,解决办法如下:
在登录成功后,如果在客户端需要去请求其他路径,可以在这个路径上携带token,然后到认证中心的时候将这个token利用StpUtil工具类将token设置到认证中心的request中就可以了.
同理,如果认证中心重定向回来,token也可能丢失,所以我们将token放在重定向地址里作为参数,就不会丢失了.
这其实都是因为跨域问题,导致HttpServletRequest成新的对象了,所以Cookie被清空了,又或者是Cookie本身没有携带过来,这可能是Sa-Token的一个大坑.
下面是客户端的拦截器代码:
@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
/** 注册 [Sa-Token全局过滤器] */
@Bean
public SaServletFilter getSaServletFilter() {
return new SaServletFilter()
.addInclude("/**")
.addExclude("/sso/*","/oauth2/*" ,"/favicon.ico",
"/swagger-ui.html",
"/swagger-ui/**",
"/swagger-resources/**",
"/v2/api-docs",
"/v3/api-docs",
"/webjars/**")
.setAuth(obj -> {
//没登录的时候就去登录
if(!StpUtil.isLogin() && SaFoxUtil.isEmpty(SaHolder.getRequest().getParam("satoken"))) {
String back = SaFoxUtil.joinParam(SaHolder.getRequest().getUrl(), SpringMVCUtil.getRequest().getQueryString());
SaHolder.getResponse().redirect("/sso/login?back=" + SaFoxUtil.encodeUrl(back));
SaRouter.back();
//登录后但还未授权就去授权
}else if (SaFoxUtil.isEmpty(SaHolder.getRequest().getParam("code"))){
String back = SaFoxUtil.joinParam(SaHolder.getRequest().getUrl(), SpringMVCUtil.getRequest().getQueryString())+"?satoken="+StpUtil.getTokenValue();
SaHolder.getResponse().redirect("http://localhost:9000/oauth2/authorize?response_type=code&client_id=1001&redirect_uri=" + SaFoxUtil.encodeUrl(back)+"&scope=userinfo");
SaRouter.back();
}
//既登录又授权之后,就可以拿到code去请求token了,可以不在这里写
});
}
}
然后是认证中心的处理代码:
@RequestMapping("/oauth2/*")
public Object request() throws Exception {
System.out.println("------- 进入请求: " + SaHolder.getRequest().getUrl());
String redirect_uri = SaHolder.getRequest().getParam("redirect_uri");
Map<String, String> paramMap = SaStringUtil.getParamMap(redirect_uri);
StpUtil.setTokenValue(paramMap.get("satoken"));
return SaOAuth2Handle.serverRequest();
}
如果不懂代码怎么回事,可以去Sa-Token学习学习,也可以去我发的**贴子**上看.