Maison >Java >javaDidacticiel >Comment résoudre le problème de l'échec des cookies et des domaines Ajax dans SpringBoot

Comment résoudre le problème de l'échec des cookies et des domaines Ajax dans SpringBoot

王林
王林avant
2023-05-26 09:56:131574parcourir

Lors de la rédaction de la page d'inscription de connexion de mon projet, étant donné que mes fonctions d'inscription et de changement de mot de passe utilisent la vérification par e-mail, le backend ajoutera un cookie aux données de réponse lors de l'envoi du code de vérification

Cookie cookie = new Cookie(toEmail.split("@")[0],verCode);
cookie.setMaxAge(30*60);
response.addCookie(cookie);
#🎜 🎜#Puis lorsque vous cliquez pour vous inscrire ou modifier le mot de passe, le backend obtiendra le cookie de la demande d'obtention des informations sur l'e-mail et le code de vérification

Cookie[] cookies = request.getCookies();

Lors du test local, le cookie peut être ajouté correctement à la réponse, et il peut aussi être correctement obtenu

Comment résoudre le problème de léchec des cookies et des domaines Ajax dans SpringBoot

Comment résoudre le problème de léchec des cookies et des domaines Ajax dans SpringBoot

mais il est apparu lors de l'empaquetage du projet dans le cloud, puis effectuer un accès ajax Problème, l'acquisition du cookie a échoué !

Il y a clairement set-Cookie dans l'en-tête de réponse, mais le Cookie n'est pas trouvé dans le deuxième en-tête de requête

Service Le client n'a pas réussi à obtenir les cookies et a signalé une erreur. La fonction d'utilisation des cookies pour enregistrer et modifier les mots de passe n'était pas valide. Après avoir recherché la documentation, j'ai découvert que l'erreur provenait du problème de perte de cookies entre domaines de Springboot et d'Ajax. nouveau sur le backend,

# 🎜🎜#Seule ma solution est publiée ici

1 Vous devez la porter dans la requête ajax

xmlhttp.withCredentials = true #🎜. 🎜#

var xmlhttp = new XMLHttpRequest();
xmlhttp.withCredentials = true;
xmlhttp.open("GET", readyUrl, true);
xmlhttp.send();
2. Ajoutez la classe de configuration corsConfig (cette étape peut être une astuce, bienvenue pour le découvrir)
package com.crisp.myblog.config;
 
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
 
@Configuration
public class corsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                //是否发送Cookie
                .allowCredentials(true)
                //放行哪些原始域
                .allowedOriginPatterns("这里填你前端代码所在的域名:端口")
                .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
                .allowedHeaders("*")
                .exposedHeaders("*");
    }
}

3. l'API dans le contrôleur,

clé#🎜🎜 #Pour le contrôle d'accès "Access-Control-Allow-Origin" sources autorisées, informations d'en-tête de requête http, définissez les sources qui autorisent le partage de ressources (inter-domaines) #🎜🎜 #

response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));

Value Pour request.getHeader("Origin"), cela signifie Le protocole et le nom de domaine de la page

où se trouve la ressource actuellement demandée

combinés ensemble signifie permet à la ressource actuellement demandée de traverser le domaine Accéder aux ressources back-end

Une fois les trois configurés, je peux obtenir le cookie à nouveau

2022-12-09 Contenu mis à jour :

J'ai trouvé une méthode plus concise et plus pratique pour ajouter une requête inter-domaines filter

Utilisation de la méthode StringUtils.isEmpty du package de dépendances du pool de données Druid, si une erreur est signalée, écrivez simplement un remplacement vous-même

import com.alibaba.druid.util.StringUtils;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
 
 
@Component
public class crispFilter implements Filter {
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }
 
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        System.out.println("跨域请求过滤器启动");
        if (request.getRequestURL().toString().matches(".+.ico$")) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            String origin = request.getHeader("Origin");
            // 简单请求跨域,如果是跨域请求在响应头里面添加对应的Origin
            if (!StringUtils.isEmpty(origin)) {
                response.addHeader("Access-Control-Allow-Origin", origin);
            }
            // 非简单请求跨域
            response.addHeader("Access-Control-Allow-Headers", "content-type");
            // 允许跨域请求的方法
            response.addHeader("Access-Control-Allow-Methods", "*");
            // 携带cookie的跨域
            response.addHeader("Access-Control-Allow-Credentials", "true");
 
            // 放行方法
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }
 
    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer