🐛 fix(auth): add AUTH_DISABLE_EMAIL_PASSWORD env to enable SSO-only mode (#12009)

This commit is contained in:
YuTengjing 2026-01-31 18:25:22 +08:00 committed by GitHub
parent 8b8159eb01
commit f3210a3f57
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 345 additions and 83 deletions

View file

@ -1,6 +1,3 @@
# add a access code to lock your lobe-chat application, you can set a long password to avoid leaking. If this value contains a comma, it is a password array.
# ACCESS_CODE=lobe66
# Specify your API Key selection method, currently supporting `random` and `turn`. # Specify your API Key selection method, currently supporting `random` and `turn`.
# API_KEY_SELECT_MODE=random # API_KEY_SELECT_MODE=random
@ -295,6 +292,10 @@ OPENAI_API_KEY=sk-xxxxxxxxx
# Leave empty to allow all emails # Leave empty to allow all emails
# AUTH_ALLOWED_EMAILS=example.com,admin@other.com # AUTH_ALLOWED_EMAILS=example.com,admin@other.com
# Disable email/password authentication (SSO-only mode)
# Set to '1' to disable email/password sign-in and registration, only allowing SSO login
# AUTH_DISABLE_EMAIL_PASSWORD=0
# Google OAuth Configuration (for Better-Auth) # Google OAuth Configuration (for Better-Auth)
# Get credentials from: https://console.cloud.google.com/apis/credentials # Get credentials from: https://console.cloud.google.com/apis/credentials
# Authorized redirect URIs: # Authorized redirect URIs:

View file

@ -158,14 +158,12 @@ ENV HOSTNAME="0.0.0.0" \
PORT="3210" PORT="3210"
# General Variables # General Variables
ENV ACCESS_CODE="" \ ENV APP_URL="" \
APP_URL="" \
API_KEY_SELECT_MODE="" \ API_KEY_SELECT_MODE="" \
DEFAULT_AGENT_CONFIG="" \ DEFAULT_AGENT_CONFIG="" \
SYSTEM_AGENT="" \ SYSTEM_AGENT="" \
FEATURE_FLAGS="" \ FEATURE_FLAGS="" \
PROXY_URL="" \ PROXY_URL=""
ENABLE_AUTH_PROTECTION=""
# Database # Database
ENV KEY_VAULTS_SECRET="" \ ENV KEY_VAULTS_SECRET="" \
@ -176,6 +174,10 @@ ENV KEY_VAULTS_SECRET="" \
ENV AUTH_SECRET="" \ ENV AUTH_SECRET="" \
AUTH_SSO_PROVIDERS="" \ AUTH_SSO_PROVIDERS="" \
AUTH_ALLOWED_EMAILS="" \ AUTH_ALLOWED_EMAILS="" \
AUTH_TRUSTED_ORIGINS="" \
AUTH_DISABLE_EMAIL_PASSWORD="" \
AUTH_EMAIL_VERIFICATION="" \
AUTH_ENABLE_MAGIC_LINK="" \
# Google # Google
AUTH_GOOGLE_ID="" \ AUTH_GOOGLE_ID="" \
AUTH_GOOGLE_SECRET="" \ AUTH_GOOGLE_SECRET="" \

View file

@ -581,7 +581,7 @@ LobeHub provides Self-Hosted Version with Vercel, Alibaba Cloud, and [Docker Ima
"If you want to deploy this service yourself on Vercel, Zeabur or Alibaba Cloud, you can follow these steps: "If you want to deploy this service yourself on Vercel, Zeabur or Alibaba Cloud, you can follow these steps:
- Prepare your [OpenAI API Key](https://platform.openai.com/account/api-keys). - Prepare your [OpenAI API Key](https://platform.openai.com/account/api-keys).
- Click the button below to start deployment: Log in directly with your GitHub account, and remember to fill in the `OPENAI_API_KEY`(required) and `ACCESS_CODE` (recommended) on the environment variable section. - Click the button below to start deployment: Log in directly with your GitHub account, and remember to fill in the `OPENAI_API_KEY`(required) on the environment variable section.
- After deployment, you can start using it. - After deployment, you can start using it.
- Bind a custom domain (optional): The DNS of the domain assigned by Vercel is polluted in some areas; binding a custom domain can connect directly. - Bind a custom domain (optional): The DNS of the domain assigned by Vercel is polluted in some areas; binding a custom domain can connect directly.
@ -647,7 +647,6 @@ This project provides some additional configuration items set with environment v
| -------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | | -------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `OPENAI_API_KEY` | Yes | This is the API key you apply on the OpenAI account page | `sk-xxxxxx...xxxxxx` | | `OPENAI_API_KEY` | Yes | This is the API key you apply on the OpenAI account page | `sk-xxxxxx...xxxxxx` |
| `OPENAI_PROXY_URL` | No | If you manually configure the OpenAI interface proxy, you can use this configuration item to override the default OpenAI API request base URL | `https://api.chatanywhere.cn` or `https://aihubmix.com/v1` <br/>The default value is<br/>`https://api.openai.com/v1` | | `OPENAI_PROXY_URL` | No | If you manually configure the OpenAI interface proxy, you can use this configuration item to override the default OpenAI API request base URL | `https://api.chatanywhere.cn` or `https://aihubmix.com/v1` <br/>The default value is<br/>`https://api.openai.com/v1` |
| `ACCESS_CODE` | No | Add a password to access this service; you can set a long password to avoid leaking. If this value contains a comma, it is a password array. | `awCTe)re_r74` or `rtrt_ewee3@09!` or `code1,code2,code3` |
| `OPENAI_MODEL_LIST` | No | Used to control the model list. Use `+` to add a model, `-` to hide a model, and `model_name=display_name` to customize the display name of a model, separated by commas. | `qwen-7b-chat,+glm-6b,-gpt-3.5-turbo` | | `OPENAI_MODEL_LIST` | No | Used to control the model list. Use `+` to add a model, `-` to hide a model, and `model_name=display_name` to customize the display name of a model, separated by commas. | `qwen-7b-chat,+glm-6b,-gpt-3.5-turbo` |
> \[!NOTE] > \[!NOTE]
@ -829,7 +828,7 @@ This project is [LobeHub Community License](./LICENSE) licensed.
[codespaces-link]: https://codespaces.new/lobehub/lobe-chat [codespaces-link]: https://codespaces.new/lobehub/lobe-chat
[codespaces-shield]: https://github.com/codespaces/badge.svg [codespaces-shield]: https://github.com/codespaces/badge.svg
[deploy-button-image]: https://vercel.com/button [deploy-button-image]: https://vercel.com/button
[deploy-link]: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat&env=OPENAI_API_KEY,ACCESS_CODE&envDescription=Find%20your%20OpenAI%20API%20Key%20by%20click%20the%20right%20Learn%20More%20button.%20%7C%20Access%20Code%20can%20protect%20your%20website&envLink=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys&project-name=lobe-chat&repository-name=lobe-chat [deploy-link]: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat&env=OPENAI_API_KEY&envDescription=Find%20your%20OpenAI%20API%20Key%20by%20click%20the%20right%20Learn%20More%20button.&envLink=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys&project-name=lobe-chat&repository-name=lobe-chat
[deploy-on-alibaba-cloud-button-image]: https://service-info-public.oss-cn-hangzhou.aliyuncs.com/computenest-en.svg [deploy-on-alibaba-cloud-button-image]: https://service-info-public.oss-cn-hangzhou.aliyuncs.com/computenest-en.svg
[deploy-on-alibaba-cloud-link]: https://computenest.console.aliyun.com/service/instance/create/default?type=user&ServiceName=LobeHub%E7%A4%BE%E5%8C%BA%E7%89%88 [deploy-on-alibaba-cloud-link]: https://computenest.console.aliyun.com/service/instance/create/default?type=user&ServiceName=LobeHub%E7%A4%BE%E5%8C%BA%E7%89%88
[deploy-on-repocloud-button-image]: https://d16t0pc4846x52.cloudfront.net/deploylobe.svg [deploy-on-repocloud-button-image]: https://d16t0pc4846x52.cloudfront.net/deploylobe.svg

View file

@ -555,7 +555,7 @@ LobeHub 提供了 Vercel 的 自托管版本 和 [Docker 镜像][docker-release-
如果想在 Vercel 、 Zeabur 或 阿里云 上部署该服务,可以按照以下步骤进行操作: 如果想在 Vercel 、 Zeabur 或 阿里云 上部署该服务,可以按照以下步骤进行操作:
- 准备好你的 [OpenAI API Key](https://platform.openai.com/account/api-keys) 。 - 准备好你的 [OpenAI API Key](https://platform.openai.com/account/api-keys) 。
- 点击下方按钮开始部署: 直接使用 GitHub 账号登录即可,记得在环境变量页填入 `OPENAI_API_KEY` (必填) and `ACCESS_CODE`(推荐) - 点击下方按钮开始部署: 直接使用 GitHub 账号登录即可,记得在环境变量页填入 `OPENAI_API_KEY` (必填);
- 部署完毕后,即可开始使用; - 部署完毕后,即可开始使用;
- 绑定自定义域名可选Vercel 分配的域名 DNS 在某些区域被污染了,绑定自定义域名即可直连。目前 Zeabur 提供的域名还未被污染,大多数地区都可以直连。 - 绑定自定义域名可选Vercel 分配的域名 DNS 在某些区域被污染了,绑定自定义域名即可直连。目前 Zeabur 提供的域名还未被污染,大多数地区都可以直连。
@ -621,7 +621,6 @@ docker compose up -d
| ------------------- | ---- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | | ------------------- | ---- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `OPENAI_API_KEY` | 必选 | 这是你在 OpenAI 账户页面申请的 API 密钥 | `sk-xxxxxx...xxxxxx` | | `OPENAI_API_KEY` | 必选 | 这是你在 OpenAI 账户页面申请的 API 密钥 | `sk-xxxxxx...xxxxxx` |
| `OPENAI_PROXY_URL` | 可选 | 如果你手动配置了 OpenAI 接口代理,可以使用此配置项来覆盖默认的 OpenAI API 请求基础 URL | `https://api.chatanywhere.cn``https://aihubmix.com/v1`<br/>默认值:<br/>`https://api.openai.com/v1` | | `OPENAI_PROXY_URL` | 可选 | 如果你手动配置了 OpenAI 接口代理,可以使用此配置项来覆盖默认的 OpenAI API 请求基础 URL | `https://api.chatanywhere.cn``https://aihubmix.com/v1`<br/>默认值:<br/>`https://api.openai.com/v1` |
| `ACCESS_CODE` | 可选 | 添加访问此服务的密码,你可以设置一个长密码以防被爆破,该值用逗号分隔时为密码数组 | `awCTe)re_r74` or `rtrt_ewee3@09!` or `code1,code2,code3` |
| `OPENAI_MODEL_LIST` | 可选 | 用来控制模型列表,使用 `+` 增加一个模型,使用 `-` 来隐藏一个模型,使用 `模型名=展示名` 来自定义模型的展示名,用英文逗号隔开。 | `qwen-7b-chat,+glm-6b,-gpt-3.5-turbo` | | `OPENAI_MODEL_LIST` | 可选 | 用来控制模型列表,使用 `+` 增加一个模型,使用 `-` 来隐藏一个模型,使用 `模型名=展示名` 来自定义模型的展示名,用英文逗号隔开。 | `qwen-7b-chat,+glm-6b,-gpt-3.5-turbo` |
> \[!NOTE] > \[!NOTE]
@ -843,7 +842,7 @@ This project is [LobeHub Community License](./LICENSE) licensed.
[codespaces-link]: https://codespaces.new/lobehub/lobe-chat [codespaces-link]: https://codespaces.new/lobehub/lobe-chat
[codespaces-shield]: https://github.com/codespaces/badge.svg [codespaces-shield]: https://github.com/codespaces/badge.svg
[deploy-button-image]: https://vercel.com/button [deploy-button-image]: https://vercel.com/button
[deploy-link]: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat&env=OPENAI_API_KEY,ACCESS_CODE&envDescription=Find%20your%20OpenAI%20API%20Key%20by%20click%20the%20right%20Learn%20More%20button.%20%7C%20Access%20Code%20can%20protect%20your%20website&envLink=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys&project-name=lobe-chat&repository-name=lobe-chat [deploy-link]: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat&env=OPENAI_API_KEY&envDescription=Find%20your%20OpenAI%20API%20Key%20by%20click%20the%20right%20Learn%20More%20button.&envLink=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys&project-name=lobe-chat&repository-name=lobe-chat
[deploy-on-alibaba-cloud-button-image]: https://service-info-public.oss-cn-hangzhou.aliyuncs.com/computenest-en.svg [deploy-on-alibaba-cloud-button-image]: https://service-info-public.oss-cn-hangzhou.aliyuncs.com/computenest-en.svg
[deploy-on-alibaba-cloud-link]: https://computenest.console.aliyun.com/service/instance/create/default?type=user&ServiceName=LobeHub%E7%A4%BE%E5%8C%BA%E7%89%88 [deploy-on-alibaba-cloud-link]: https://computenest.console.aliyun.com/service/instance/create/default?type=user&ServiceName=LobeHub%E7%A4%BE%E5%8C%BA%E7%89%88
[deploy-on-sealos-button-image]: https://raw.githubusercontent.com/labring-actions/templates/main/Deploy-on-Sealos.svg [deploy-on-sealos-button-image]: https://raw.githubusercontent.com/labring-actions/templates/main/Deploy-on-Sealos.svg

View file

@ -61,6 +61,8 @@ To enable Better Auth in LobeHub, set the following environment variables:
Click on a provider below for detailed configuration guides: Click on a provider below for detailed configuration guides:
<Cards> <Cards>
<Card href={'/docs/self-hosting/advanced/auth/providers/password'} title={'Email/Password'} />
<Card href={'/docs/self-hosting/advanced/auth/providers/github'} title={'GitHub'} /> <Card href={'/docs/self-hosting/advanced/auth/providers/github'} title={'GitHub'} />
<Card href={'/docs/self-hosting/advanced/auth/providers/google'} title={'Google'} /> <Card href={'/docs/self-hosting/advanced/auth/providers/google'} title={'Google'} />
@ -149,6 +151,16 @@ The current authentication system requires email. Please configure a valid email
This applies to all authentication methods, including SSO providers like Casdoor. Always ensure users have valid email addresses configured. This applies to all authentication methods, including SSO providers like Casdoor. Always ensure users have valid email addresses configured.
### How do I enable SSO-only mode (disable email/password login)?
Set `AUTH_DISABLE_EMAIL_PASSWORD=1` to disable email/password authentication. When enabled:
- The email input will be hidden on the login page, only SSO buttons are displayed
- The signup page will redirect to the login page
- Users can only log in via configured SSO providers
Make sure you have at least one SSO provider configured via `AUTH_SSO_PROVIDERS` before enabling this option.
### How do I restrict registration to specific emails or domains? ### How do I restrict registration to specific emails or domains?
Set the `AUTH_ALLOWED_EMAILS` environment variable with a comma-separated list of allowed emails or domains. For example: Set the `AUTH_ALLOWED_EMAILS` environment variable with a comma-separated list of allowed emails or domains. For example:

View file

@ -61,6 +61,8 @@ LobeHub 支持使用 Better Auth 配置外部身份验证服务,供企业 /
点击下方提供商查看详细配置指南: 点击下方提供商查看详细配置指南:
<Cards> <Cards>
<Card href={'/zh/docs/self-hosting/advanced/auth/providers/password'} title={'邮箱密码'} />
<Card href={'/zh/docs/self-hosting/advanced/auth/providers/github'} title={'GitHub'} /> <Card href={'/zh/docs/self-hosting/advanced/auth/providers/github'} title={'GitHub'} />
<Card href={'/zh/docs/self-hosting/advanced/auth/providers/google'} title={'Google'} /> <Card href={'/zh/docs/self-hosting/advanced/auth/providers/google'} title={'Google'} />
@ -150,6 +152,16 @@ Better Auth 支持内置提供商Google、GitHub、Microsoft、Apple、AWS Co
这适用于所有身份验证方式,包括 Casdoor 等 SSO 提供商。请确保用户配置了有效的邮箱地址。 这适用于所有身份验证方式,包括 Casdoor 等 SSO 提供商。请确保用户配置了有效的邮箱地址。
### 如何启用仅 SSO 模式(禁用邮箱密码登录)?
设置 `AUTH_DISABLE_EMAIL_PASSWORD=1` 可禁用邮箱密码登录。启用后:
- 登录页面将隐藏邮箱输入框,仅显示 SSO 登录按钮
- 注册页面将重定向到登录页面
- 用户只能通过配置的 SSO 提供商登录
启用此选项前,请确保已通过 `AUTH_SSO_PROVIDERS` 配置了至少一个 SSO 提供商。
### 如何限制只允许特定邮箱或域名注册? ### 如何限制只允许特定邮箱或域名注册?
设置 `AUTH_ALLOWED_EMAILS` 环境变量,支持完整邮箱地址或域名,以逗号分隔。例如: 设置 `AUTH_ALLOWED_EMAILS` 环境变量,支持完整邮箱地址或域名,以逗号分隔。例如:

View file

@ -0,0 +1,112 @@
---
title: Configuring Email/Password Authentication for LobeHub
description: >-
Learn how to configure email and password authentication for LobeHub,
including enabling/disabling options and SSO-only mode.
tags:
- Email
- Password
- Authentication
- LobeHub
---
# Configuring Email/Password Authentication
LobeHub supports traditional email and password authentication out of the box.
This guide covers the available configuration options.
## Default Behavior
By default, email/password authentication is enabled.
Users can register with their email address and set a password.
## Configuration Options
### Disable Email/Password Authentication (SSO-Only Mode)
If you want to force users to authenticate via SSO providers only,
set the following environment variable:
| Environment Variable | Type | Description |
| ----------------------------- | -------- | ------------------------------------------ |
| `AUTH_DISABLE_EMAIL_PASSWORD` | Optional | Set to `1` to disable email/password login |
When enabled:
- The email input field is hidden on the login page
- Only SSO provider buttons are displayed
- The signup page redirects to the login page
- Users must authenticate through configured SSO providers
<Callout type={'warning'}>
Before enabling SSO-only mode, ensure you have configured at least one SSO
provider via `AUTH_SSO_PROVIDERS`. Otherwise, users will have no way to log
in.
</Callout>
### Enable Email Verification
To require users to verify their email address before signing in:
| Environment Variable | Type | Description |
| ------------------------- | -------- | ---------------------------------------- |
| `AUTH_EMAIL_VERIFICATION` | Optional | Set to `1` to require email verification |
This requires configuring an email service (SMTP).
See [Email Service Configuration](/docs/self-hosting/auth/email) for details.
### Enable Magic Link Login
To allow passwordless login via email magic links:
| Environment Variable | Type | Description |
| ------------------------ | -------- | ------------------------------------- |
| `AUTH_ENABLE_MAGIC_LINK` | Optional | Set to `1` to enable magic link login |
This also requires configuring an email service (SMTP).
## Change Password
Users can change their password in two ways:
1. **Profile Settings**: Go to Settings > Profile to change password
2. **Forgot Password**: On the login page, enter email, proceed to the password step, then click "Forgot Password" below the password input
<Callout type={'info'}>
Both methods require email service (SMTP) to be configured for sending
password reset emails.
</Callout>
## Example Configurations
### SSO-Only (Disable Email/Password)
```bash
AUTH_DISABLE_EMAIL_PASSWORD=1
AUTH_SSO_PROVIDERS=google,github
```
### Email/Password with Verification
```bash
AUTH_EMAIL_VERIFICATION=1
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=noreply@example.com
SMTP_PASS=your-password
```
### Email/Password with Magic Link
```bash
AUTH_ENABLE_MAGIC_LINK=1
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=noreply@example.com
SMTP_PASS=your-password
```
<Callout type={'tip'}>
Go to [Environment Variables](/docs/self-hosting/environment-variables/auth)
for detailed information on all authentication variables.
</Callout>

View file

@ -0,0 +1,103 @@
---
title: 配置 LobeHub 邮箱密码登录
description: 了解如何配置 LobeHub 的邮箱密码登录,包括启用/禁用选项和仅 SSO 模式。
tags:
- 邮箱
- 密码
- 身份验证
- LobeHub
---
# 配置邮箱密码登录
LobeHub 默认支持传统的邮箱密码登录方式。本指南介绍可用的配置选项。
## 默认行为
默认情况下,邮箱密码登录已启用。用户可以使用邮箱地址注册并设置密码。
## 配置选项
### 禁用邮箱密码登录(仅 SSO 模式)
如果你希望强制用户只能通过 SSO 提供商登录,请设置以下环境变量:
| 环境变量 | 类型 | 描述 |
| ----------------------------- | -- | ---------------- |
| `AUTH_DISABLE_EMAIL_PASSWORD` | 可选 | 设置为 `1` 禁用邮箱密码登录 |
启用后:
- 登录页面隐藏邮箱输入框
- 仅显示 SSO 提供商登录按钮
- 注册页面重定向到登录页面
- 用户必须通过配置的 SSO 提供商进行身份验证
<Callout type={'warning'}>
启用仅 SSO 模式前,请确保已通过 `AUTH_SSO_PROVIDERS` 配置了至少一个 SSO
提供商。否则用户将无法登录。
</Callout>
### 启用邮箱验证
要求用户在登录前验证邮箱地址:
| 环境变量 | 类型 | 描述 |
| ------------------------- | -- | -------------- |
| `AUTH_EMAIL_VERIFICATION` | 可选 | 设置为 `1` 启用邮箱验证 |
这需要配置邮件服务SMTP。详情请参阅[邮件服务配置](/zh/docs/self-hosting/auth/email)。
### 启用魔法链接登录
允许通过邮件魔法链接实现无密码登录:
| 环境变量 | 类型 | 描述 |
| ------------------------ | -- | ---------------- |
| `AUTH_ENABLE_MAGIC_LINK` | 可选 | 设置为 `1` 启用魔法链接登录 |
这也需要配置邮件服务SMTP
## 修改密码
用户可以通过以下两种方式修改密码:
1. **个人设置**:前往 设置 > 个人资料 修改密码
2. **忘记密码**:在登录页面输入邮箱后,进入密码输入步骤,点击密码框下方的「忘记密码」
<Callout type={'info'}>
以上两种方式都需要配置邮件服务SMTP以发送密码重置邮件。
</Callout>
## 配置示例
### 仅 SSO禁用邮箱密码
```bash
AUTH_DISABLE_EMAIL_PASSWORD=1
AUTH_SSO_PROVIDERS=google,github
```
### 邮箱密码 + 邮箱验证
```bash
AUTH_EMAIL_VERIFICATION=1
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=noreply@example.com
SMTP_PASS=your-password
```
### 邮箱密码 + 魔法链接
```bash
AUTH_ENABLE_MAGIC_LINK=1
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=noreply@example.com
SMTP_PASS=your-password
```
<Callout type={'tip'}>
前往[环境变量](/zh/docs/self-hosting/environment-variables/auth)查看所有身份验证相关变量的详细信息。
</Callout>

View file

@ -46,6 +46,13 @@ LobeHub provides a complete authentication service capability when deployed. The
- Default: `-` - Default: `-`
- Example: `example.com,admin@other.com` - Example: `example.com,admin@other.com`
#### `AUTH_DISABLE_EMAIL_PASSWORD`
- Type: Optional
- Description: Set to `1` to disable email/password authentication, forcing users to use SSO login only. When enabled, the email input will be hidden on the login page and the signup page will redirect to login.
- Default: `0`
- Example: `1`
#### `JWKS_KEY` #### `JWKS_KEY`
- Type: Required - Type: Required

View file

@ -44,6 +44,13 @@ LobeHub 在部署时提供了完善的身份验证服务能力,以下是相关
- 默认值:`-` - 默认值:`-`
- 示例:`example.com,admin@other.com` - 示例:`example.com,admin@other.com`
#### `AUTH_DISABLE_EMAIL_PASSWORD`
- 类型:可选
- 描述:设置为 `1` 以禁用邮箱密码登录,强制用户使用 SSO 登录。启用后,登录页面将隐藏邮箱输入框,注册页面将重定向到登录页。
- 默认值:`0`
- 示例:`1`
#### `JWKS_KEY` #### `JWKS_KEY`
- 类型:必选 - 类型:必选

View file

@ -190,13 +190,6 @@ SSRF_ALLOW_IP_ADDRESS_LIST=192.168.1.100,10.0.0.50
- Allow access to internal API gateway: `10.0.0.50` - Allow access to internal API gateway: `10.0.0.50`
- Allow access to internal documentation server: `172.16.0.10` - Allow access to internal documentation server: `172.16.0.10`
### `ENABLE_AUTH_PROTECTION`
- Type: Optional
- Description: Controls whether to enable route protection. When set to `1`, all routes except public routes (like `/api/auth`, `/login`, `/signup`) will require authentication. When set to `0` or not set, only specific protected routes (like `/settings`, `/files`) will require authentication.
- Default: `0`
- Example: `1` or `0`
### `NEXT_PUBLIC_ASSET_PREFIX` ### `NEXT_PUBLIC_ASSET_PREFIX`
- Type: Optional - Type: Optional

View file

@ -185,13 +185,6 @@ SSRF_ALLOW_IP_ADDRESS_LIST=192.168.1.100,10.0.0.50
- 允许访问内网 API 网关:`10.0.0.50` - 允许访问内网 API 网关:`10.0.0.50`
- 允许访问内网文档服务器:`172.16.0.10` - 允许访问内网文档服务器:`172.16.0.10`
### `ENABLE_AUTH_PROTECTION`
- 类型:可选
- 说明:控制是否启用路由保护。当设置为 `1` 时,除了公共路由(如 `/api/auth`、`/login`、`/signup`)外,所有路由都需要认证。当设置为 `0` 或未设置时,只有特定的受保护路由(如 `/settings`、`/files` 等)需要认证。
- 默认值:`0`
- 示例:`1` 或 `0`
### `NEXT_PUBLIC_ASSET_PREFIX` ### `NEXT_PUBLIC_ASSET_PREFIX`
- 类型:可选 - 类型:可选

View file

@ -40,4 +40,3 @@ If you want the deployed version to be pre-configured with Azure OpenAI for end
| `AZURE_ENDPOINT` | Required | Azure API address, can be found in the "Keys and Endpoints" section when checking resources in the Azure portal | - | `https://docs-test-001.openai.azure.com` | | `AZURE_ENDPOINT` | Required | Azure API address, can be found in the "Keys and Endpoints" section when checking resources in the Azure portal | - | `https://docs-test-001.openai.azure.com` |
| `AZURE_API_VERSION` | Required | Azure API version, following the format YYYY-MM-DD | 2023-08-01-preview | `-`, see [latest version](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions) | | `AZURE_API_VERSION` | Required | Azure API version, following the format YYYY-MM-DD | 2023-08-01-preview | `-`, see [latest version](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions) |
| `AZURE_MODEL_LIST` | Required | Used to control the model list, use `+` to add a model, use `-` to hide a model, use `id->deplymentName=displayName` to customize the display name of a model, separated by commas. Definition syntax rules see [Model List](/docs/self-hosting/advanced/model-list) | - | `gpt-35-turbo->my-deploy=GPT 3.5 Turbo` or `gpt-4-turbo->my-gpt4=GPT 4 Turbo<128000:vision:fc>` | | `AZURE_MODEL_LIST` | Required | Used to control the model list, use `+` to add a model, use `-` to hide a model, use `id->deplymentName=displayName` to customize the display name of a model, separated by commas. Definition syntax rules see [Model List](/docs/self-hosting/advanced/model-list) | - | `gpt-35-turbo->my-deploy=GPT 3.5 Turbo` or `gpt-4-turbo->my-gpt4=GPT 4 Turbo<128000:vision:fc>` |
| `ACCESS_CODE` | Optional | Add a password to access LobeHub. You can set a long password to prevent brute force attacks. When this value is separated by commas, it becomes an array of passwords | - | `awCT74` or `e3@09!` or `code1,code2,code3` |

View file

@ -42,4 +42,3 @@ LobeHub 支持使用 [Azure OpenAI](https://learn.microsoft.com/zh-cn/azure/ai-s
| `AZURE_ENDPOINT` | 必选 | Azure API 地址,从 Azure 门户检查资源时,可在 “密钥和终结点” 部分中找到此值 | - | `https://docs-test-001.openai.azure.com` | | `AZURE_ENDPOINT` | 必选 | Azure API 地址,从 Azure 门户检查资源时,可在 “密钥和终结点” 部分中找到此值 | - | `https://docs-test-001.openai.azure.com` |
| `AZURE_API_VERSION` | 必选 | Azure 的 API 版本,遵循 YYYY-MM-DD 格式 | 2023-08-01-preview | `-`,查阅[最新版本](https://learn.microsoft.com/zh-cn/azure/ai-services/openai/reference#chat-completions) | | `AZURE_API_VERSION` | 必选 | Azure 的 API 版本,遵循 YYYY-MM-DD 格式 | 2023-08-01-preview | `-`,查阅[最新版本](https://learn.microsoft.com/zh-cn/azure/ai-services/openai/reference#chat-completions) |
| `AZURE_MODEL_LIST` | 必选 | 用来控制模型列表,使用 `模型名->部署名=展示名` 来自定义模型的展示名,用英文逗号隔开。支持扩展能力,其余语法规则详见 [模型列表](/zh/docs/self-hosting/advanced/model-list) | - | `gpt-35-turbo->my-deploy=GPT 3.5 Turbo` 或 `gpt-4-turbo->my-gpt4=GPT 4 Turbo<128000:vision:fc>` | | `AZURE_MODEL_LIST` | 必选 | 用来控制模型列表,使用 `模型名->部署名=展示名` 来自定义模型的展示名,用英文逗号隔开。支持扩展能力,其余语法规则详见 [模型列表](/zh/docs/self-hosting/advanced/model-list) | - | `gpt-35-turbo->my-deploy=GPT 3.5 Turbo` 或 `gpt-4-turbo->my-gpt4=GPT 4 Turbo<128000:vision:fc>` |
| `ACCESS_CODE` | 可选 | 添加访问 LobeHub 的密码,你可以设置一个长密码以防被爆破,该值用逗号分隔时为密码数组 | - | `awCT74` 或 `e3@09!` or `code1,code2,code3` |

View file

@ -98,6 +98,7 @@
"betterAuth.signin.signupLink": "Sign up now", "betterAuth.signin.signupLink": "Sign up now",
"betterAuth.signin.socialError": "Social sign in failed, please try again", "betterAuth.signin.socialError": "Social sign in failed, please try again",
"betterAuth.signin.socialOnlyHint": "This email was registered via a third-party social account. Sign in with that provider, or", "betterAuth.signin.socialOnlyHint": "This email was registered via a third-party social account. Sign in with that provider, or",
"betterAuth.signin.ssoOnlyNoProviders": "Email registration is disabled and no SSO providers are configured. Please contact your administrator.",
"betterAuth.signin.submit": "Sign In", "betterAuth.signin.submit": "Sign In",
"betterAuth.signup.confirmPasswordPlaceholder": "Confirm your password", "betterAuth.signup.confirmPasswordPlaceholder": "Confirm your password",
"betterAuth.signup.emailPlaceholder": "Enter your email address", "betterAuth.signup.emailPlaceholder": "Enter your email address",

View file

@ -98,6 +98,7 @@
"betterAuth.signin.signupLink": "创建账号", "betterAuth.signin.signupLink": "创建账号",
"betterAuth.signin.socialError": "登录遇到了问题,请重试", "betterAuth.signin.socialError": "登录遇到了问题,请重试",
"betterAuth.signin.socialOnlyHint": "此邮箱是通过第三方社交账号注册的。请使用该服务提供商登录,或", "betterAuth.signin.socialOnlyHint": "此邮箱是通过第三方社交账号注册的。请使用该服务提供商登录,或",
"betterAuth.signin.ssoOnlyNoProviders": "邮箱注册已禁用,且未配置 SSO 提供商。请联系管理员。",
"betterAuth.signin.submit": "登录", "betterAuth.signin.submit": "登录",
"betterAuth.signup.confirmPasswordPlaceholder": "请确认密码", "betterAuth.signup.confirmPasswordPlaceholder": "请确认密码",
"betterAuth.signup.emailPlaceholder": "请输入邮箱地址", "betterAuth.signup.emailPlaceholder": "请输入邮箱地址",

View file

@ -7,4 +7,3 @@ NODE_OPTIONS = "--max-old-space-size=4096"
[template.environment] [template.environment]
OPENAI_API_KEY = "set your OpenAI API Key" OPENAI_API_KEY = "set your OpenAI API Key"
ACCESS_CODE = "set your password to protect your api key"

View file

@ -49,6 +49,7 @@ export type ServerLanguageModel = Partial<Record<GlobalLLMProviderKey, ServerMod
export interface GlobalServerConfig { export interface GlobalServerConfig {
aiProvider: ServerLanguageModel; aiProvider: ServerLanguageModel;
defaultAgent?: PartialDeep<UserDefaultAgent>; defaultAgent?: PartialDeep<UserDefaultAgent>;
disableEmailPassword?: boolean;
enableBusinessFeatures?: boolean; enableBusinessFeatures?: boolean;
enableEmailVerification?: boolean; enableEmailVerification?: boolean;
enableKlavis?: boolean; enableKlavis?: boolean;

View file

@ -24,6 +24,7 @@ export const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
export const USERNAME_REGEX = /^\w+$/; export const USERNAME_REGEX = /^\w+$/;
export interface SignInEmailStepProps { export interface SignInEmailStepProps {
disableEmailPassword?: boolean;
form: FormInstance<{ email: string }>; form: FormInstance<{ email: string }>;
isSocialOnly: boolean; isSocialOnly: boolean;
loading: boolean; loading: boolean;
@ -36,6 +37,7 @@ export interface SignInEmailStepProps {
} }
export const SignInEmailStep = ({ export const SignInEmailStep = ({
disableEmailPassword,
form, form,
isSocialOnly, isSocialOnly,
loading, loading,
@ -133,58 +135,63 @@ export const SignInEmailStep = ({
{getProviderLabel(provider)} {getProviderLabel(provider)}
</Button> </Button>
))} ))}
{divider} {!disableEmailPassword && divider}
</Flexbox> </Flexbox>
)} )}
<Form {serverConfigInit && disableEmailPassword && oAuthSSOProviders.length === 0 && (
form={form} <Alert description={t('betterAuth.signin.ssoOnlyNoProviders')} showIcon type="warning" />
layout="vertical" )}
onFinish={(values) => onCheckUser(values as { email: string })} {!disableEmailPassword && (
> <Form
<Form.Item form={form}
name="email" layout="vertical"
rules={[ onFinish={(values) => onCheckUser(values as { email: string })}
{ message: t('betterAuth.errors.emailRequired'), required: true },
{
validator: (_, value) => {
if (!value) return Promise.resolve();
const trimmedValue = (value as string).trim();
if (EMAIL_REGEX.test(trimmedValue) || USERNAME_REGEX.test(trimmedValue)) {
return Promise.resolve();
}
return Promise.reject(new Error(t('betterAuth.errors.emailInvalid')));
},
},
]}
style={{ marginBottom: 0 }}
> >
<Input <Form.Item
placeholder={t('betterAuth.signin.emailPlaceholder')} name="email"
prefix={ rules={[
<Icon { message: t('betterAuth.errors.emailRequired'), required: true },
icon={Mail} {
style={{ validator: (_, value) => {
marginInline: 6, if (!value) return Promise.resolve();
}} const trimmedValue = (value as string).trim();
/> if (EMAIL_REGEX.test(trimmedValue) || USERNAME_REGEX.test(trimmedValue)) {
} return Promise.resolve();
ref={emailInputRef} }
size="large" return Promise.reject(new Error(t('betterAuth.errors.emailInvalid')));
style={{ },
padding: 6, },
}} ]}
suffix={ style={{ marginBottom: 0 }}
<Button >
icon={ChevronRight} <Input
loading={loading} placeholder={t('betterAuth.signin.emailPlaceholder')}
onClick={() => form.submit()} prefix={
title={t('betterAuth.signin.nextStep')} <Icon
variant={'filled'} icon={Mail}
/> style={{
} marginInline: 6,
/> }}
</Form.Item> />
</Form> }
ref={emailInputRef}
size="large"
style={{
padding: 6,
}}
suffix={
<Button
icon={ChevronRight}
loading={loading}
onClick={() => form.submit()}
title={t('betterAuth.signin.nextStep')}
variant={'filled'}
/>
}
/>
</Form.Item>
</Form>
)}
{isSocialOnly && ( {isSocialOnly && (
<Alert <Alert
description={ description={

View file

@ -10,6 +10,7 @@ import { useSignIn } from './useSignIn';
const SignInPage = () => { const SignInPage = () => {
const { const {
disableEmailPassword,
email, email,
form, form,
handleBackToEmail, handleBackToEmail,
@ -29,6 +30,7 @@ const SignInPage = () => {
<Suspense fallback={<Loading debugId={'Signin'} />}> <Suspense fallback={<Loading debugId={'Signin'} />}>
{step === 'email' ? ( {step === 'email' ? (
<SignInEmailStep <SignInEmailStep
disableEmailPassword={disableEmailPassword}
form={form as any} form={form as any}
isSocialOnly={isSocialOnly} isSocialOnly={isSocialOnly}
loading={loading} loading={loading}

View file

@ -32,6 +32,7 @@ export const useSignIn = () => {
const router = useRouter(); const router = useRouter();
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const enableMagicLink = useServerConfigStore(serverConfigSelectors.enableMagicLink); const enableMagicLink = useServerConfigStore(serverConfigSelectors.enableMagicLink);
const disableEmailPassword = useServerConfigStore(serverConfigSelectors.disableEmailPassword);
const [form] = Form.useForm<SignInFormValues>(); const [form] = Form.useForm<SignInFormValues>();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [socialLoading, setSocialLoading] = useState<string | null>(null); const [socialLoading, setSocialLoading] = useState<string | null>(null);
@ -242,6 +243,7 @@ export const useSignIn = () => {
}; };
return { return {
disableEmailPassword,
email, email,
form, form,
handleBackToEmail, handleBackToEmail,

View file

@ -1,3 +1,6 @@
import { redirect } from 'next/navigation';
import { authEnv } from '@/envs/auth';
import { metadataModule } from '@/server/metadata'; import { metadataModule } from '@/server/metadata';
import { translation } from '@/server/translation'; import { translation } from '@/server/translation';
import { type DynamicLayoutProps } from '@/types/next'; import { type DynamicLayoutProps } from '@/types/next';
@ -17,6 +20,10 @@ export const generateMetadata = async (props: DynamicLayoutProps) => {
}; };
const Page = () => { const Page = () => {
if (authEnv.AUTH_DISABLE_EMAIL_PASSWORD) {
redirect('/signin');
}
return <BetterAuthSignUpForm />; return <BetterAuthSignUpForm />;
}; };

View file

@ -52,7 +52,6 @@ export const getAppConfig = () => {
INTERNAL_APP_URL: z.string().optional(), INTERNAL_APP_URL: z.string().optional(),
VERCEL_EDGE_CONFIG: z.string().optional(), VERCEL_EDGE_CONFIG: z.string().optional(),
MIDDLEWARE_REWRITE_THROUGH_LOCAL: z.boolean().optional(), MIDDLEWARE_REWRITE_THROUGH_LOCAL: z.boolean().optional(),
ENABLE_AUTH_PROTECTION: z.boolean().optional(),
CDN_USE_GLOBAL: z.boolean().optional(), CDN_USE_GLOBAL: z.boolean().optional(),
CUSTOM_FONT_FAMILY: z.string().optional(), CUSTOM_FONT_FAMILY: z.string().optional(),
@ -107,7 +106,6 @@ export const getAppConfig = () => {
APP_URL, APP_URL,
INTERNAL_APP_URL, INTERNAL_APP_URL,
MIDDLEWARE_REWRITE_THROUGH_LOCAL: process.env.MIDDLEWARE_REWRITE_THROUGH_LOCAL === '1', MIDDLEWARE_REWRITE_THROUGH_LOCAL: process.env.MIDDLEWARE_REWRITE_THROUGH_LOCAL === '1',
ENABLE_AUTH_PROTECTION: process.env.ENABLE_AUTH_PROTECTION === '1',
CUSTOM_FONT_FAMILY: process.env.CUSTOM_FONT_FAMILY, CUSTOM_FONT_FAMILY: process.env.CUSTOM_FONT_FAMILY,
CUSTOM_FONT_URL: process.env.CUSTOM_FONT_URL, CUSTOM_FONT_URL: process.env.CUSTOM_FONT_URL,

View file

@ -13,6 +13,7 @@ declare global {
AUTH_SSO_PROVIDERS?: string; AUTH_SSO_PROVIDERS?: string;
AUTH_TRUSTED_ORIGINS?: string; AUTH_TRUSTED_ORIGINS?: string;
AUTH_ALLOWED_EMAILS?: string; AUTH_ALLOWED_EMAILS?: string;
AUTH_DISABLE_EMAIL_PASSWORD?: string;
// ===== Auth Provider Credentials ===== // // ===== Auth Provider Credentials ===== //
AUTH_GOOGLE_ID?: string; AUTH_GOOGLE_ID?: string;
@ -112,6 +113,7 @@ export const getAuthConfig = () => {
AUTH_EMAIL_VERIFICATION: z.boolean().optional().default(false), AUTH_EMAIL_VERIFICATION: z.boolean().optional().default(false),
AUTH_ENABLE_MAGIC_LINK: z.boolean().optional().default(false), AUTH_ENABLE_MAGIC_LINK: z.boolean().optional().default(false),
AUTH_ALLOWED_EMAILS: z.string().optional(), AUTH_ALLOWED_EMAILS: z.string().optional(),
AUTH_DISABLE_EMAIL_PASSWORD: z.boolean().optional().default(false),
AUTH_GOOGLE_ID: z.string().optional(), AUTH_GOOGLE_ID: z.string().optional(),
AUTH_GOOGLE_SECRET: z.string().optional(), AUTH_GOOGLE_SECRET: z.string().optional(),
@ -199,6 +201,7 @@ export const getAuthConfig = () => {
AUTH_SSO_PROVIDERS: process.env.AUTH_SSO_PROVIDERS, AUTH_SSO_PROVIDERS: process.env.AUTH_SSO_PROVIDERS,
AUTH_TRUSTED_ORIGINS: process.env.AUTH_TRUSTED_ORIGINS, AUTH_TRUSTED_ORIGINS: process.env.AUTH_TRUSTED_ORIGINS,
AUTH_ALLOWED_EMAILS: process.env.AUTH_ALLOWED_EMAILS, AUTH_ALLOWED_EMAILS: process.env.AUTH_ALLOWED_EMAILS,
AUTH_DISABLE_EMAIL_PASSWORD: process.env.AUTH_DISABLE_EMAIL_PASSWORD === '1',
// Cognito provider specific env vars // Cognito provider specific env vars
AUTH_COGNITO_DOMAIN: process.env.AUTH_COGNITO_DOMAIN, AUTH_COGNITO_DOMAIN: process.env.AUTH_COGNITO_DOMAIN,

View file

@ -107,7 +107,7 @@ export function defineConfig(customOptions: CustomBetterAuthOptions) {
emailAndPassword: { emailAndPassword: {
autoSignIn: true, autoSignIn: true,
enabled: true, enabled: !authEnv.AUTH_DISABLE_EMAIL_PASSWORD,
maxPasswordLength: 64, maxPasswordLength: 64,
minPasswordLength: 8, minPasswordLength: 8,
requireEmailVerification: authEnv.AUTH_EMAIL_VERIFICATION, requireEmailVerification: authEnv.AUTH_EMAIL_VERIFICATION,

View file

@ -228,7 +228,6 @@ export function defineConfig() {
}; };
logDefault('Middleware configuration: %O', { logDefault('Middleware configuration: %O', {
enableAuthProtection: appEnv.ENABLE_AUTH_PROTECTION,
enableOIDC: authEnv.ENABLE_OIDC, enableOIDC: authEnv.ENABLE_OIDC,
}); });

View file

@ -102,6 +102,8 @@ export default {
'betterAuth.signin.socialError': 'Social sign in failed, please try again', 'betterAuth.signin.socialError': 'Social sign in failed, please try again',
'betterAuth.signin.socialOnlyHint': 'betterAuth.signin.socialOnlyHint':
'This email was registered via a third-party social account. Sign in with that provider, or', 'This email was registered via a third-party social account. Sign in with that provider, or',
'betterAuth.signin.ssoOnlyNoProviders':
'Email registration is disabled and no SSO providers are configured. Please contact your administrator.',
'betterAuth.signin.submit': 'Sign In', 'betterAuth.signin.submit': 'Sign In',
'betterAuth.signup.confirmPasswordPlaceholder': 'Confirm your password', 'betterAuth.signup.confirmPasswordPlaceholder': 'Confirm your password',
'betterAuth.signup.emailPlaceholder': 'Enter your email address', 'betterAuth.signup.emailPlaceholder': 'Enter your email address',

View file

@ -74,6 +74,7 @@ export const getServerGlobalConfig = async () => {
defaultAgent: { defaultAgent: {
config: parseAgentConfig(DEFAULT_AGENT_CONFIG), config: parseAgentConfig(DEFAULT_AGENT_CONFIG),
}, },
disableEmailPassword: authEnv.AUTH_DISABLE_EMAIL_PASSWORD,
enableBusinessFeatures: ENABLE_BUSINESS_FEATURES, enableBusinessFeatures: ENABLE_BUSINESS_FEATURES,
enableEmailVerification: authEnv.AUTH_EMAIL_VERIFICATION, enableEmailVerification: authEnv.AUTH_EMAIL_VERIFICATION,
enableKlavis: !!klavisEnv.KLAVIS_API_KEY, enableKlavis: !!klavisEnv.KLAVIS_API_KEY,

View file

@ -3,6 +3,7 @@ import { type ServerConfigStore } from './store';
export const featureFlagsSelectors = (s: ServerConfigStore) => s.featureFlags; export const featureFlagsSelectors = (s: ServerConfigStore) => s.featureFlags;
export const serverConfigSelectors = { export const serverConfigSelectors = {
disableEmailPassword: (s: ServerConfigStore) => s.serverConfig.disableEmailPassword || false,
enableBusinessFeatures: (s: ServerConfigStore) => s.serverConfig.enableBusinessFeatures || false, enableBusinessFeatures: (s: ServerConfigStore) => s.serverConfig.enableBusinessFeatures || false,
enableEmailVerification: (s: ServerConfigStore) => enableEmailVerification: (s: ServerConfigStore) =>
s.serverConfig.enableEmailVerification || false, s.serverConfig.enableEmailVerification || false,