Tidak dapat mendapatkan data kuki daripada pelayan Go menggunakan React
P粉360266095
P粉360266095 2024-04-06 13:09:26
0
1
503

Selepas React saya mula masuk ke bahagian belakang dan menambah github OAUTH dan sesi pada pelayan bahagian belakang untuk menyimpan data. Mereka semua berfungsi dengan baik di bahagian belakang dan saya boleh mengakses data daripada pengendali lain melalui sesi dll. Tetapi sebaik sahaja saya cuba mendapatkan sesi dari bahagian belakang menggunakan React, saya tidak boleh melakukannya.

func (h Handler) HandleAuth(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Access-Control-Allow-Origin", "http://127.0.0.1:5173")
    w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    w.Header().Set("Access-Control-Allow-Methods", "GET")
    url := Oauth2Config.AuthCodeURL("state", oauth2.AccessTypeOffline)
    http.Redirect(w, r, url, http.StatusFound)
}

func (h Handler) HandleAuthCallback(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Access-Control-Allow-Origin", "http://127.0.0.1:5173")
    w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    w.Header().Set("Access-Control-Allow-Methods", "GET")
    code := r.URL.Query().Get("code")
    token, err := Oauth2Config.Exchange(r.Context(), code)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    // Use the access token to get the user's GitHub data
    client := github2.NewTokenClient(r.Context(), token.AccessToken)
    user, _, err := client.Users.Get(r.Context(), "")
    if err != nil {
        fmt.Printf("Error: %v\n", err.Error())
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    session, err := store.Get(r, "session")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    session.Values["user"] = user.GetLogin()
    session.Values["access_token"] = token.AccessToken
    err = session.Save(r, w)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    fmt.Fprintf(w, "this is authcallback: %s", user.GetLogin())

}

func (h Handler) HandleCurrentUser(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Access-Control-Allow-Origin", "http://localhost:5173")
    w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    w.Header().Set("Access-Control-Allow-Methods", "GET")
    session, err := store.Get(r, "session")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    user, ok := session.Values["user"].(string)
    if !ok {
        http.Error(w, "Invalid user in session", http.StatusInternalServerError)
        return
    }
    // Set the content type header to JSON
    w.Header().Set("Content-Type", "text/plain")

    // Write the JSON data to the response
    w.Write([]byte(user))
}

Saya mencuba banyak perkara, mula-mula saya menggunakan perpustakaan sesi yang berbeza daripada gorila, ia dipanggil scs, saya fikir ia mungkin perpustakaan saya, tetapi tidak begitu. Apabila menukar kod saya mendapat ralat yang berbeza tetapi bahagian belakang berfungsi dengan baik setiap kali. Pada permintaan API dari bahagian belakang kadangkala saya mendapat data rentetan kosong, atau ralat rangkaian atau pengguna tidak ditemui dsb. tetapi setiap kali saya menyemak bahagian belakang dalam setiap lelaran kod ia berfungsi dengan baik. Berikut adalah permintaan dapatkan:

function App() {
    const [user, setUser] = useState(null);

    useEffect(() => {
        fetch('http://127.0.0.1:3080/user', {
            method: 'GET',
        })
            .then(response => response.text())
            .then(data => {
                setUser(data);
                console.log(data);
            })
            .catch(error => console.error(error));
    }, []);
[]);
    return <>
    <p>Logged in as: {user}</p>
            <button onClick={() => window.location.href = 'http://127.0.0.1:3080/oauth'}>Login</button>

    </>
}

P粉360266095
P粉360266095

membalas semua(1)
P粉237029457

IIUC, halaman web membuat permintaan GET daripada http://localhost:5173 加载,并向 http://127.0.0.1:3080/user. Jadi ini adalah permintaan silang asal.

Secara lalai, penyemak imbas tidak menghantar bukti kelayakan (seperti Cookie dan Pengesahan HTTP) dalam XMLHttpRequest atau Ambil panggilan silang asal. Bendera tertentu mesti ditetapkan apabila memanggil objek XMLHttpRequest atau pembina Request.

Untuk memberitahu penyemak imbas menghantar kuki ke URL merentas domain, panggilan ambil hendaklah ditukar seperti ini:

fetch('http://127.0.0.1:3080/user', {
    method: 'GET',
+   mode: 'cors',
+   credentials: 'include',
  })

Untuk butiran, lihat Permintaan dengan Tauliah.

Nampaknya kod bahagian belakang mempunyai pengepala CORS yang dikonfigurasikan dengan betul, jadi perubahan di atas sepatutnya menjadikannya berfungsi. Jika tidak, semak konsol DevTools penyemak imbas anda. Ia sepatutnya mengandungi beberapa mesej ralat/amaran yang memberitahu anda apa yang salah.


Ini ialah demo minimum untuk membantu nyahpepijat isu ini.

  1. Mulakan pelayan: go run main.go

  2. Navigasi ke http://127.0.0.1:3080/callback dalam penyemak imbas anda untuk menetapkan kuki.

    Set-Cookie: session=abc;路径=/;过期=2023 年 4 月 18 日星期二 18:34:49 GMT;最大年龄=86372;仅 Http; SameSite=Lax.

  3. Navigasi ke http://127.0.0.1:5173/ untuk membuka halaman.

  4. Klik butang Dapatkan di halaman ini. Ia harus mengeluarkan kuki sesi "abc" ke konsol DevTools.

Nota:

Saya baru menyedari bahawa kuki sedang disimpan ke domain 127.0.0.1 (tiada port). Jadi halaman 127.0.0.1(没有端口)。所以http://127.0.0.1:5173/ juga boleh membaca cookies.

package main

import (
    "fmt"
    "net/http"
    "time"
)

func main() {
    go func() {
        _ = http.ListenAndServe(":5173", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            w.Write([]byte(page))
        }))
    }()

    http.HandleFunc("/callback", func(w http.ResponseWriter, r *http.Request) {
        http.SetCookie(w, &http.Cookie{
            Name:     "session",
            Value:    "abc",
            Path:     "/",
            Expires:  time.Now().Add(24 * time.Hour),
            MaxAge:   86372,
            HttpOnly: true,
            SameSite: http.SameSiteLaxMode,
        })
        w.Write([]byte("done"))
    })

    http.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "http://127.0.0.1:5173")
        w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
        w.Header().Set("Access-Control-Allow-Methods", "GET")
        w.Header().Set("Access-Control-Allow-Credentials", "true")

        cookie, err := r.Cookie("session")
        if err != nil {
            fmt.Fprintln(w, err.Error())
            return
        }
        w.Write([]byte(cookie.Value))
    })

    http.ListenAndServe(":3080", nil)
}

const page = `
  
    
    sssccc
  
`

Tingkap inkognito tidak dapat melihat kuki daripada tetingkap lain. Sila semak pelayar anda untuk memastikan kuki itu ada.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan