mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-29 05:56:38 +08:00
[优化] Header 认证
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 == "" {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
const openFlareTokenStorageKey = 'openflare_token';
|
||||
const openFlareTokenStorageKey = 'OpenFlare-Token';
|
||||
|
||||
export function getStoredOpenFlareToken() {
|
||||
if (typeof window === 'undefined') {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user