OAuth

Better Auth 自带对 OAuth 2.0 和 OpenID Connect 的内置支持。这允许您通过像 Google、Facebook、GitHub 等流行的 OAuth 提供商来认证用户。

如果您的所需提供商没有直接支持,您可以使用 Generic OAuth Plugin 进行自定义集成。

Configuring Social Providers

要启用社交提供商,您需要为该提供商提供 clientIdclientSecret

以下是配置 Google 作为提供商的示例:

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

export const auth = betterAuth({
  // Other configurations...
  socialProviders: {
    google: {
      clientId: "YOUR_GOOGLE_CLIENT_ID",
      clientSecret: "YOUR_GOOGLE_CLIENT_SECRET",
    },
  },
});

Usage

Sign In

要使用社交提供商登录,您可以使用 authClientsignIn.social 函数,或者对于服务器端使用,使用 auth.api

// client-side usage
await authClient.signIn.social({
  provider: "google", // or any other provider id
})
// server-side usage
await auth.api.signInSocial({
  body: {
    provider: "google", // or any other provider id
  },
});

要将账户链接到社交提供商,您可以使用 authClientlinkAccount 函数,或者对于服务器端使用,使用 auth.api

await authClient.linkSocial({
  provider: "google", // or any other provider id
})

server-side usage:

await auth.api.linkSocialAccount({
  body: {
    provider: "google", // or any other provider id
  },
  headers: // pass headers with authenticated token
});

Get Access Token

要获取社交提供商的访问令牌,您可以使用 authClientgetAccessToken 函数,或者对于服务器端使用,使用 auth.api。当您使用此端点时,如果访问令牌已过期,它将被刷新。

const { accessToken } = await authClient.getAccessToken({
  providerId: "google", // or any other provider id
  accountId: "accountId", // optional, if you want to get the access token for a specific account
})

server-side usage:

await auth.api.getAccessToken({
  body: {
    providerId: "google", // or any other provider id
    accountId: "accountId", // optional, if you want to get the access token for a specific account
    userId: "userId", // optional, if you don't provide headers with authenticated token
  },
  headers: // pass headers with authenticated token
});

Get Account Info Provided by the provider

要获取提供商特定的账户信息,您可以使用 authClientaccountInfo 函数,或者对于服务器端使用,使用 auth.api

const info = await authClient.accountInfo({
  accountId: "accountId", // here you pass in the provider given account id, the provider is automatically detected from the account id
})

server-side usage:

await auth.api.accountInfo({
  body: { accountId: "accountId" },
  headers: // pass headers with authenticated token
});

Requesting Additional Scopes

有时您的应用程序可能需要在用户已经注册后需要额外的 OAuth 范围(例如,访问 GitHub 仓库或 Google Drive)。用户可能不想在最初授予广泛的权限,而是更喜欢从最小权限开始,并在需要时授予额外访问权限。

您可以通过使用与同一提供商的 linkSocial 方法来请求额外范围。这将触发一个新的 OAuth 流程,请求额外范围,同时保持现有的账户连接。

const requestAdditionalScopes = async () => {
    await authClient.linkSocial({
        provider: "google",
        scopes: ["https://www.googleapis.com/auth/drive.file"],
    });
};

确保您运行的是 Better Auth 版本 1.2.7 或更高版本。较早版本(如 1.2.2)在尝试使用现有提供商链接额外范围时可能会显示“Social account already linked”错误。

Provider Options

scope

访问请求的范围。例如,emailprofile

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

export const auth = betterAuth({
  // Other configurations...
  socialProviders: {
    google: {
      clientId: "YOUR_GOOGLE_CLIENT_ID",
      clientSecret: "YOUR_GOOGLE_CLIENT_SECRET",
      scope: ["email", "profile"],
    },
  },
});

redirectURI

提供商的自定义重定向 URI。默认情况下,它使用 /api/auth/callback/${providerName}

auth.ts

export const auth = betterAuth({
  // Other configurations...
  socialProviders: {
    google: {
      clientId: "YOUR_GOOGLE_CLIENT_ID",
      clientSecret: "YOUR_GOOGLE_CLIENT_SECRET",
      redirectURI: "https://your-app.com/auth/callback",
    },
  },
});

disableSignUp

禁用新用户的注册。

disableIdTokenSignIn

禁用使用 ID 令牌进行登录。默认情况下,对于像 Google 和 Apple 这样的某些提供商,它是启用的。

verifyIdToken

用于验证 ID 令牌的自定义函数。

overrideUserInfoOnSignIn

一个布尔值,用于确定在登录时是否覆盖数据库中的用户信息。默认情况下,它设置为 false,意味着在登录期间用户信息不会被覆盖。如果您想在每次登录时更新用户信息,请将其设置为 true

mapProfileToUser

一个自定义函数,用于将提供商返回的用户配置文件映射到数据库中的用户对象。

如果您的用户对象中有额外的字段想要从提供商的配置文件填充,或者如果您想更改默认的用户对象映射方式,这很有用。

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

export const auth = betterAuth({
  // Other configurations...
  socialProviders: {
    google: {
      clientId: "YOUR_GOOGLE_CLIENT_ID",
      clientSecret: "YOUR_GOOGLE_CLIENT_SECRET",
      mapProfileToUser: (profile) => {
        return {
          firstName: profile.given_name,
          lastName: profile.family_name,
        };
      },
    },
  },
});

refreshAccessToken

用于刷新令牌的自定义函数。此功能仅支持内置社交提供商(Google、Facebook、GitHub 等),目前不支持通过 Generic OAuth Plugin 配置的自定义 OAuth 提供商。对于内置提供商,如果需要,您可以提供一个自定义函数来刷新令牌。

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

export const auth = betterAuth({
  // Other configurations...
  socialProviders: {
    google: {
      clientId: "YOUR_GOOGLE_CLIENT_ID",
      clientSecret: "YOUR_GOOGLE_CLIENT_SECRET",
      refreshAccessToken: async (token) => {
        return {
          accessToken: "new-access-token",
          refreshToken: "new-refresh-token",
        };
      },
    },
  },
});

clientKey

您的应用程序的客户端密钥。这由 TikTok Social Provider 使用,而不是 clientId

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

export const auth = betterAuth({
  // Other configurations...
  socialProviders: {
    tiktok: {
      clientKey: "YOUR_TIKTOK_CLIENT_KEY",
      clientSecret: "YOUR_TIKTOK_CLIENT_SECRET",
    },
  },
});

getUserInfo

从提供商获取用户信息的自定义函数。这允许您覆盖默认的用户信息检索过程。

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

export const auth = betterAuth({
  // Other configurations...
  socialProviders: {
    google: {
      clientId: "YOUR_GOOGLE_CLIENT_ID",
      clientSecret: "YOUR_GOOGLE_CLIENT_SECRET",
      getUserInfo: async (token) => {
        // Custom implementation to get user info
        const response = await fetch("https://www.googleapis.com/oauth2/v2/userinfo", {
          headers: {
            Authorization: `Bearer ${token.accessToken}`,
          },
        });
        const profile = await response.json();
        return {
          user: {
            id: profile.id,
            name: profile.name,
            email: profile.email,
            image: profile.picture,
            emailVerified: profile.verified_email,
          },
          data: profile,
        };
      },
    },
  },
});

disableImplicitSignUp

禁用新用户的隐式注册。当为提供商设置为 true 时,需要使用 requestSignUp 为 true 来调用登录以创建新用户。

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

export const auth = betterAuth({
  // Other configurations...
  socialProviders: {
    google: {
      clientId: "YOUR_GOOGLE_CLIENT_ID",
      clientSecret: "YOUR_GOOGLE_CLIENT_SECRET",
      disableImplicitSignUp: true,
    },
  },
});

prompt

用于授权码请求的提示。这控制认证流程行为。

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

export const auth = betterAuth({
  // Other configurations...
  socialProviders: {
    google: {
      clientId: "YOUR_GOOGLE_CLIENT_ID",
      clientSecret: "YOUR_GOOGLE_CLIENT_SECRET",
      prompt: "select_account", // or "consent", "login", "none", "select_account+consent"
    },
  },
});

responseMode

用于授权码请求的响应模式。这决定了授权响应如何返回。

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

export const auth = betterAuth({
  // Other configurations...
  socialProviders: {
    google: {
      clientId: "YOUR_GOOGLE_CLIENT_ID",
      clientSecret: "YOUR_GOOGLE_CLIENT_SECRET",
      responseMode: "query", // or "form_post"
    },
  },
});

disableDefaultScope

移除提供商的默认范围。默认情况下,提供商包括像 emailprofile 这样的某些范围。将此设置为 true 以移除这些默认范围,并仅使用您指定的范围。

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

export const auth = betterAuth({
  // Other configurations...
  socialProviders: {
    google: {
      clientId: "YOUR_GOOGLE_CLIENT_ID",
      clientSecret: "YOUR_GOOGLE_CLIENT_SECRET",
      disableDefaultScope: true,
      scope: ["https://www.googleapis.com/auth/userinfo.email"], // Only this scope will be used
    },
  },
});

Other Provider Configurations

每个提供商可能有额外的选项,请查看特定提供商文档以获取更多细节。