OAuth 登录记住发起页:回调后回到登录前所在的前台 origin(开发时 3000/8080 分离不再落错站)

This commit is contained in:
Sakurasan
2026-09-28 00:15:17 +08:00
parent cfd6948987
commit 8e9d98e261
+19 -1
View File
@@ -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 {