OAuth

Better Auth는 OAuth 2.0과 OpenID Connect에 대한 내장 지원을 제공합니다. 이를 통해 Google, Facebook, GitHub 등 인기 있는 OAuth 제공자를 통해 사용자를 인증할 수 있습니다.

원하는 제공자가 직접 지원되지 않는 경우 커스텀 통합을 위해 Generic OAuth 플러그인을 사용할 수 있습니다.

소셜 제공자 설정하기

소셜 제공자를 활성화하려면 해당 제공자의 clientIdclientSecret을 제공해야 합니다.

다음은 Google을 제공자로 설정하는 예제입니다:

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

export const auth = betterAuth({
  // 기타 설정...
  socialProviders: {
    google: {
      clientId: "YOUR_GOOGLE_CLIENT_ID",
      clientSecret: "YOUR_GOOGLE_CLIENT_SECRET",
    },
  },
});

사용법

로그인

소셜 제공자로 로그인하려면 authClient와 함께 signIn.social 함수를 사용하거나 서버 측 사용을 위해 auth.api를 사용할 수 있습니다.

// 클라이언트 측 사용
await authClient.signIn.social({
  provider: "google", // 또는 다른 제공자 id
})
// 서버 측 사용
await auth.api.signInSocial({
  body: {
    provider: "google", // 또는 다른 제공자 id
  },
});

계정 연결

소셜 제공자에 계정을 연결하려면 authClient와 함께 linkAccount 함수를 사용하거나 서버 측 사용을 위해 auth.api를 사용할 수 있습니다.

await authClient.linkSocial({
  provider: "google", // 또는 다른 제공자 id
})

서버 측 사용:

await auth.api.linkSocialAccount({
  body: {
    provider: "google", // 또는 다른 제공자 id
  },
  headers: // 인증된 토큰이 포함된 헤더 전달
});

Access Token 가져오기

소셜 제공자의 access token을 가져오려면 authClient와 함께 getAccessToken 함수를 사용하거나 서버 측 사용을 위해 auth.api를 사용할 수 있습니다. 이 엔드포인트를 사용하면 access token이 만료된 경우 새로고침됩니다.

const { accessToken } = await authClient.getAccessToken({
  providerId: "google", // 또는 다른 제공자 id
  accountId: "accountId", // 선택 사항, 특정 계정의 access token을 가져오려는 경우
})

서버 측 사용:

await auth.api.getAccessToken({
  body: {
    providerId: "google", // 또는 다른 제공자 id
    accountId: "accountId", // 선택 사항, 특정 계정의 access token을 가져오려는 경우
    userId: "userId", // 선택 사항, 인증된 토큰이 포함된 헤더를 제공하지 않는 경우
  },
  headers: // 인증된 토큰이 포함된 헤더 전달
});

제공자가 제공한 계정 정보 가져오기

제공자별 계정 정보를 가져오려면 authClient와 함께 accountInfo 함수를 사용하거나 서버 측 사용을 위해 auth.api를 사용할 수 있습니다.

const info = await authClient.accountInfo({
  accountId: "accountId", // 여기에 제공자가 제공한 계정 id를 전달하면, 계정 id에서 제공자가 자동으로 감지됩니다
})

서버 측 사용:

await auth.api.accountInfo({
  body: { accountId: "accountId" },
  headers: // 인증된 토큰이 포함된 헤더 전달
});

추가 Scope 요청하기

사용자가 이미 가입한 후에 애플리케이션에 추가 OAuth scope가 필요한 경우가 있습니다 (예: GitHub 저장소 또는 Google Drive 접근). 사용자는 처음에 광범위한 권한을 부여하고 싶지 않을 수 있으며, 최소한의 권한으로 시작하고 필요에 따라 추가 접근 권한을 부여하는 것을 선호합니다.

같은 제공자로 linkSocial 메서드를 사용하여 추가 scope를 요청할 수 있습니다. 이렇게 하면 기존 계정 연결을 유지하면서 추가 scope를 요청하는 새로운 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 같은)은 추가 scope를 위해 기존 제공자와 연결을 시도할 때 "소셜 계정이 이미 연결되어 있습니다" 오류를 표시할 수 있습니다.

제공자 옵션

scope

접근 요청의 scope. 예를 들어 email 또는 profile.

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

export const auth = betterAuth({
  // 기타 설정...
  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({
  // 기타 설정...
  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({
  // 기타 설정...
  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 플러그인을 통해 구성된 커스텀 OAuth 제공자에는 지원되지 않습니다. 내장 제공자의 경우 필요한 경우 토큰을 새로고침하기 위한 커스텀 함수를 제공할 수 있습니다.

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

export const auth = betterAuth({
  // 기타 설정...
  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

애플리케이션의 클라이언트 키. clientId 대신 TikTok 소셜 제공자가 사용합니다.

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

export const auth = betterAuth({
  // 기타 설정...
  socialProviders: {
    tiktok: {
      clientKey: "YOUR_TIKTOK_CLIENT_KEY",
      clientSecret: "YOUR_TIKTOK_CLIENT_SECRET",
    },
  },
});

getUserInfo

제공자로부터 사용자 정보를 가져오기 위한 커스텀 함수. 이를 통해 기본 사용자 정보 검색 프로세스를 재정의할 수 있습니다.

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

export const auth = betterAuth({
  // 기타 설정...
  socialProviders: {
    google: {
      clientId: "YOUR_GOOGLE_CLIENT_ID",
      clientSecret: "YOUR_GOOGLE_CLIENT_SECRET",
      getUserInfo: async (token) => {
        // 사용자 정보를 가져오기 위한 커스텀 구현
        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({
  // 기타 설정...
  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({
  // 기타 설정...
  socialProviders: {
    google: {
      clientId: "YOUR_GOOGLE_CLIENT_ID",
      clientSecret: "YOUR_GOOGLE_CLIENT_SECRET",
      prompt: "select_account", // 또는 "consent", "login", "none", "select_account+consent"
    },
  },
});

responseMode

인증 코드 요청에 사용할 응답 모드. 인증 응답이 반환되는 방식을 결정합니다.

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

export const auth = betterAuth({
  // 기타 설정...
  socialProviders: {
    google: {
      clientId: "YOUR_GOOGLE_CLIENT_ID",
      clientSecret: "YOUR_GOOGLE_CLIENT_SECRET",
      responseMode: "query", // 또는 "form_post"
    },
  },
});

disableDefaultScope

제공자의 기본 scope를 제거합니다. 기본적으로 제공자는 emailprofile 같은 특정 scope를 포함합니다. 이를 true로 설정하면 이러한 기본 scope를 제거하고 지정한 scope만 사용합니다.

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

export const auth = betterAuth({
  // 기타 설정...
  socialProviders: {
    google: {
      clientId: "YOUR_GOOGLE_CLIENT_ID",
      clientSecret: "YOUR_GOOGLE_CLIENT_SECRET",
      disableDefaultScope: true,
      scope: ["https://www.googleapis.com/auth/userinfo.email"], // 이 scope만 사용됩니다
    },
  },
});

기타 제공자 설정

각 제공자에는 추가 옵션이 있을 수 있으며, 자세한 내용은 특정 제공자 문서를 확인하세요.