程式碼如下:
@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中文網其他相關文章!

本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

Dreamweaver CS6
視覺化網頁開發工具