React 이후 백엔드에 들어가기 시작했고 데이터를 저장하기 위해 백엔드 서버에 github OAUTH와 세션을 추가했습니다. 모두 백엔드에서 잘 작동하며 세션 등을 통해 다른 핸들러의 데이터에 액세스할 수 있습니다. 하지만 일단 React를 사용하여 백엔드에서 세션을 가져오려고 하면 절대 할 수 없습니다.
으아악많은 것을 시도했는데, 먼저 고릴라가 아닌 다른 세션 라이브러리를 사용했는데 scs라고 해서 내 라이브러리일지도 모른다고 생각했는데 그렇지 않았습니다. 코드를 변경할 때 다른 오류가 발생하지만 백엔드는 매번 잘 작동합니다. 백엔드의 API 요청에서 때때로 빈 문자열 데이터, 네트워크 오류 또는 사용자를 찾을 수 없는 등의 오류가 발생하지만 코드를 반복할 때마다 백엔드를 확인할 때마다 정상적으로 작동합니다. 요청 받기는 다음과 같습니다.
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)) }
IIUC, 웹페이지는
http://localhost:5173
加载,并向http://127.0.0.1:3080/user
에서 GET 요청을 합니다. 따라서 이것은 교차 출처 요청입니다.기본적으로 브라우저는 원본 간 XMLHttpRequest 또는 Fetch 호출에서 자격 증명(예: Cookie 및 HTTP 인증)을 보내지 않습니다. XMLHttpRequest 개체 또는 요청 생성자를 호출할 때 특정 플래그를 설정해야 합니다.
크로스 도메인 URL로 쿠키를 보내도록 브라우저에 지시하려면 가져오기 호출을 다음과 같이 변경해야 합니다.
으아악자세한 내용은 자격 증명이 포함된 요청을 참조하세요.
백엔드 코드에 CORS 헤더가 올바르게 구성된 것 같으므로 위의 변경 사항을 적용하면 제대로 작동할 것입니다. 그렇지 않은 경우 브라우저의 DevTools 콘솔을 확인하세요. 여기에는 무엇이 잘못되었는지 알려주는 오류/경고 메시지가 포함되어야 합니다.
이 문제를 디버깅하는 데 도움이 되는 최소한의 데모입니다.
서버 시작:
go run main.go
쿠키를 설정하려면 브라우저에서
http://127.0.0.1:3080/callback
로 이동하세요.Set-Cookie: session=abc;路径=/;过期=2023 年 4 月 18 日星期二 18:34:49 GMT;最大年龄=86372;仅 Http; SameSite=Lax
.페이지를 열려면
http://127.0.0.1:5173/
로 이동하세요.이 페이지에서 Get 버튼을 클릭하세요. DevTools 콘솔에 세션 쿠키 "abc"를 출력해야 합니다.
Notes:
쿠키가 도메인
으아악127.0.0.1
(포트 없음)에 저장되고 있다는 것을 방금 깨달았습니다. 따라서127.0.0.1
(没有端口)。所以http://127.0.0.1:5173/
페이지에서도 쿠키를 읽을 수 있습니다.시크릿 창에서는 다른 창의 쿠키를 볼 수 없습니다. 쿠키가 존재하는지 브라우저를 확인하십시오.