From 8e9d98e261fd8b9d63d715a1866fd08d2deb8240 Mon Sep 17 00:00:00 2001 From: Sakurasan <26715255+Sakurasan@users.noreply.github.com> Date: Mon, 28 Sep 2026 00:15:17 +0800 Subject: [PATCH] =?UTF-8?q?OAuth=20=E7=99=BB=E5=BD=95=E8=AE=B0=E4=BD=8F?= =?UTF-8?q?=E5=8F=91=E8=B5=B7=E9=A1=B5=EF=BC=9A=E5=9B=9E=E8=B0=83=E5=90=8E?= =?UTF-8?q?=E5=9B=9E=E5=88=B0=E7=99=BB=E5=BD=95=E5=89=8D=E6=89=80=E5=9C=A8?= =?UTF-8?q?=E7=9A=84=E5=89=8D=E5=8F=B0=20origin=EF=BC=88=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E6=97=B6=203000/8080=20=E5=88=86=E7=A6=BB=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E8=90=BD=E9=94=99=E7=AB=99=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/api/comments.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/backend/internal/api/comments.go b/backend/internal/api/comments.go index 712d7f9..01d1d1d 100644 --- a/backend/internal/api/comments.go +++ b/backend/internal/api/comments.go @@ -10,6 +10,7 @@ import ( "encoding/hex" "errors" "net/http" + "net/url" "strconv" "strings" "time" @@ -24,6 +25,7 @@ import ( const ( readerCookie = "one_reader" oauthStateCook = "one_oauth_state" + oauthBackCook = "one_oauth_back" maxCommentLen = 500 editWindow = 10 * time.Minute ) @@ -72,6 +74,8 @@ func (a *API) authLogout(w http.ResponseWriter, r *http.Request) { // githubLogin 跳转 GitHub 授权页。state 防 CSRF 存短命 cookie; // 授权完成回到 callback 后必须带上同一个值。 +// 同时把发起登录的前台 origin 记下来(one_oauth_back), +// callback 用它跳回去——开发时前端 3000 / 后端 8080 分离才不会落错站。 func (a *API) githubLogin(w http.ResponseWriter, r *http.Request) { if !a.GH.Enabled() { httpx.NotFound(w) @@ -80,6 +84,12 @@ func (a *API) githubLogin(w http.ResponseWriter, r *http.Request) { state := randHex(16) http.SetCookie(w, &http.Cookie{Name: oauthStateCook, Value: state, Path: "/", HttpOnly: true, MaxAge: 600}) + if ref := r.Referer(); ref != "" { + if u, err := url.Parse(ref); err == nil && u.Scheme != "" && u.Host != "" { + http.SetCookie(w, &http.Cookie{Name: oauthBackCook, + Value: u.Scheme + "://" + u.Host, Path: "/", HttpOnly: true, MaxAge: 600}) + } + } http.Redirect(w, r, a.GH.LoginURL(a.Cfg.SiteURL+"/api/auth/callback/github", state), http.StatusFound) } @@ -120,7 +130,15 @@ func (a *API) githubCallback(w http.ResponseWriter, r *http.Request) { token, _ := a.ReaderSessions.Issue(reader.ID) http.SetCookie(w, &http.Cookie{Name: auth.ReaderCookie, Value: token, Path: "/", HttpOnly: true, SameSite: http.SameSiteLaxMode, MaxAge: int((30 * 24 * time.Hour).Seconds())}) - http.Redirect(w, r, "/", http.StatusFound) + // 回到发起登录的前台;没有记录(直接敲 URL 进来的)就回站点根 + back := a.Cfg.SiteURL + if ck, err := r.Cookie(oauthBackCook); err == nil && ck.Value != "" { + if u, err := url.Parse(ck.Value); err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != "" && u.Path == "" { + back = u.Scheme + "://" + u.Host + } + } + http.SetCookie(w, &http.Cookie{Name: oauthBackCook, Value: "", Path: "/", MaxAge: -1}) + http.Redirect(w, r, back, http.StatusFound) } func randHex(n int) string {