Maison  >  Article  >  développement back-end  >  Le navigateur n'enregistre pas les cookies envoyés par le backend Golang

Le navigateur n'enregistre pas les cookies envoyés par le backend Golang

PHPz
PHPzavant
2024-02-14 23:30:091040parcourir

Le navigateur nenregistre pas les cookies envoyés par le backend Golang

l'éditeur php Strawberry est là pour vous présenter un problème concernant l'enregistrement des cookies par les navigateurs. Parfois, lorsque nous utilisons le backend Golang pour envoyer des cookies, nous constatons que le navigateur ne les enregistre pas. Cela peut être dû à un certain nombre de raisons, telles que les paramètres de confidentialité du navigateur ou certains problèmes dans le code. Dans cet article, nous explorerons ce problème en détail et proposerons quelques solutions pour garantir que les navigateurs enregistrent correctement les cookies envoyés par le backend Golang. commençons!

Contenu de la question

Je sais que cette question a été posée plusieurs fois, mais j'ai essayé la plupart des réponses et je n'arrive toujours pas à la faire fonctionner.

J'ai une API Golang avec un package net/http et une interface js. J'ai une fonction

func setcookie(w *http.responsewriter, email string) string {
    val := uuid.newstring()
    http.setcookie(*w, &http.cookie{
        name:     "gocookie",
        value:    val,
        path:     "/",
    })
    return val
}

Cette fonction est appelée lorsque l'utilisateur se connecte et je souhaite qu'elle soit envoyée à tous les autres points de terminaison. Cela correspond aux attentes du facteur. Cependant, en ce qui concerne le navigateur, je n'arrive pas à lui faire mémoriser le cookie ou même à l'envoyer à d'autres points de terminaison.

exemple js utilisant un point de terminaison

async function getDataWithQuery(query, schema){
    
    let raw = `{"query":"${query}", "schema":"${schema}"}`;
    let requestOptions = {
        method: 'POST',
        body: raw,
        redirect: 'follow',
    };
    try{
        let dataJson = await fetch("http://localhost:8080/query/", requestOptions)
        data = await dataJson.json();
    }catch(error){
        console.log(error);
    }

    return data;
}

J'ai essayé de configurer samesite 属性,或在 js 中使用 credential: "include" dans Golang et d'autres réponses, mais sans succès.

Solution

Grâce à la discussion dans les commentaires, j'ai trouvé quelques astuces sur ce problème.

Enregistrez les cookies (l'API et le frontend sont sur le même hôte)

J'utilise document.cookie来保存cookie。我手动设置选项,因为在 api fetch 的响应上调用 res.cookie 仅返回值。一个例子是 document.cookie = `gocookie=${res.cookie};路径=/;域=localhost;.

Envoyer des cookies

Cette question a reçu une réponse dans une question précédente et encore dans les commentaires. Le problème est que j'ai utilisé credential:'include' 而不是正确的 credentials:'include' (pluriel).

cors et cookies

Si l'API et le frontend ne sont pas sur le même hôte, vous devrez modifier à la fois l'API et le frontend.

Front-end

Le cookie doit avoir le domaine de l'API, puisque c'est l'API qui en a besoin, pas le frontend. Ainsi, pour des raisons de sécurité, vous ne pouvez pas définir de cookies pour un domaine (api) d'un autre domaine (frontend). La solution consiste à rediriger l'utilisateur vers un point de terminaison d'API qui renvoie un en-tête set-cookie dans les en-têtes de réponse. Cette solution demande au navigateur d'enregistrer le cookie avec un domaine supplémentaire (le domaine de l'API, puisque l'API l'a envoyé).

De plus, vous devez toujours inclure credentials:'include' sur le frontend.

api

Vous devez définir des en-têtes. Ce que j'ai défini, c'est

    w.header().set("access-control-allow-origin", frontendorigin)
    w.header().set("access-control-allow-credentials", "true")
    w.header().set("access-control-allow-headers", "content-type, withcredentials")
    w.header().set("access-control-allow-methods", method) // use the endpoint's method: post, get, options

Vous devez exposer le point de terminaison où le frontend redirigera l'utilisateur et définir un cookie dans la réponse. Vous pouvez l'omettre et au lieu de définir manuellement le domaine de l'API, le navigateur le remplira automatiquement avec le domaine.

Pour gérer les cors et que js envoie le cookie avec succès, vous devez définir l'attribut samesite=nonesecure dans le cookie et servir l'API via https (pour plus de simplicité, j'ai utilisé ngrok).

Comme ça

func SetCookie(w *http.ResponseWriter, email string) string {
    val := uuid.NewString()
    http.SetCookie(*w, &http.Cookie{
        Name:     "goCookie",
        Value:    val,
        SameSite: http.SameSiteNoneMode,
        Secure:   true,
        Path:     "/",
    })
   // rest of the code
}

Je vous recommande également de lire la différence entre utiliser localstoragedocument.cookie , c'est l'un des problèmes que j'ai rencontré.

J'espère que cela vous aidera.

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