代码如下:
@Configuration public class CorsConfiguration { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedHeaders("*") .allowedMethods("*") .allowedOrigins("*"); } }; } }
这个配置就是允许所有mapping,所有请求头,所有请求方法,所有源。改好配置之后我果断重启项目,看效果,结果发现根本没法重定向跳转到单点登录页面,看浏览器报错是跨域导致的,我先上我登录拦截器的代码
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //用户已经登录 if (request.getSession().getAttribute("user") != null) { return true; } //从单点登录返回之后的状态,本系统还不处于登录状态 //根据code值去获取access_token,然后再根据access_token去获取用户信息,并将用户信息存到session中 String state = request.getParameter("state"); String uri = getUri(request); if (isLoginFromSSO(state)) { String code = request.getParameter("code"); Object cacheUrl = request.getSession().getAttribute(state); if (cacheUrl == null) { response.sendRedirect(uri); return false; } HttpUtil client = new HttpUtil(); StringBuffer sb = new StringBuffer(); sb.append("code=").append(code) .append("&grant_type=").append("authorization_code") .append("&client_id=").append(SSOAuth.ClientID) .append("&client_secret=").append(SSOAuth.ClientSecret) .append("&redirect_uri=").append(URLEncoder.encode((String) cacheUrl)); String resp = client.post(SSOAuth.AccessTokenUrl, sb.toString()); Map<string> map = new Gson().fromJson(resp, Map.class); //根据access_token去获取用户信息 String accessToken = map.get("access_token"); HttpUtil http = new HttpUtil(); http.addHeader("Authorization", "Bearer " + accessToken); String encrypt = http.get(SSOAuth.UserUrl); String userinfo = decryptUserInfo(encrypt); //封装成user对象 User user = new Gson().fromJson(userinfo, User.class); request.getSession().setAttribute("user", user); return true; } //跳转到单点登录界面 state = Const._SSO_LOGIN + Const.UNDERLINE + RandomUtil.getUUID(); request.getSession().setAttribute(state, uri); String redirectUrl = buildAuthCodeUrl(uri, state); response.sendRedirect(redirectUrl); return false; }</string>
后面把前端vue请求后台的登录接口方式直接用
window.location.href=this.$api.config.baseUrl+"/system/user/login"
之后前端访问系统,可以直接跳转到单点登录页面。但是当我输完账号和密码点击登录后回跳到系统,发现所有的请求数据接口都无法正常访问,debug发现所有的请求都没带用户信息,被拦截器识别为未登录,所有请求无法通过。
为什么我明明登录了呀,拦截器也设置了用户信息到session啊,怎么cookies那就没了呢?再次发起请求,发现每次请求的JsessionId都不一样,查了很多资料,发现是需要在前端加一个允许带认证信息的配置
axios.defaults.withCredentials=true;
后台也需要做一个相应的配置allowCredentials(true);
@Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedHeaders("*") .allowedMethods("*") .allowedOrigins("*").allowCredentials(true); } }; }
加完这个配置之后,重新执行一遍操作流程,发现登录之后能正常跳转到系统,页面数据也展示正常。
正当我以为大功告成的时候,突然点到一个页面又无法正常显示数据,好纳闷啊,赶紧F12,发现一个之前没见过的请求方式,OPTIONS请求,原来这个请求方式明明是POST呀,怎么就变成了OPTIONS了呢?于是我有点了其他几个POST的请求,发现都变成了OPTIONS请求,一脸懵逼的我赶紧查了一下OPTIONS请求的资料,网上说OPTIONS请求叫做“预检查请求”,就是在你的正式请求执行之前,浏览器会先发起预检查请求,预检查请求通过了,才能执行正式请求。看完恍然大悟,原来OPTIONS被拦截了,所以没法再执行我的POST的请求啊,那我直接让预检查请求通过就好了。只要在拦截器中加一个这个判断就好了
//option预检查,直接通过请求 if ("OPTIONS".equals(request.getMethod())){ return true; }
这样拦截器发现请求是预检查请求就直接通过,就可以执行接下来的POST的请求了。
以上是vue springboot前后端分离怎么解决单点登录跨域问题的详细内容。更多信息请关注PHP中文网其他相关文章!

关于曲线积分中变量替换的疑问本文将针对一个曲线积分计算中变量替换的步骤进行详细解释。提问者在计算一...

微信小程序申请流程及费用详解朋友委托开发微信小程序商城,在申请过程中遇到一些关于费用和流程的问题,...

Java缓存数据无法获取的原因分析及优化方案在Java项目中,将大量数据缓存到内存中以便快速访问是一个常见的�...

深入Java:值得探索的虚拟机世界很多Java开发者在掌握了基础语法和常用框架后,都希望进一步提升自己的技术�...

EasyExcel模板填充合并单元格时的常见问题在使用EasyExcel进行Excel...

系统对接中的字段映射挑战及其解决方案在系统对接过程中,经常会遇到需要将一个系统的接口字段映射到另一...

SpringBoot应用中PgJDBC连接池抛出PSQLException:ERROR:cancelingstatementduetouserrequest异常在使用SpringBoot MyBatis-Plus ...


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

WebStorm Mac版
好用的JavaScript开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

SublimeText3 Linux新版
SublimeText3 Linux最新版

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。