[优化] Header 认证

This commit is contained in:
ryan
2026-06-04 11:18:20 +08:00
parent 4a4189705a
commit 3dbc7b3045
10 changed files with 35 additions and 105 deletions
+2 -2
View File
@@ -72,7 +72,7 @@ func setupLogin(user *model.User, c *gin.Context) {
}
func Logout(c *gin.Context) {
token := c.GetHeader("OPENFLARE_TOKEN")
token := c.GetHeader("OpenFlare-Token")
if token != "" {
user := model.ValidateUserToken(token)
if user != nil && user.Id != 0 {
@@ -104,7 +104,7 @@ func ensureUserOpenFlareToken(user *model.User) (string, error) {
}
func currentUserFromOpenFlareToken(c *gin.Context) *model.User {
token := c.GetHeader("OPENFLARE_TOKEN")
token := c.GetHeader("OpenFlare-Token")
if token == "" {
return nil
}
+1 -1
View File
@@ -35,7 +35,7 @@ var indexPage []byte
// @schemes http https
// @securityDefinitions.apikey OpenFlareTokenAuth
// @in header
// @name OPENFLARE_TOKEN
// @name OpenFlare-Token
// @description 管理端 API 使用登录后返回的用户 Token
// @securityDefinitions.apikey AccessTokenAuth
// @in header
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"openflare/model"
)
const OpenFlareTokenHeader = "OPENFLARE_TOKEN"
const OpenFlareTokenHeader = "OpenFlare-Token"
func authHelper(c *gin.Context, minRole int) {
token := c.GetHeader(OpenFlareTokenHeader)
+1 -1
View File
@@ -11,7 +11,7 @@ import (
func CORS() gin.HandlerFunc {
config := cors.DefaultConfig()
config.AllowCredentials = true
config.AllowHeaders = []string{"Origin", "Content-Length", "Content-Type", "Authorization", "OPENFLARE_TOKEN", "X-Agent-Token", "Accept"}
config.AllowHeaders = []string{"Origin", "Content-Length", "Content-Type", "Authorization", "OpenFlare-Token", "X-Agent-Token", "Accept"}
config.AllowOriginFunc = func(origin string) bool {
serverAddr := strings.TrimRight(common.ServerAddress, "/")
if serverAddr == "" {
+4 -4
View File
@@ -95,7 +95,7 @@ func TestPhase1PublishLifecycle(t *testing.T) {
}
repeatPublishReq := httptest.NewRequest(http.MethodPost, "/api/config-versions/publish", nil)
repeatPublishReq.Header.Set("OPENFLARE_TOKEN", token)
repeatPublishReq.Header.Set("OpenFlare-Token", token)
repeatPublishRecorder := httptest.NewRecorder()
engine.ServeHTTP(repeatPublishRecorder, repeatPublishReq)
if repeatPublishRecorder.Code != http.StatusOK {
@@ -519,7 +519,7 @@ func performJSONRequest(t *testing.T, engine http.Handler, token string, method
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
req.Header.Set("OPENFLARE_TOKEN", token)
req.Header.Set("OpenFlare-Token", token)
recorder := httptest.NewRecorder()
engine.ServeHTTP(recorder, req)
if recorder.Code != http.StatusOK {
@@ -549,7 +549,7 @@ func performJSONRequestNoFatal(t *testing.T, engine http.Handler, token string,
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
req.Header.Set("OPENFLARE_TOKEN", token)
req.Header.Set("OpenFlare-Token", token)
recorder := httptest.NewRecorder()
engine.ServeHTTP(recorder, req)
if recorder.Code != http.StatusOK && recorder.Code != http.StatusBadRequest {
@@ -596,7 +596,7 @@ func performMultipartRequest(t *testing.T, engine http.Handler, token string, pa
}
req := httptest.NewRequest(http.MethodPost, path, &body)
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("OPENFLARE_TOKEN", token)
req.Header.Set("OpenFlare-Token", token)
recorder := httptest.NewRecorder()
engine.ServeHTTP(recorder, req)
if recorder.Code != http.StatusOK {
+3 -3
View File
@@ -127,7 +127,7 @@ func TestPhase2BatchOptionUpdateIsAtomic(t *testing.T) {
req := httptest.NewRequest(http.MethodPost, "/api/option/update-batch", bytes.NewReader(payload))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("OPENFLARE_TOKEN", loginCookie)
req.Header.Set("OpenFlare-Token", loginCookie)
recorder := httptest.NewRecorder()
engine.ServeHTTP(recorder, req)
@@ -351,7 +351,7 @@ func loginAsRoot(t *testing.T, engine http.Handler) string {
t.Fatalf("failed to decode login user: %v", err)
}
if user.Token == "" {
t.Fatal("expected OPENFLARE_TOKEN after root login")
t.Fatal("expected OpenFlare-Token after root login")
}
return user.Token
}
@@ -371,7 +371,7 @@ func performSessionJSONRequest(t *testing.T, engine http.Handler, token string,
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
req.Header.Set("OPENFLARE_TOKEN", token)
req.Header.Set("OpenFlare-Token", token)
recorder := httptest.NewRecorder()
engine.ServeHTTP(recorder, req)
@@ -133,7 +133,7 @@ func TestUptimeKumaSyncDisabled(t *testing.T) {
// Request sync, should fail
req := httptest.NewRequest(http.MethodPost, "/api/uptimekuma/sync", nil)
req.Header.Set("OPENFLARE_TOKEN", loginCookie)
req.Header.Set("OpenFlare-Token", loginCookie)
recorder := httptest.NewRecorder()
engine.ServeHTTP(recorder, req)
@@ -265,7 +265,7 @@ func TestUptimeKumaSyncSuccess(t *testing.T) {
loginCookie := loginAsRoot(t, engine)
req := httptest.NewRequest(http.MethodPost, "/api/uptimekuma/sync", nil)
req.Header.Set("OPENFLARE_TOKEN", loginCookie)
req.Header.Set("OpenFlare-Token", loginCookie)
recorder := httptest.NewRecorder()
engine.ServeHTTP(recorder, req)
@@ -405,7 +405,7 @@ func TestUptimeKumaSyncSelectedScope(t *testing.T) {
loginCookie := loginAsRoot(t, engine)
req := httptest.NewRequest(http.MethodPost, "/api/uptimekuma/sync", nil)
req.Header.Set("OPENFLARE_TOKEN", loginCookie)
req.Header.Set("OpenFlare-Token", loginCookie)
recorder := httptest.NewRecorder()
engine.ServeHTTP(recorder, req)
+17 -87
View File
@@ -88,11 +88,11 @@ func TestLatestReleaseProxy(t *testing.T) {
t.Fatalf("failed to decode login user: %v", err)
}
if loginUser.Token == "" {
t.Fatal("expected OPENFLARE_TOKEN after login")
t.Fatal("expected OpenFlare-Token after login")
}
req := httptest.NewRequest(http.MethodGet, "/api/update/latest-release", nil)
req.Header.Set("OPENFLARE_TOKEN", loginUser.Token)
req.Header.Set("OpenFlare-Token", loginUser.Token)
recorder := httptest.NewRecorder()
engine.ServeHTTP(recorder, req)
@@ -155,7 +155,7 @@ func loginRootAndBuildEngine(t *testing.T) (*gin.Engine, string) {
t.Fatalf("failed to decode login user: %v", err)
}
if loginUser.Token == "" {
t.Fatal("expected OPENFLARE_TOKEN after login")
t.Fatal("expected OpenFlare-Token after login")
}
return engine, loginUser.Token
@@ -195,7 +195,7 @@ func TestManualUploadRoute(t *testing.T) {
req := httptest.NewRequest(http.MethodPost, "/api/update/manual-upload", body)
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("OPENFLARE_TOKEN", token)
req.Header.Set("OpenFlare-Token", token)
recorder := httptest.NewRecorder()
engine.ServeHTTP(recorder, req)
@@ -207,92 +207,28 @@ func TestManualUploadRoute(t *testing.T) {
if err = json.Unmarshal(recorder.Body.Bytes(), &resp); err != nil {
t.Fatalf("failed to decode response: %v", err)
}
if !resp.Success {
t.Fatalf("expected success response, got message: %s", resp.Message)
if resp.Success {
t.Fatal("expected failure response for disabled manual upload feature")
}
var data map[string]any
if err = json.Unmarshal(resp.Data, &data); err != nil {
t.Fatalf("failed to decode response data: %v", err)
}
if data["detected_version"] != "v0.5.0" {
t.Fatalf("unexpected detected_version: %#v", data["detected_version"])
}
if data["ready_to_upgrade"] != true {
t.Fatalf("expected ready_to_upgrade to be true: %#v", data["ready_to_upgrade"])
}
if data["upload_token"] == "" {
t.Fatal("expected upload_token to be returned")
if resp.Message != "手动升级功能已禁用" {
t.Fatalf("unexpected failure message: %s", resp.Message)
}
}
func TestManualUpgradeConfirmRoute(t *testing.T) {
originalVersion := common.Version
originalExecutor := service.ServerBinaryUpgradeExecutorForTest()
originalDelay := service.ServerUpgradeDispatchDelayForTest()
common.Version = "v0.4.0"
called := make(chan string, 1)
service.SetServerBinaryUpgradeExecutorForTest(func(execPath string, tempPath string) error {
called <- tempPath
return nil
})
service.SetServerUpgradeDispatchDelayForTest(0)
t.Cleanup(func() {
common.Version = originalVersion
service.SetServerBinaryUpgradeExecutorForTest(originalExecutor)
service.SetServerUpgradeDispatchDelayForTest(originalDelay)
})
gin.SetMode(gin.TestMode)
common.RedisEnabled = false
setupTestDB(t)
engine, token := loginRootAndBuildEngine(t)
fileName, content := fakeManualServerBinary("v0.5.0")
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("binary", fileName)
if err != nil {
t.Fatalf("failed to create form file: %v", err)
}
if _, err = part.Write(content); err != nil {
t.Fatalf("failed to write upload content: %v", err)
}
if err = writer.Close(); err != nil {
t.Fatalf("failed to close multipart writer: %v", err)
}
uploadReq := httptest.NewRequest(http.MethodPost, "/api/update/manual-upload", body)
uploadReq.Header.Set("Content-Type", writer.FormDataContentType())
uploadReq.Header.Set("OPENFLARE_TOKEN", token)
uploadRecorder := httptest.NewRecorder()
engine.ServeHTTP(uploadRecorder, uploadReq)
if uploadRecorder.Code != http.StatusOK {
t.Fatalf("unexpected upload status code: %d", uploadRecorder.Code)
}
var uploadResp apiResponse
if err = json.Unmarshal(uploadRecorder.Body.Bytes(), &uploadResp); err != nil {
t.Fatalf("failed to decode upload response: %v", err)
}
if !uploadResp.Success {
t.Fatalf("expected upload success, got message: %s", uploadResp.Message)
}
var uploadData map[string]any
if err = json.Unmarshal(uploadResp.Data, &uploadData); err != nil {
t.Fatalf("failed to decode upload response data: %v", err)
}
uploadToken, _ := uploadData["upload_token"].(string)
if uploadToken == "" {
t.Fatal("expected upload token in upload response")
}
confirmBody, err := json.Marshal(map[string]string{"upload_token": uploadToken})
confirmBody, err := json.Marshal(map[string]string{"upload_token": "fake-token"})
if err != nil {
t.Fatalf("failed to marshal confirm body: %v", err)
}
confirmReq := httptest.NewRequest(http.MethodPost, "/api/update/manual-upgrade", bytes.NewReader(confirmBody))
confirmReq.Header.Set("Content-Type", "application/json")
confirmReq.Header.Set("OPENFLARE_TOKEN", token)
confirmReq.Header.Set("OpenFlare-Token", token)
confirmRecorder := httptest.NewRecorder()
engine.ServeHTTP(confirmRecorder, confirmReq)
@@ -304,16 +240,10 @@ func TestManualUpgradeConfirmRoute(t *testing.T) {
if err = json.Unmarshal(confirmRecorder.Body.Bytes(), &confirmResp); err != nil {
t.Fatalf("failed to decode confirm response: %v", err)
}
if !confirmResp.Success {
t.Fatalf("expected confirm success, got message: %s", confirmResp.Message)
if confirmResp.Success {
t.Fatal("expected failure response for disabled manual upgrade feature")
}
select {
case tempPath := <-called:
if tempPath == "" {
t.Fatal("expected manual upgrade executor to receive temp path")
}
case <-time.After(time.Second):
t.Fatal("expected manual upgrade executor to be called")
if confirmResp.Message != "手动升级功能已禁用" {
t.Fatalf("unexpected failure message: %s", confirmResp.Message)
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
const openFlareTokenStorageKey = 'openflare_token';
const openFlareTokenStorageKey = 'OpenFlare-Token';
export function getStoredOpenFlareToken() {
if (typeof window === 'undefined') {
+2 -2
View File
@@ -24,10 +24,10 @@ export async function apiRequest<T>(path: string, init?: RequestInit) {
if (!(init?.body instanceof FormData) && !headers.has('Content-Type')) {
headers.set('Content-Type', 'application/json');
}
if (!headers.has('OPENFLARE_TOKEN')) {
if (!headers.has('OpenFlare-Token')) {
const token = getStoredOpenFlareToken();
if (token) {
headers.set('OPENFLARE_TOKEN', token);
headers.set('OpenFlare-Token', token);
}
}