docs/development/basic/add-new-authentication-providers.mdx
LobeHub uses Better Auth as the external authentication service. Better Auth is an open-source authentication library that provides a simple way to implement authentication and authorization features. This document will introduce how to use Better Auth to implement a new authentication provider.
To add a new authentication provider in LobeHub (for example, adding GitLab), you need to follow the steps below:
| Type | Description | Examples |
|---|---|---|
builtin | Providers natively supported by Better Auth | Google, GitHub, Microsoft, Apple |
generic | Implemented via Generic OIDC/OAuth plugin | Auth0, Keycloak, Okta, etc. |
Using GitLab as an example (not yet implemented in the codebase), here's how to add a generic type provider.
Create gitlab.ts in src/libs/better-auth/sso/providers/:
import { authEnv } from '@/envs/auth';
import { buildOidcConfig } from '../helpers';
import type { GenericProviderDefinition } from '../types';
const provider: GenericProviderDefinition<{
AUTH_GITLAB_ID: string;
AUTH_GITLAB_ISSUER: string;
AUTH_GITLAB_SECRET: string;
}> = {
// Build OIDC configuration
build: (env) =>
buildOidcConfig({
clientId: env.AUTH_GITLAB_ID,
clientSecret: env.AUTH_GITLAB_SECRET,
issuer: env.AUTH_GITLAB_ISSUER,
overrides: {
// Optional: customize user profile mapping
mapProfileToUser: (profile) => ({
email: profile.email,
name: profile.name ?? profile.preferred_username ?? profile.email ?? profile.sub,
}),
},
providerId: 'gitlab',
}),
// Environment variable validation
checkEnvs: () => {
return !!(authEnv.AUTH_GITLAB_ID && authEnv.AUTH_GITLAB_SECRET && authEnv.AUTH_GITLAB_ISSUER)
? {
AUTH_GITLAB_ID: authEnv.AUTH_GITLAB_ID,
AUTH_GITLAB_ISSUER: authEnv.AUTH_GITLAB_ISSUER,
AUTH_GITLAB_SECRET: authEnv.AUTH_GITLAB_SECRET,
}
: false;
},
// Provider ID (used in AUTH_SSO_PROVIDERS)
id: 'gitlab',
type: 'generic',
};
export default provider;
Import and register in src/libs/better-auth/sso/index.ts:
// Import provider
import GitLab from './providers/gitlab';
// Add to providerDefinitions array
const providerDefinitions = [
// ... other providers
GitLab,
] as const;
Add type declarations in packages/env/src/auth.ts:
// Add to ProcessEnv interface
AUTH_GITLAB_ID?: string;
AUTH_GITLAB_SECRET?: string;
AUTH_GITLAB_ISSUER?: string;
// Add to getAuthConfig server schema
AUTH_GITLAB_ID: z.string().optional(),
AUTH_GITLAB_SECRET: z.string().optional(),
AUTH_GITLAB_ISSUER: z.string().optional(),
// Add to runtimeEnv
AUTH_GITLAB_ID: process.env.AUTH_GITLAB_ID,
AUTH_GITLAB_SECRET: process.env.AUTH_GITLAB_SECRET,
AUTH_GITLAB_ISSUER: process.env.AUTH_GITLAB_ISSUER,
Add provider documentation in docs/self-hosting/auth.mdx and docs/self-hosting/auth.zh-CN.mdx.
For providers natively supported by Better Auth (e.g., Discord), the steps differ slightly:
import { authEnv } from '@/envs/auth';
import type { BuiltinProviderDefinition } from '../types';
const provider: BuiltinProviderDefinition<{
AUTH_DISCORD_ID: string;
AUTH_DISCORD_SECRET: string;
}> = {
build: (env) => ({
clientId: env.AUTH_DISCORD_ID,
clientSecret: env.AUTH_DISCORD_SECRET,
}),
checkEnvs: () => {
return !!(authEnv.AUTH_DISCORD_ID && authEnv.AUTH_DISCORD_SECRET)
? {
AUTH_DISCORD_ID: authEnv.AUTH_DISCORD_ID,
AUTH_DISCORD_SECRET: authEnv.AUTH_DISCORD_SECRET,
}
: false;
},
id: 'discord',
type: 'builtin',
};
export default provider;
Add to src/libs/better-auth/constants.ts:
export const BUILTIN_BETTER_AUTH_PROVIDERS = [
'apple',
'google',
'github',
'cognito',
'microsoft',
'discord', // Add new provider
] as const;
When configuring OAuth applications, use these callback URL formats:
https://yourdomain.com/api/auth/callback/{providerId}https://yourdomain.com/api/auth/callback/{providerId}After configuring environment variables, enable in AUTH_SSO_PROVIDERS:
AUTH_SSO_PROVIDERS=google,github,gitlab
AUTH_GITLAB_ID=your-client-id
AUTH_GITLAB_SECRET=your-client-secret
AUTH_GITLAB_ISSUER=https://gitlab.example.com
Now, you can use GitLab as your provider to implement the authentication feature in LobeHub.