v1xingyue/dsh-auth-plugin1

dsh-auth-plugin

DSH Web 用户授权插件 — 用户名密码 + 通用 OAuth 2.0(内置 GitHub/Google/Discord 等模板)+ Solana/EVM 钱包登录。零依赖核心,纯配置接入

包名
dsh-auth-plugin
版本
1.8.0
许可证
MIT
最近更新
2026年8月18日

安装

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:v1xingyue/dsh-auth-plugin

(默认 admin/admin123,启动警告,请立即覆盖配置)


安装后在 profile 的 `cordis.patch.yml` 按 id 覆盖 config 即可:

```yaml
- id: auth
  config:
    users:
      admin: { password: "scrypt$...", role: admin }
    oauth:
      providers:
        github: { builtin: github, clientId: "...", clientSecret: "..." }

已在隔离 DSH_HOME 完整验证:dsh plugin add → bundles 列表 自动追加 → --dump-config 出现 # == dsh-auth-plugin 段。

安装后文件布局

~/.dsh/profiles/web/
├── cordis.patch.yml         # 认证配置(insert auth 行)
├── dsh-auth-plugin.js       # 插件本体(单文件)
├── package.json             # profile manifest(可选加 "type": "module")
└── pnpm-workspace.yaml

快速开始


# cordis.patch.yml —— 最简配置:用户名密码登录
- insert:
    - id: auth
      name: "./dsh-auth-plugin.js"
      config:
        users:
          admin: admin123

## 配置参考

### 顶层配置

| 字段 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `enabled` | boolean | `true` | 总开关 |
| `secret` | string | 每次启动随机 | 会话签名密钥;可用环境变量 `DSH_AUTH_SECRET` 固定 |
| `ttlHours` | number | `24` | 会话有效期(小时) |
| `title` | string | `DSH 登录` | 登录页标题 |
| `cookie` | string | `dsh_session` | 会话 Cookie 名 |
| `users` | dict | 空→`admin/admin123` | 用户表(见下) |
| `solana` | `false` \| object | `false` | Solana 钱包登录配置(见下) |
| `evm` | `false` \| object | `false` | EVM 钱包登录配置(见下) |
| `oauth` | object | `{providers:{}}` | 通用 OAuth 配置(见下) |
| `publicPaths` | string[] | 见下 | 免认证路径(精确或前缀匹配) |

默认 `publicPaths`:`/login`、`/api/auth/login`、`/api/auth/logout`、
`/favicon.ico`

> ⚠️ **`secret` 为空时每次启动随机**——重启后所有会话失效需重新登录。
> 这是保守设计(无需持久化);生产环境建议固定:`secret: !!js process.env.DSH_AUTH_SECRET`。

### `users` 三种写法

```yaml

### 顶层配置

| 字段 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `enabled` | boolean | `true` | 总开关 |
| `secret` | string | 每次启动随机 | 会话签名密钥;可用环境变量 `DSH_AUTH_SECRET` 固定 |
| `ttlHours` | number | `24` | 会话有效期(小时) |
| `title` | string | `DSH 登录` | 登录页标题 |
| `cookie` | string | `dsh_session` | 会话 Cookie 名 |
| `users` | dict | 空→`admin/admin123` | 用户表(见下) |
| `solana` | `false` \| object | `false` | Solana 钱包登录配置(见下) |
| `evm` | `false` \| object | `false` | EVM 钱包登录配置(见下) |
| `oauth` | object | `{providers:{}}` | 通用 OAuth 配置(见下) |
| `publicPaths` | string[] | 见下 | 免认证路径(精确或前缀匹配) |

默认 `publicPaths`:`/login`、`/api/auth/login`、`/api/auth/logout`、
`/favicon.ico`

> ⚠️ **`secret` 为空时每次启动随机**——重启后所有会话失效需重新登录。
> 这是保守设计(无需持久化);生产环境建议固定:`secret: !!js process.env.DSH_AUTH_SECRET`。

### `solana` 配置

| 字段 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `enabled` | boolean | `true`(对象形式) | 开关;`solana: false` 或省略 = 禁用 |
| `challengeTtlMs` | number | `300000` | nonce 有效期(5 分钟) |
| `allowlist` | string[] | **必填** | 公钥白名单(base58),至少 1 个 |
| `role` | string | `user` | 钱包登录默认角色 |

> ⚠️ **`allowlist` 必填**:启用时缺字段或空数组都会在加载时报配置错误
> (schema 层拦截)——**不允许"任何钱包可登录"**。

### `evm` 配置(MetaMask 等 EVM 钱包)

```yaml
evm:
  enabled: true
  allowlist:                # 必填:只允许这些 0x 地址(小写或混合大小写均可)
    - "0x4e984616e2dd9dffe7f2413efc7da35ef64c4117"
  role: user
字段类型默认值说明
enabledbooleantrue(对象形式)开关;evm: false 或省略 = 禁用
challengeTtlMsnumber300000nonce 有效期(5 分钟)
allowliststring[]必填允许的 0x 地址,至少 1 个
rolestringuser登录成功角色

⚠️ 同 Solana:allowlist 必填;且需要可选依赖 @noble/curves + @noble/hashesdsh plugin --profile web add @noble/curves @noble/hashes), 缺失时该功能自动禁用(其余登录不受影响)。

oauth 通用 OAuth 2.0 配置

每个 provider 一条,纯配置接入任意标准授权码 OAuth 服务。 支持内置模板:填 builtin + 凭据即可,端点/字段映射/scope 自动填充。

最简方式:内置模板(推荐)

oauth:
  providers:
    github:                       # provider id
      builtin: "github"           # ← 内置模板:端点/字段/scope 自动填充
      clientId: "Ov23li..."
      clientSecret: "ghp_..."     # 仅服务端使用,绝不下发浏览器

内置模板一览(BUILTIN_OAUTH,显式字段可覆盖模板):

builtin授权端点token 端点userinfo 端点默认 scopeidField
githubgithub.com/login/oauth/authorize…/access_tokenapi.github.com/userread:userid
googleaccounts.google.com/o/oauth2/v2/authoauth2.googleapis.com/token…/oauth2/v3/userinfoopenid email profilesub
discorddiscord.com/oauth2/authorizediscord.com/api/oauth2/tokendiscord.com/api/users/@meidentify emailid
gitlabgitlab.com/oauth/authorizegitlab.com/oauth/tokengitlab.com/api/v4/userread_userid
microsoftlogin.microsoftonline.com/common/oauth2/v2.0/authorize…/tokengraph.microsoft.com/v1.0/meUser.Readid
bitbucketbitbucket.org/site/oauth2/authorize…/access_tokenapi.bitbucket.org/2.0/useraccountuuid

完整方式:显式配置(任意标准 OAuth 服务)

oauth:
  providers:
    custom:
      label: "我的服务"
      clientId: "..."
      clientSecret: "..."
      authorizeUrl: "https://.../authorize"
      tokenUrl: "https://.../token"
      userInfoUrl: "https://.../userinfo"
      scope: "read"                # 可选
      idField: "id"                # 可选,默认 id
      nameField: "name"            # 可选
      emailField: "email"          # 可选
      role: "user"                 # 可选
      # redirectUri: "https://..." # 可选:显式回调地址
字段类型默认值说明
builtinstring""内置模板名(见上表);填了则端点/字段/scope 用模板
labelstringprovider id / 模板登录页按钮文案
clientId / clientSecretstring必填OAuth 应用凭据
authorizeUrl / tokenUrl / userInfoUrlstring模板值三个端点
responseTypestringcode授权响应类型(授权码模式)
scopestring模板值/空请求的 scope(空格分隔)
redirectUristring自动显式回调地址;留空 = http:///api/auth/oauth//callback
idField / nameField / emailFieldstringid / 模板userinfo 字段映射
emailDomainsstring[][]邮箱域名白名单;非空时邮箱域名必须命中,否则拒绝(oauth_email_not_allowed
rolestringuser登录成功角色
userInfoHeadersdict{}取 userinfo 附加请求头
tokenParamsdict{}token 请求附加参数
stateTtlMsnumber600000state 有效期(10 分钟)

回调地址(OAuth 应用后台填写):http(s):///api/auth/oauth//callback 例如:http://127.0.0.1:3080/api/auth/oauth/github/callback 未知 builtin 名或合并后缺必需字段会在启动时报配置错误。