From b8e50c10f6ca419d562e8671674856d98c5d25a5 Mon Sep 17 00:00:00 2001
From: HouYunFei <1844025705@qq.com>
Date: Mon, 25 May 2026 16:03:54 +0800
Subject: [PATCH] =?UTF-8?q?feat(auth):=20=E6=B7=BB=E5=8A=A0=E7=94=A8?=
=?UTF-8?q?=E6=88=B7=E6=B3=A8=E5=86=8C=E5=BC=80=E5=85=B3=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 在系统设置中新增 allowRegister 配置项控制用户注册
- 实现注册接口的开关检查机制
- 登录页面根据注册开关动态显示或隐藏注册选项
- 首次 Linux.do 登录创建用户时也受注册开关限制
- 更新系统配置文档说明新的认证配置项
---
docs/system-settings.md | 14 ++++++++++++++
model/setting.go | 3 ++-
service/auth.go | 11 +++++++++++
service/settings.go | 4 ++++
web/src/app/(admin)/admin/settings/page.tsx | 8 +++++++-
web/src/app/(user)/login/page.tsx | 16 +++++++++++-----
web/src/services/api/admin.ts | 1 +
7 files changed, 50 insertions(+), 7 deletions(-)
diff --git a/docs/system-settings.md b/docs/system-settings.md
index aa992f7..74a267b 100644
--- a/docs/system-settings.md
+++ b/docs/system-settings.md
@@ -22,6 +22,12 @@
"defaultTextModel": "gpt-5.5",
"systemPrompt": "",
"allowCustomChannel": true
+ },
+ "auth": {
+ "allowRegister": true,
+ "linuxDo": {
+ "enabled": false
+ }
}
}
```
@@ -29,6 +35,7 @@
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `modelChannel` | object | 模型渠道公开配置组 |
+| `auth` | object | 认证相关公开配置 |
`modelChannel` 字段:
@@ -56,6 +63,13 @@
| 云端渠道 | 使用后端 `/api/v1/*` 代理接口,请求会按模型名匹配 `private.value.channels` 中的可用渠道 |
| 本地直连 | 默认可选;`allowCustomChannel` 关闭后不可选,用户在浏览器本地配置 `baseUrl`、`apiKey` 和模型列表后直接请求模型接口 |
+`auth` 字段:
+
+| 字段 | 类型 | 说明 |
+| --- | --- | --- |
+| `allowRegister` | boolean | 是否允许用户注册,默认允许;关闭后注册入口隐藏,注册接口拒绝新用户创建 |
+| `linuxDo.enabled` | boolean | 是否开启 Linux.do 登录 |
+
## private.value
```json
diff --git a/model/setting.go b/model/setting.go
index 60dc301..d6d4a1f 100644
--- a/model/setting.go
+++ b/model/setting.go
@@ -46,7 +46,8 @@ type PublicSetting struct {
}
type PublicAuthSetting struct {
- LinuxDo PublicLinuxDoAuthSetting `json:"linuxDo"`
+ AllowRegister *bool `json:"allowRegister"`
+ LinuxDo PublicLinuxDoAuthSetting `json:"linuxDo"`
}
type PublicLinuxDoAuthSetting struct {
diff --git a/service/auth.go b/service/auth.go
index 9a26619..ad32df7 100644
--- a/service/auth.go
+++ b/service/auth.go
@@ -59,6 +59,14 @@ func EnsureDefaultAdmin() error {
}
func Register(username string, password string) (model.AuthSession, error) {
+ settings, err := repository.GetSettings()
+ if err != nil {
+ return model.AuthSession{}, err
+ }
+ normalizedSettings := normalizeSettings(settings)
+ if normalizedSettings.Public.Auth.AllowRegister != nil && !*normalizedSettings.Public.Auth.AllowRegister {
+ return model.AuthSession{}, safeMessageError{message: "当前未开放注册"}
+ }
username = strings.TrimSpace(username)
if strings.ContainsAny(username, " \t\r\n") {
return model.AuthSession{}, safeMessageError{message: "用户名不能包含空格"}
@@ -163,6 +171,9 @@ func LoginWithLinuxDo(r *http.Request, code string, state string) (model.AuthSes
return model.AuthSession{}, redirect, err
}
if !ok {
+ if settings.Public.Auth.AllowRegister != nil && !*settings.Public.Auth.AllowRegister {
+ return model.AuthSession{}, redirect, safeMessageError{message: "当前未开放注册"}
+ }
user = model.User{
ID: newID("user"),
Username: linuxDoUsername(profile.Username, linuxDoID),
diff --git a/service/settings.go b/service/settings.go
index 0f30d6a..bbf088f 100644
--- a/service/settings.go
+++ b/service/settings.go
@@ -78,6 +78,10 @@ func normalizePublicSetting(setting model.PublicSetting) model.PublicSetting {
enabled := true
setting.ModelChannel.AllowCustomChannel = &enabled
}
+ if setting.Auth.AllowRegister == nil {
+ enabled := true
+ setting.Auth.AllowRegister = &enabled
+ }
return setting
}
diff --git a/web/src/app/(admin)/admin/settings/page.tsx b/web/src/app/(admin)/admin/settings/page.tsx
index 867d4dc..2493467 100644
--- a/web/src/app/(admin)/admin/settings/page.tsx
+++ b/web/src/app/(admin)/admin/settings/page.tsx
@@ -36,7 +36,7 @@ const emptySettings: AdminSettings = {
systemPrompt: "",
allowCustomChannel: true,
},
- auth: { linuxDo: { enabled: false } },
+ auth: { allowRegister: true, linuxDo: { enabled: false } },
},
private: { channels: [], promptSync: { enabled: true, cron: "*/5 * * * *" }, auth: { linuxDo: { clientId: "", clientSecret: "" } } },
};
@@ -371,6 +371,11 @@ export default function AdminSettingsPage() {