单点登录 (SSO)

单点登录(SSO)允许用户使用单一凭证对多个应用程序进行身份验证。此插件支持OpenID Connect(OIDC)和OAuth2提供商。

SAML支持即将推出。在我们的GitHub上为该功能请求投票

安装

将插件添加到服务器

auth.ts
import { betterAuth } from "better-auth"
import { sso } from "better-auth/plugins/sso";
 
const auth = betterAuth({
    plugins: [ 
        sso() 
    ] 
})

迁移数据库

运行迁移或生成schema,以向数据库添加必要的字段和表。

npx @better-auth/cli migrate

查看Schema部分手动添加字段。

添加客户端插件

auth-client.ts
import { createAuthClient } from "better-auth/client"
import { ssoClient } from "better-auth/client/plugins"
 
const authClient = createAuthClient({
    plugins: [ 
        ssoClient() 
    ] 
})

使用方法

注册OIDC提供商

要注册OIDC提供商,请使用createOIDCProvider端点并提供提供商所需的配置详情。

系统将使用提供商ID自动生成重定向URL。例如,如果提供商ID是hydra,则重定向URL将是{baseURL}/api/auth/sso/hydra。注意,根据您的基本路径配置,/api/auth可能会有所不同。

register-provider.ts
import { authClient } from "@/lib/auth-client";
 
// 如果提供商支持发现,则仅使用issuer
await authClient.sso.register({
    issuer: "https://idp.example.com",
    providerId: "example-provider",
});
 
// 包含所有字段
await authClient.sso.register({
    issuer: "https://idp.example.com",
    domain: "example.com",
    clientId: "client-id",
    clientSecret: "client-secret",
    authorizationEndpoint: "https://idp.example.com/authorize",
    tokenEndpoint: "https://idp.example.com/token",
    jwksEndpoint: "https://idp.example.com/jwks",
    mapping: {
        id: "sub",
        email: "email",
        emailVerified: "email_verified",
        name: "name",
        image: "picture",
    },
    providerId: "example-provider",
});

使用SSO登录

要使用SSO提供商登录,您可以调用signIn.sso

您可以使用匹配域名的电子邮件进行登录:

sign-in.ts
const res = await authClient.signIn.sso({
    email: "[email protected]",
    callbackURL: "/dashboard",
});

或者您可以指定域名:

sign-in-domain.ts
const res = await authClient.signIn.sso({
    domain: "example.com",
    callbackURL: "/dashboard",
});

如果提供商与组织关联,您还可以使用组织别名登录:

sign-in-org.ts
const res = await authClient.signIn.sso({
    organizationSlug: "example-org",
    callbackURL: "/dashboard",
});

或者,您可以使用提供商的ID登录:

sign-in-provider-id.ts
const res = await authClient.signIn.sso({
    providerId: "example-provider-id",
    callbackURL: "/dashboard",
});

要使用服务器API,您可以使用signInSSO

sign-in-org.ts
const res = await auth.api.signInSSO({
    body: {
        organizationSlug: "example-org",
        callbackURL: "/dashboard",
    }
});

当用户通过身份验证时,如果用户不存在,将使用provisionUser函数配置用户。如果启用了组织配置且提供商与组织关联,则用户将被添加到该组织。

auth.ts
const auth = betterAuth({
    plugins: [
        sso({
            provisionUser: async (user) => {
                // 配置用户
            },
            organizationProvisioning: {
                disabled: false,
                defaultRole: "member",
                getRole: async (user) => {
                    // 如需要,获取角色
                },
            },
        }),
    ],
});

Schema

该插件需要在ssoProvider表中添加额外字段来存储提供商的配置。

Field NameTypeKeyDescription
idstring数据库标识符
issuerstring-发行者标识符
domainstring-提供商的域名
oidcConfigstring-OIDC配置
userIdstring-用户ID
providerIdstring-提供商ID。用于标识提供商并生成重定向URL。
organizationIdstring-组织ID。如果提供商与组织链接。

选项

服务器

provisionUser: 当用户使用SSO提供商登录时配置用户的自定义函数。

organizationProvisioning: 向组织配置用户的选项。

PropTypeDefault
provisionUser?
function
-
organizationProvisioning?
object
-

On this page