Skip to content

Commit

Permalink
feat: support custom auth proxy header name (#472)
Browse files Browse the repository at this point in the history
Signed-off-by: BobDu <[email protected]>
  • Loading branch information
BobDu authored Mar 9, 2024
1 parent 1fa33bb commit 3195778
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 10 deletions.
3 changes: 2 additions & 1 deletion README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,8 @@ Set env `AUTH_PROXY_ENABLED=true` can enable auth proxy mode.

After activating this feature, it is necessary to ensure that chatgpt-web can only be accessed through a reverse proxy.

Authentication is carried out by the reverse proxy, which then forwards the request with the `X-Email` header to identify the user identity.
Authentication is carried out by the reverse proxy, which then forwards the request with the header to identify the user identity.
Default header name is `X-Email`, can custom config use set env `AUTH_PROXY_HEADER_NAME`.

Recommended for current IdP to use LDAP protocol, using [authelia](https://www.authelia.com)

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,8 @@ pnpm build

在开启该功能后 需确保 chatgpt-web 只能通过反向代理访问

由反向代理进行进行身份验证 并再转发请求时携带请求头`X-Email`标识用户身份
由反向代理进行进行身份验证 并再转发请求时携带请求头标识用户身份
默认请求头为 `X-Email` 并可以通过设置环境变量 `AUTH_PROXY_HEADER_NAME` 自定义配置

推荐当前 Idp 使用 LDAP 协议的 可以选择使用 [authelia](https://www.authelia.com)

Expand Down
14 changes: 9 additions & 5 deletions service/src/middleware/auth.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import jwt from 'jsonwebtoken'
import type { Request } from 'express'
import { getCacheConfig } from '../storage/config'
import { authProxyHeaderName, getCacheConfig } from '../storage/config'
import { createUser, getUser, getUserById } from '../storage/mongo'
import { Status, UserRole } from '../storage/model'
import type { AuthJwtPayload } from '../types'
Expand All @@ -10,17 +10,17 @@ async function auth(req, res, next) {

if (config.siteConfig.authProxyEnabled) {
try {
const username = req.header('X-Email')
const username = req.header(authProxyHeaderName)
if (!username) {
res.send({ status: 'Unauthorized', message: 'Please config auth proxy (usually is nginx) add set proxy header X-Email.', data: null })
res.send({ status: 'Unauthorized', message: `Please config auth proxy (usually is nginx) add set proxy header ${authProxyHeaderName}.`, data: null })
return
}
const user = await getUser(username)
req.headers.userId = user._id.toString()
next()
}
catch (error) {
res.send({ status: 'Unauthorized', message: error.message ?? 'Please config auth proxy (usually is nginx) add set proxy header X-Email.', data: null })
res.send({ status: 'Unauthorized', message: error.message ?? `Please config auth proxy (usually is nginx) add set proxy header ${authProxyHeaderName}.`, data: null })
}
return
}
Expand Down Expand Up @@ -52,7 +52,11 @@ async function getUserId(req: Request): Promise<string | undefined> {
try {
const config = await getCacheConfig()
if (config.siteConfig.authProxyEnabled) {
const username = req.header('X-Email')
const username = req.header(authProxyHeaderName)
if (!username) {
globalThis.console.error(`Please config auth proxy (usually is nginx) add set proxy header ${authProxyHeaderName}.`)
return null
}
let user = await getUser(username)
if (user == null) {
const isRoot = username.toLowerCase() === process.env.ROOT_USER
Expand Down
6 changes: 3 additions & 3 deletions service/src/middleware/rootAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import jwt from 'jsonwebtoken'
import * as dotenv from 'dotenv'
import { Status, UserRole } from '../storage/model'
import { getUser, getUserById } from '../storage/mongo'
import { getCacheConfig } from '../storage/config'
import { authProxyHeaderName, getCacheConfig } from '../storage/config'
import type { AuthJwtPayload } from '../types'

dotenv.config()
Expand All @@ -12,7 +12,7 @@ async function rootAuth(req, res, next) {

if (config.siteConfig.authProxyEnabled) {
try {
const username = req.header('X-Email')
const username = req.header(authProxyHeaderName)
const user = await getUser(username)
req.headers.userId = user._id
if (user == null || user.status !== Status.Normal || !user.roles.includes(UserRole.Admin))
Expand All @@ -21,7 +21,7 @@ async function rootAuth(req, res, next) {
next()
}
catch (error) {
res.send({ status: 'Unauthorized', message: error.message ?? 'Please config auth proxy (usually is nginx) add set proxy header X-Email.', data: null })
res.send({ status: 'Unauthorized', message: error.message ?? `Please config auth proxy (usually is nginx) add set proxy header ${authProxyHeaderName}.`, data: null })
}
return
}
Expand Down
2 changes: 2 additions & 0 deletions service/src/storage/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,5 @@ export async function getApiKeys() {
})
return result
}

export const authProxyHeaderName = process.env.AUTH_PROXY_HEADER_NAME ?? 'X-Email'

0 comments on commit 3195778

Please sign in to comment.