Maison >Java >javaDidacticiel >Comment résoudre le problème inter-domaines de l'authentification unique en séparant le front-end et le back-end de vue+springboot
Le code est le suivant :
@Configuration public class CorsConfiguration { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedHeaders("*") .allowedMethods("*") .allowedOrigins("*"); } }; } }
Cette configuration autorise tous les mappages, tous les en-têtes de requêtes, toutes les méthodes de requêtes et toutes les sources. Après avoir modifié la configuration, j'ai redémarré le projet de manière décisive pour voir l'effet. J'ai constaté qu'il n'y avait aucun moyen de rediriger vers la page de connexion unique. Voyant que l'erreur du navigateur était causée par un interdomaine, j'ai d'abord ajouté le code de. mon intercepteur de connexion
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; }
Utilisez
window.location.href=this.$api.config.baseUrl+"/system/user/login"
pour utiliser directement la vue frontale pour demander l'interface de connexion back-end. Ensuite, le front-end accède au système et peut accéder directement à la page de connexion unique. Mais lorsque j'ai entré mon compte et mon mot de passe et cliqué pour me connecter, je suis revenu au système et j'ai constaté que toutes les interfaces de données de requête n'étaient pas accessibles normalement. Debug a constaté que toutes les requêtes ne contenaient pas d'informations utilisateur et étaient reconnues par l'intercepteur comme étant. pas connecté, donc toutes les demandes n’ont pas pu être acceptées.
Pourquoi suis-je clairement connecté et l'intercepteur définit également les informations utilisateur sur la session. Pourquoi les cookies ont-ils disparu ? J'ai lancé une nouvelle demande et j'ai constaté que le JsessionId de chaque demande était différent. Après avoir vérifié de nombreuses informations, j'ai découvert qu'une configuration permettant les informations d'authentification devait être ajoutée au front-end
axios.defaults.withCredentials=true;
Une configuration correspondante doit également être ajoutée. effectué dans le backend allowCredentials(true);
@Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedHeaders("*") .allowedMethods("*") .allowedOrigins("*").allowCredentials(true); } }; }
Après avoir ajouté cette configuration, j'ai réexécuté le processus d'opération et j'ai constaté qu'après m'être connecté, je peux accéder au système normalement et les données de la page s'affichent également normalement.
Juste au moment où je pensais avoir terminé, j'ai soudainement cliqué sur une page et les données ne pouvaient pas être affichées normalement. J'étais tellement confus que j'ai rapidement F12 et j'ai trouvé une méthode de requête que je n'avais jamais vue auparavant, la requête OPTIONS. que cette méthode de requête était évidemment POST. Pourquoi est-elle devenue OPTIONS ? J'ai donc commandé plusieurs autres requêtes POST et j'ai découvert qu'elles se sont toutes transformées en requêtes OPTIONS. J'étais confus et j'ai rapidement vérifié les informations des requêtes OPTIONS. Internet a dit que les requêtes OPTIONS sont appelées "demandes de pré-vérification", ce qui signifie que dans votre formulaire. Avant que la demande ne soit exécutée, le navigateur lancera d'abord une demande de pré-vérification. Ce n'est qu'une fois la demande de pré-vérification réussie que la demande formelle pourra être exécutée. Après l'avoir lu, j'ai soudain réalisé que OPTIONS avait été interceptée, je ne pouvais donc plus exécuter ma requête POST. Ensuite, j'ai simplement laissé passer la requête de pré-vérification. Ajoutez simplement ce jugement à l'intercepteur
//option预检查,直接通过请求 if ("OPTIONS".equals(request.getMethod())){ return true; }
De cette façon, si l'intercepteur constate que la requête est une requête de pré-vérification, il la transmettra directement et la prochaine requête POST pourra être exécutée.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!