其他社交提供商

其他社交提供商的设置和用法。

Better Auth 通过 Generic OAuth Plugin 支持任何实现 OAuth 2.0 或 OpenID Connect(OIDC)的社交提供商。你可以使用内置的提供商辅助工具、安装社区提供商辅助工具,或手动配置提供商。

安装

将插件添加到你的认证配置中

要使用 Generic OAuth 插件,需要将其添加到你的认证配置中。

auth.ts
import { betterAuth } from "better-auth"
import { genericOAuth } from "better-auth/plugins"

export const auth = betterAuth({
    // ... 其他配置选项
    plugins: [
        genericOAuth({ 
            config: [ 
                { 
                    providerId: "provider-id", 
                    clientId: "test-client-id", 
                    clientSecret: "test-client-secret", 
                    discoveryUrl: "https://auth.example.com/.well-known/openid-configuration", 
                    // ... 其他配置选项
                }, 
                // 根据需要添加更多提供商
            ] 
        }) 
    ]
})

创建你的认证客户端

auth-client.ts
import { createAuthClient } from "better-auth/client"

const authClient = createAuthClient()

详细了解 Generic OAuth 插件的安装和用法,请参阅 Generic OAuth 插件文档。

使用示例

以下是配置通用 OAuth 提供商的基本示例:

auth.ts
import { betterAuth } from "better-auth"
import { genericOAuth } from "better-auth/plugins"

export const auth = betterAuth({
  plugins: [
    genericOAuth({
      config: [
        {
          providerId: "provider-id",
          clientId: process.env.CLIENT_ID,
          clientSecret: process.env.CLIENT_SECRET,
          discoveryUrl: "https://auth.example.com/.well-known/openid-configuration",
        },
      ],
    }),
  ],
})

提供商辅助工具

提供商辅助工具将特定于提供商的端点、作用域和个人资料映射封装为可复用的 GenericOAuthConfig 工厂函数。

内置提供商辅助工具

Better Auth 内置了以下提供商的辅助工具:

  • Auth0 - auth0(options)
  • Gumroad - gumroad(options)
  • HubSpot - hubspot(options)
  • Keycloak - keycloak(options)
  • LINE - line(options)
  • Microsoft Entra ID (Azure AD) - microsoftEntraId(options)
  • Okta - okta(options)
  • Patreon - patreon(options)
  • Slack - slack(options)
  • Yandex - yandex(options)

以下是使用 Slack 的示例:

auth.ts
import { betterAuth } from "better-auth"
import { genericOAuth, slack } from "better-auth/plugins"

export const auth = betterAuth({
  plugins: [
    genericOAuth({
      config: [
        slack({
          clientId: process.env.SLACK_CLIENT_ID,
          clientSecret: process.env.SLACK_CLIENT_SECRET,
        }),
      ],
    }),
  ],
})
sign-in.ts
const response = await authClient.signIn.social({
  provider: "slack",
  callbackURL: "/dashboard",
})

每个辅助工具都通过 BaseOAuthProviderOptions 接受通用 OAuth 选项,并包含以下特定于提供商的字段:

  • Auth0:需要 domain(例如,dev-xxx.eu.auth0.com)
  • HubSpot:接受可选的 scopes,默认值为 ["oauth"]
  • Keycloak:需要 issuer(例如,https://my-domain/realms/MyRealm)
  • LINE:接受可选的 providerId。使用不同的提供商 ID 和凭据调用 line(),即可支持多个特定国家/地区的频道
  • Microsoft Entra ID:需要具体的租户 GUID。对于多租户的 "common"、"organizations" 或 "consumers" authority,请使用内置的 Microsoft 社交提供商
  • Okta:需要 issuer(例如,https://dev-xxxxx.okta.com/oauth2/default)

所有辅助工具都接受以下通用选项:

  • clientId
  • clientSecret
  • tokenEndpointAuth
  • scopes
  • redirectURI
  • pkce
  • disableImplicitSignUp
  • disableSignUp
  • overrideUserInfo
  • endSessionEndpoint
  • postLogoutRedirectURI
  • disableProviderLogout

社区提供商辅助工具

提供商作者和社区维护者可以发布可复用的辅助工具,这些辅助工具会返回一个类型化的 GenericOAuthConfig,供 Generic OAuth 插件使用。

社区提供商辅助工具并非由 Better Auth 团队官方提供或验证。请自行斟酌使用,并在将其集成到应用程序之前审查其源代码。

提供商包仓库维护者
AgentID@agentmail/agentid-better-authagentmail-to/agentid-better-auth@agentmail-to
EVE Online@localisprimary/better-auth-eve-onlinelocalisprimary/better-auth-eve-online@localisprimary
ThunderID@thunderid/better-auththunder-id/javascript-sdks@thunder-id

创建提供商辅助工具

提供商辅助工具接受凭据和特定于提供商的选项,然后返回 GenericOAuthConfig。

provider.ts
import type {
  BaseOAuthProviderOptions,
  GenericOAuthConfig,
} from "better-auth/plugins/generic-oauth";

export interface ExampleOptions extends BaseOAuthProviderOptions {}

export function example(
  options: ExampleOptions,
): GenericOAuthConfig<"example"> {
  return {
    providerId: "example",
    discoveryUrl: "https://auth.example.com/.well-known/openid-configuration",
    clientId: options.clientId,
    clientSecret: options.clientSecret,
    tokenEndpointAuth: options.tokenEndpointAuth,
    scopes: options.scopes ?? ["openid", "email", "profile"],
    redirectURI: options.redirectURI,
  };
}

用户从辅助工具作者处安装该辅助工具,并将其传递给 Generic OAuth。

auth.ts
import { example } from "@example/better-auth";
import { betterAuth } from "better-auth";
import { genericOAuth } from "better-auth/plugins";

export const auth = betterAuth({
  plugins: [
    genericOAuth({
      config: [
        example({
          clientId: process.env.EXAMPLE_CLIENT_ID!,
          clientSecret: process.env.EXAMPLE_CLIENT_SECRET!,
        }),
      ],
    }),
  ],
});

如需与社区分享提供商辅助工具,请参阅贡献指南。

手动配置提供商

如果你需要配置的提供商没有对应的提供商辅助工具,可以手动配置:

Instagram 示例

auth.ts
import { betterAuth } from "better-auth";
import { genericOAuth } from "better-auth/plugins";

export const auth = betterAuth({
  // ... 其他配置选项
  plugins: [
    genericOAuth({
      config: [
        {
          providerId: "instagram",
          clientId: process.env.INSTAGRAM_CLIENT_ID as string,
          clientSecret: process.env.INSTAGRAM_CLIENT_SECRET as string,
          authorizationUrl: "https://api.instagram.com/oauth/authorize",
          tokenUrl: "https://api.instagram.com/oauth/access_token",
          scopes: ["user_profile", "user_media"],
        },
      ],
    }),
  ],
});
sign-in.ts
const response = await authClient.signIn.social({
  provider: "instagram",
  callbackURL: "/dashboard",
});

Coinbase 示例

auth.ts
import { betterAuth } from "better-auth";
import { genericOAuth } from "better-auth/plugins";

export const auth = betterAuth({
  // ... 其他配置选项
  plugins: [
    genericOAuth({
      config: [
        {
          providerId: "coinbase",
          clientId: process.env.COINBASE_CLIENT_ID as string,
          clientSecret: process.env.COINBASE_CLIENT_SECRET as string,
          authorizationUrl: "https://www.coinbase.com/oauth/authorize",
          tokenUrl: "https://api.coinbase.com/oauth/token",
          scopes: ["wallet:user:read"], // 以及更多...
        },
      ],
    }),
  ],
});
sign-in.ts
const response = await authClient.signIn.social({
  provider: "coinbase",
  callbackURL: "/dashboard",
});