今回は、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("*");
}
};
}
}
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 リクエストは、正式な Before では「事前チェック リクエスト」と呼ばれているとのことです。リクエストが実行されると、ブラウザはまず事前チェック リクエストを開始し、事前チェック リクエストが通過した後にのみ正式なリクエストを実行できます。これを読んだ後、OPTIONS がインターセプトされたため、POST リクエストを実行できなくなったことに突然気づきました。その後、事前チェックリクエストを通過させました。この判断をインターセプターに追加するだけです
@Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedHeaders("*") .allowedMethods("*") .allowedOrigins("*").allowCredentials(true); } }; }
このようにして、インターセプターはリクエストが事前チェックリクエストであることを認識し、それを直接渡し、次の POST リクエストを実行できるようになります。
この記事の事例を読んだ後は、この方法を習得したと思います。さらに興味深い情報については、php 中国語 Web サイトの他の関連記事に注目してください。
推奨読書:
vueのプロジェクト構造の説明vue ショッピングカートの小さなボール放物線効果の実現についての詳細な説明以上がvue+springboot は、単一ポイントのクロスドメイン ログインをフロントエンドとバックエンドから分離します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。