vue+springboot によるシングル サインオンのクロスドメイン問題の実装方法 (詳細なチュートリアル)
この記事では、vue+springboot のフロントエンドとバックエンドを分離することによる、シングル サインオンのクロスドメイン問題の解決策を主に紹介します。必要な友人は参照してください
現在、バックに取り組んでいます。 -エンド管理システム。フロントエンドは人気のある vue.js を使用します。バックグラウンドは springboot に基づいています。バックエンドシステムにはログイン機能がありませんが、統一ログインが必要なため、ログイン認証には.netプロジェクトチームの認証システムを利用しています。つまり、シングル サインオンを行うということです。シングル サインオンが何なのかわからない学生には、万能の Du Niang にアクセスすることをお勧めします。
最初にこの要件を受け取ったとき、私は軽蔑しながらこう思いました。ログインするだけでは重要ではありません。しかし、開発プロセスは私を激しく叩きました(熱い平手打ち)。 。 。 , したがって、将来そのような落とし穴に足を踏み込まないように、今回はこの教訓をしっかりと記録する必要があります。
私が最初に直面した問題は、ブラウザ コンソールが CORS を直接報告することでした。私は、長年の開発経験を活かして、バックグラウンドでクロスドメイン構成を設定しました。コードは次のとおりです。
この設定では、すべてのマッピング、すべてのリクエスト ヘッダー、すべてのリクエスト メソッド、およびすべてのソースが許可されます。構成を変更した後、効果を確認するために思い切ってプロジェクトを再起動したところ、ブラウザー エラーの原因がクロスドメインであることがわかり、最初に のコードをアップロードしました。私のログインインターセプター
@Configuration public class CorsConfiguration { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedHeaders("*") .allowedMethods("*") .allowedOrigins("*"); } }; } }
その後、フロントエンド vue は
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; }
を使用してバックエンド ログイン インターフェイスを直接リクエストし、フロントエンドはシステムにアクセスし、シングル サインに直接ジャンプできます。 -ページ内。しかし、アカウントとパスワードを入力してクリックしてログインすると、システムに戻って、すべてのリクエスト データ インターフェイスに正常にアクセスできないことがわかりました。デバッグでは、すべてのリクエストにユーザー情報が含まれておらず、インターセプターによって認識されたことがわかりました。ログインしていないため、すべてのリクエストが通過できませんでした。
なぜ私は明らかにログインしているのに、インターセプターはユーザー情報をセッションに設定するのですか? なぜ Cookie が消えてしまうのでしょうか?再度リクエストを開始したところ、各リクエストの JsessionId が異なることがわかりました。多くの情報を確認したところ、フロントエンドに認証情報を追加できるように構成を追加する必要があることがわかりました
window.location.href=this.$api.config.baseUrl+"/system/user/login"
。バックエンドも対応する設定を行う必要がありますallowCredentials(true );
axios.defaults.withCredentials=true;
この設定を追加した後、操作プロセスを再実行したところ、ログイン後は通常どおりシステムにジャンプし、ページデータにジャンプできることがわかりましたも正常に表示されます。
終わったと思ったら、突然ページをクリックしてしまい、データが正常に表示されなくなり、慌ててF12を押すと、OPTIONSリクエストという、見たことのないリクエスト方法が見つかりました。このリクエストメソッドは明らかに POST でしたが、なぜ OPTIONS になったのでしょうか?そこで、他の POST リクエストをいくつか注文しましたが、それらはすべて OPTIONS リクエストになっていることがわかり、混乱してすぐに OPTIONS リクエストの情報を確認しました。OPTIONS リクエストは正式には「事前チェック リクエスト」と呼ばれているとのことです。リクエストが実行される前に、ブラウザはまず事前チェック リクエストを開始します。事前チェック リクエストが通過した後でのみ、正式なリクエストを実行できます。これを読んだ後、OPTIONS がインターセプトされたため、POST リクエストを実行できなくなったことに突然気づきました。その後、事前チェックリクエストを通過させました。この判断をインターセプターに追加するだけです
@Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedHeaders("*") .allowedMethods("*") .allowedOrigins("*").allowCredentials(true); } }; }
このように、インターセプターがリクエストが事前チェックリクエストであると判断した場合はそのままパスし、次のPOSTリクエストを実行することができます。
上記は私があなたのためにまとめたものです。
関連記事:
webpackが127.0.0.1にアクセスできない問題を解決する以上がvue+springboot によるシングル サインオンのクロスドメイン問題の実装方法 (詳細なチュートリアル)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









HTMLテンプレートのボタンをメソッドにバインドすることにより、VUEボタンに関数を追加できます。 VUEインスタンスでメソッドを定義し、関数ロジックを書き込みます。

vue.jsでBootstrapを使用すると、5つのステップに分かれています。ブートストラップをインストールします。 main.jsにブートストラップをインポートしますブートストラップコンポーネントをテンプレートで直接使用します。オプション:カスタムスタイル。オプション:プラグインを使用します。

Vue.jsの監視オプションにより、開発者は特定のデータの変更をリッスンできます。データが変更されたら、Watchはコールバック関数をトリガーして更新ビューまたはその他のタスクを実行します。その構成オプションには、すぐにコールバックを実行するかどうかを指定する即時と、オブジェクトまたは配列の変更を再帰的に聴くかどうかを指定するDEEPが含まれます。

vue.jsでJSファイルを参照するには3つの方法があります。タグ;; mounted()ライフサイクルフックを使用した動的インポート。 Vuex State Management Libraryを介してインポートします。

VUEマルチページ開発は、VUE.JSフレームワークを使用してアプリケーションを構築する方法です。アプリケーションは別々のページに分割されます。コードメンテナンス:アプリケーションを複数のページに分割すると、コードの管理とメンテナンスが容易になります。モジュール性:各ページは、簡単に再利用および交換するための別のモジュールとして使用できます。簡単なルーティング:ページ間のナビゲーションは、単純なルーティング構成を介して管理できます。 SEOの最適化:各ページには独自のURLがあり、SEOに役立ちます。

Vue Devtoolsを使用してブラウザのコンソールでVueタブを表示することにより、Vueバージョンを照会できます。 NPMを使用して、「NPM List -G Vue」コマンドを実行します。 package.jsonファイルの「依存関係」オブジェクトでVueアイテムを見つけます。 Vue CLIプロジェクトの場合、「Vue -Version」コマンドを実行します。 &lt; script&gt;でバージョン情報を確認してくださいVueファイルを参照するHTMLファイルにタグを付けます。

vue.jsには、前のページに戻る4つの方法があります。$ router.go(-1)$ router.back()outes&lt; router-link to =&quot;/&quot; Component Window.history.back()、およびメソッド選択はシーンに依存します。

VUEの関数傍受は、指定された期間内に関数が呼び出され、パフォーマンスの問題を防ぐ回数を制限するために使用される手法です。実装方法は次のとおりです。LodashLibrary:Import {Debounce}から「Lodash」からインポート。 debounce関数を使用して、インターセプト関数を作成します。インターセプト関数を呼び出すと、制御関数は500ミリ秒でせいぜい1回呼び出されます。
