In diesem Artikel wird hauptsächlich die Lösung des domänenübergreifenden Problems des Single Sign-On durch die Trennung von Vue + Springboot-Frontend und Back-End vorgestellt
Ich bin Derzeit wird an einem Back-End-Managementsystem gearbeitet. Das Front-End verwendet das aktuelle beliebte vue.js, das Backend 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 (eine heftige Ohrfeige). . . Deshalb muss ich diese Lektion dieses Mal gut 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, habe ich das Projekt entschlossen neu gestartet, um den Effekt zu sehen. Da ich festgestellt habe, dass es keine Möglichkeit gibt, zur Single-Sign-In-Seite umzuleiten, habe ich zuerst den Code von 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; }
Der Front-End-Vue fordert die Back-End-Login-Schnittstelle direkt über
window.location.href=this.$api.config.baseUrl+"/system/user/login"
< an 🎜>
und dann 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 die Anfrage erneut 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öglichtaxios.defaults.withCredentials=true;
@Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedHeaders("*") .allowedMethods("*") .allowedOrigins("*").allowCredentials(true); } }; }
//option预检查,直接通过请求 if ("OPTIONS".equals(request.getMethod())){ return true; }
Lösung des Problems, dass Webpack nicht auf 127.0.0.1 zugreifen kann
Verwendung von Async in Node.js und Wartefunktion
Übergabe der Vorlage an die Komponente in Angular
Das obige ist der detaillierte Inhalt vonWie vue+springboot domänenübergreifende Single-Sign-On-Probleme implementiert (ausführliches Tutorial). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!