Dieses Mal bringe ich Ihnen Vue+Springboot-Front-End und Front-End-Trennung, domänenübergreifende Einzelpunkt-Anmeldung, Vue+Springboot-Front-End und Front-End-Trennung, domänenübergreifende Einzelpunkt-Anmeldung Was sind die Vorsichtsmaßnahmen? Das Folgende ist der eigentliche Kampf. Schauen wir uns den Fall an.
Vor kurzem arbeite ich an einem Back-End-Managementsystem. Das Front-End verwendet das beliebte vue.js und das Back-End basiert auf Springboot. Da das Backend-System keine Anmeldefunktion hat, das Unternehmen jedoch eine einheitliche Anmeldung benötigt, verwendet die Anmeldeauthentifizierung das Authentifizierungssystem des .net-Projektteams. Das bedeutet, dass Sie Single Sign-On durchführen müssen. Für Studierende, die nicht wissen, was Single Sign-On ist, empfehle ich Ihnen, sich an die Allzweck-App Du Niang zu wenden.
Als ich diese Anforderung zum ersten Mal erhielt, dachte ich mit Verachtung: Nur das Einloggen ist nicht wichtig. Der Entwicklungsprozess hat mich jedoch hart getroffen (ein heftiger Schlag). . . Deshalb muss ich diese Lektion dieses Mal sorgfältig aufzeichnen, um in Zukunft nicht in solche Fallstricke zu tappen.
Das erste Problem, mit dem ich konfrontiert war, war die domänenübergreifende Konfiguration von CORS. Mit meiner langjährigen Entwicklungserfahrung habe ich die domänenübergreifende Konfiguration wie folgt konfiguriert:
@Configuration public class CorsConfiguration { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedHeaders("*") .allowedMethods("*") .allowedOrigins("*"); } }; } }
Diese Konfiguration ermöglicht alle Zuordnungen, alle Anforderungsheader, alle Anforderungsmethoden und alle Quellen. Nachdem ich die Konfiguration geändert hatte, startete ich das Projekt entschlossen neu, um den Effekt zu sehen. Da ich sah, dass der Browserfehler durch domänenübergreifendes Umleiten verursacht wurde, habe ich zuerst den Code hochgeladen mein Login-Interceptor
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; }
Später fordert das Front-End-Vue die Anmeldeschnittstelle im Hintergrund direkt über
window.location.href=this.$api.config.baseUrl+"/system/user/login"
an Nachdem das Frontend auf das System zugreift, können Sie direkt zur Single-Sign-On-Seite springen. Aber als ich mein Konto und mein Passwort eingegeben und auf „Anmelden“ geklickt habe, sprang ich zurück zum System und stellte fest, dass nicht auf alle Anforderungsdatenschnittstellen normal zugegriffen werden konnte. Debug stellte fest, dass alle Anforderungen keine Benutzerinformationen enthielten und vom Interceptor als erkannt wurden nicht angemeldet, daher konnten nicht alle Anfragen angenommen werden.
Warum setzt der Interceptor auch Benutzerinformationen für die Sitzung, obwohl ich angemeldet bin? Warum sind die Cookies verschwunden? Ich habe erneut eine Anfrage initiiert und festgestellt, dass die JsessionId jeder Anfrage unterschiedlich war. Ich habe viele Informationen überprüft und festgestellt, dass ich eine Konfiguration hinzufügen muss, die das Hinzufügen von Authentifizierungsinformationen zum Frontend ermöglicht
axios.defaults.withCredentials=true;
Der Hintergrund muss auch eine entsprechende Konfiguration ermöglichen, AllowCredentials(true);
@Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedHeaders("*") .allowedMethods("*") .allowedOrigins("*").allowCredentials(true); } }; }
Nachdem ich diese Konfiguration hinzugefügt hatte, führte ich den Vorgang erneut aus und stellte fest, dass ich nach der Anmeldung normal zum System springen konnte und die Seitendaten auch normal angezeigt wurden.
Gerade als ich dachte, ich wäre fertig, klickte ich plötzlich auf eine Seite und die Daten konnten nicht normal angezeigt werden. Ich war so verwirrt, dass ich eine Anfragemethode fand, die ich noch nie zuvor gesehen hatte. Es stellte sich heraus, dass dies der Fall war Die Anforderungsmethode war offensichtlich POST. Warum wurde sie zu OPTIONS? Also bestellte ich mehrere andere POST-Anfragen und stellte fest, dass sie alle zu OPTIONS-Anfragen wurden. Ich war verwirrt und überprüfte schnell die Informationen von OPTIONS-Anfragen. Im Internet hieß es, dass OPTIONS-Anfragen „Vorabprüfungsanfragen“ heißen Bevor die Anfrage ausgeführt wird, initiiert der Browser zunächst eine Vorabprüfungsanforderung. Erst nachdem die Vorabprüfungsanforderung erfolgreich war, kann die formelle Anfrage ausgeführt werden. Nachdem ich es gelesen hatte, wurde mir plötzlich klar, dass OPTIONS abgefangen wurde, sodass ich meine POST-Anfrage nicht mehr ausführen konnte. Dann ließ ich die Vorabprüfungsanfrage einfach passieren. Fügen Sie dieses Urteil einfach dem Abfangjäger hinzu
//option预检查,直接通过请求 if ("OPTIONS".equals(request.getMethod())){ return true; }
Auf diese Weise stellt der Interceptor fest, dass es sich bei der Anfrage um eine Vorabprüfungsanforderung handelt, leitet sie direkt weiter und kann dann die nächste POST-Anfrage ausführen.
Ich glaube, dass Sie die Methode beherrschen, nachdem Sie den Fall in diesem Artikel gelesen haben. Weitere spannende Informationen finden Sie in anderen verwandten Artikeln auf der chinesischen PHP-Website!
Empfohlene Lektüre:
Anleitung zum Projektaufbau von vue
Ausführliche Erläuterung der Umsetzung der kleinen Kugelparabel durch vue Wirkung des Warenkorbs
Das obige ist der detaillierte Inhalt vonvue+springboot trennt die domänenübergreifende Einzelpunktanmeldung zwischen Front- und Back-End. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!