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> </> }
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:
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.
Mulakan pelayan:
go run main.go
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
.Navigasi ke
http://127.0.0.1:5173/
untuk membuka halaman.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 halaman127.0.0.1
(没有端口)。所以http://127.0.0.1:5173/
juga boleh membaca cookies.Tingkap inkognito tidak dapat melihat kuki daripada tetingkap lain. Sila semak pelayar anda untuk memastikan kuki itu ada.