首頁 web前端 js教程 vue+springboot如何實作單一登入跨網域問題(詳細教學)

vue+springboot如何實作單一登入跨網域問題(詳細教學)

Jun 08, 2018 pm 06:19 PM
boot spring vue 前後端分離 跨域

這篇文章主要介紹了vue springboot前後端分離實現單一登入跨域問題的解決方法,需要的朋友可以參考下

#最近在做一個後台管理系統,前端是用時下火熱的vue.js,後台是基於springboot的。因為後台系統沒有登入功能,但是公司要求統一登錄,登入認證統一使用.net專案組的認證系統。那就意味著做單點登入咯,至於不知道什麼是單一登入的同學,建議去找萬能的度娘。

剛接到這個需求的時候,老夫心裡便不屑的認為:區區登入何足掛齒,但是,開發的過程狠狠的打了我一巴掌(火辣辣的一巴掌)。 。 。 ,所以這次必須得好好記錄一下這次教訓,以免以後再踩這樣的坑。

我面臨的第一個問題是跨域,瀏覽器控制台直接報CORS,以我多年開發經驗,我果斷在後台配置了跨域配置,程式碼如下:

@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, 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;
}
登入後複製

後面把前端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的請求了。

上面是我整理給大家的,希望今後對大家有幫助。

相關文章:

解決webpack無法存取127.0.0.1的問題

在Node.js中使用Async和Await函數

在Angular中傳遞範本給元件

########################################## #

以上是vue+springboot如何實作單一登入跨網域問題(詳細教學)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

vue中怎麼用bootstrap vue中怎麼用bootstrap Apr 07, 2025 pm 11:33 PM

在 Vue.js 中使用 Bootstrap 分為五個步驟:安裝 Bootstrap。在 main.js 中導入 Bootstrap。直接在模板中使用 Bootstrap 組件。可選:自定義樣式。可選:使用插件。

vue怎麼給按鈕添加函數 vue怎麼給按鈕添加函數 Apr 08, 2025 am 08:51 AM

可以通過以下步驟為 Vue 按鈕添加函數:將 HTML 模板中的按鈕綁定到一個方法。在 Vue 實例中定義該方法並編寫函數邏輯。

vue中的watch怎麼用 vue中的watch怎麼用 Apr 07, 2025 pm 11:36 PM

Vue.js 中的 watch 選項允許開發者監聽特定數據的變化。當數據發生變化時,watch 會觸發一個回調函數,用於執行更新視圖或其他任務。其配置選項包括 immediate,用於指定是否立即執行回調,以及 deep,用於指定是否遞歸監聽對像或數組的更改。

vue多頁面開發是啥意思 vue多頁面開發是啥意思 Apr 07, 2025 pm 11:57 PM

Vue 多頁面開發是一種使用 Vue.js 框架構建應用程序的方法,其中應用程序被劃分為獨立的頁面:代碼維護性:將應用程序拆分為多個頁面可以使代碼更易於管理和維護。模塊化:每個頁面都可以作為獨立的模塊,便於重用和替換。路由簡單:頁面之間的導航可以通過簡單的路由配置來管理。 SEO 優化:每個頁面都有自己的 URL,這有助於搜索引擎優化。

vue.js怎麼引用js文件 vue.js怎麼引用js文件 Apr 07, 2025 pm 11:27 PM

在 Vue.js 中引用 JS 文件的方法有三種:直接使用 &lt;script&gt; 標籤指定路徑;利用 mounted() 生命週期鉤子動態導入;通過 Vuex 狀態管理庫進行導入。

vue返回上一頁的方法 vue返回上一頁的方法 Apr 07, 2025 pm 11:30 PM

Vue.js 返回上一頁有四種方法:$router.go(-1)$router.back()使用 &lt;router-link to=&quot;/&quot;&gt; 組件window.history.back(),方法選擇取決於場景。

vue遍歷怎麼用 vue遍歷怎麼用 Apr 07, 2025 pm 11:48 PM

Vue.js 遍歷數組和對像有三種常見方法:v-for 指令用於遍歷每個元素並渲染模板;v-bind 指令可與 v-for 一起使用,為每個元素動態設置屬性值;.map 方法可將數組元素轉換為新數組。

vue的div怎麼跳轉 vue的div怎麼跳轉 Apr 08, 2025 am 09:18 AM

Vue 中 div 元素跳轉的方法有兩種:使用 Vue Router,添加 router-link 組件。添加 @click 事件監聽器,調用 this.$router.push() 方法跳轉。

See all articles