Maison  >  Article  >  interface Web  >  vue+springboot sépare la connexion inter-domaines en un seul point entre le front-end et le back-end

vue+springboot sépare la connexion inter-domaines en un seul point entre le front-end et le back-end

php中世界最好的语言
php中世界最好的语言original
2018-04-13 10:23:392565parcourir

Cette fois, je vous proposerai vue+springboot séparation front-end et back-end connexion inter-domaine en un seul point, vue+springboot front-end et séparation front-end connexion inter-domaine en un seul point Quelles sont les précautions, voici le combat réel. Jetons un coup d'œil au cas.

Récemment, je travaille sur un système de gestion back-end. Le front-end utilise le populaire vue.js et le back-end est basé sur springboot. Étant donné que le système backend n'a pas de fonction de connexion, mais que l'entreprise nécessite une connexion unifiée, l'authentification de connexion utilise le système d'authentification de l'équipe du projet .net. Cela signifie faire de l'authentification unique. Quant aux étudiants qui ne savent pas ce qu'est l'authentification unique, je vous suggère d'aller au Du Niang polyvalent.

Lorsque j'ai reçu cette exigence pour la première fois, j'ai pensé avec dédain : le simple fait de se connecter n'est pas important. Cependant, le processus de développement m'a durement giflé (une gifle chaude). . . , je dois donc enregistrer cette leçon soigneusement cette fois pour éviter de tomber dans de tels pièges à l'avenir.

Le premier problème que j'ai rencontré était inter-domaines. La console du navigateur a directement signalé CORS. Grâce à mes nombreuses années d'expérience en développement, j'ai configuré de manière décisive la configuration inter-domaines en arrière-plan. 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ête, toutes les

méthodes de requête 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 téléchargé 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;
}
Plus tard, la vue frontale demande l'arrière-plan

interface de connexion directement en utilisant

window.location.href=this.$api.config.baseUrl+"/system/user/login"
Une fois que le frontal a accédé au système, vous pouvez accéder directement à la page d'authentification unique. Mais lorsque j'ai entré le compte et le 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 évidemment connecté, mais l'intercepteur définit également les informations utilisateur sur la session ? Pourquoi les cookies ont-ils disparu ? J'ai lancé à nouveau une demande et j'ai constaté que le JsessionId de chaque demande était différent. J'ai vérifié beaucoup d'informations et j'ai découvert que je devais ajouter une configuration permettant d'ajouter des informations d'authentification au front-end

Le backend doit également effectuer une configuration correspondante allowCredentials(true);
axios.defaults.withCredentials=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 pouvais accéder au système normalement et les données de la page étaient également affichées normalement.
@Bean
public WebMvcConfigurer corsConfigurer() {
 return new WebMvcConfigurerAdapter() {
  @Override
  public void addCorsMappings(CorsRegistry registry) {
   registry.addMapping("/**")
     .allowedHeaders("*")
     .allowedMethods("*")
     .allowedOrigins("*").allowCredentials(true);
  }
 };
}

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. La méthode de requête était évidemment POST. Pourquoi a-t-elle changé ? 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 dans votre Avant formel. la demande est 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

De cette façon, l'intercepteur découvre que la requête est une requête de pré-vérification et la transmet directement, puis la requête POST suivante peut être exécutée.
//option预检查,直接通过请求
if ("OPTIONS".equals(request.getMethod())){
 return true;
}

Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web chinois de php !

Lecture recommandée :

Instructions pour la structure du projet de vue


Explication détaillée de l'implémentation par vue de la petite parabole boule effet du panier


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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn