-
-
Notifications
You must be signed in to change notification settings - Fork 10.1k
Add New Authentication Providers
LobeChat uses Auth.js v5 as the external authentication service. Auth.js is an open-source authentication library that provides a simple way to implement authentication and authorization features. This document will introduce how to use Auth.js to implement a new authentication provider.
To add a new authentication provider in LobeChat (for example, adding Okta), you need to follow the steps below:
First, you need to check the Auth.js Provider List to see if your provider is already supported. If yes, you can directly use the SDK provided by Auth.js to implement the authentication feature.
Next, I will use Okta as an example to introduce how to add a new authentication provider.
Open the src/app/api/auth/next-auth.ts
file and import next-auth/providers/okta
.
import { NextAuth } from 'next-auth';
import Auth0 from 'next-auth/providers/auth0';
import Okta from 'next-auth/providers/okta';
// Import Okta provider
Add the predefined server configuration.
// Import server configuration
const { OKTA_CLIENT_ID, OKTA_CLIENT_SECRET, OKTA_ISSUER } = getServerConfig();
const nextAuth = NextAuth({
providers: [
// ... Other providers
Okta({
clientId: OKTA_CLIENT_ID,
clientSecret: OKTA_CLIENT_SECRET,
issuer: OKTA_ISSUER,
}),
],
});
Open the src/config/server/app.ts
file and add Okta-related environment variables in the getAppConfig
function.
export const getAppConfig = () => {
// ... Other code
return {
// ... Other environment variables
OKTA_CLIENT_ID: process.env.OKTA_CLIENT_ID || '',
OKTA_CLIENT_SECRET: process.env.OKTA_CLIENT_SECRET || '',
OKTA_ISSUER: process.env.OKTA_ISSUER || '',
};
};
Modify the signIn
function parameter in src/Features/Conversation/Error/OAuthForm.tsx
and `src/app/settings/common/Common.tsx
The default is auth0
, which you can change to okta
to switch to the Okta provider, or remove this parameter to support all added authentication services
This value is the id of the Auth.js provider, and you can read the source code of the corresponding next-auth/providers
module to read the default ID.
Add OKTA_CLIENT_ID
、OKTA_CLIENT_SECRET
、OKTA_ISSUER
environment variables when you deploy.
Use the useOAuthSession()
method in the frontend page to get the user information user
returned by the backend:
import { useOAuthSession } from '@/hooks/useOAuthSession';
const { user, isOAuthLoggedIn } = useOAuthSession();
The default type of user
is User
, and the type definition is:
interface User {
id?: string;
name?: string | null;
email?: string | null;
image?: string | null;
}
The user.id
is used to identify users. When introducing a new OAuth identity provider, you need to handle the information carried in the OAuth callback in src/app/api/auth/next-auth.ts
. You need to select the user's id
from this information. Before that, we need to understand the data processing sequence of Auth.js
:
authorize --> jwt --> session
By default, in the jwt --> session
process, Auth.js
will automatically assign the user id
to account.providerAccountId
based on the login type. If you need to select a different value as the user id
, you need to implement the following handling logic:
callbacks: {
async jwt({ token, account, profile }) {
if (account) {
// You can select a different value from `account` or `profile`
token.userId = account.providerAccountId;
}
return token;
},
},
If you want to carry more information about profile
and account
in the session
, according to the data processing order mentioned above in Auth.js
, you must first copy this information to the token
. For example, add the user avatar URL profile.picture
to the session
:
callbacks: {
async jwt({ token, profile, account }) {
if (profile && account) {
token.userId = account.providerAccountId;
+ token.avatar = profile.picture;
}
return token;
},
async session({ session, token }) {
if (session.user) {
session.user.id = token.userId ?? session.user.id;
+ session.user.avatar = token.avatar;
}
return session;
},
},
Then supplement the type definition for the new parameters:
declare module '@auth/core/jwt' {
interface JWT {
// ...
avatar?: string;
}
}
declare module 'next-auth' {
interface User {
avatar?: string;
}
}
If you have configured multiple authentication providers and their userId
mappings are different, you can use the account.provider
parameter in the jwt
method to get the default id of the identity provider and enter different processing logic.
callbacks: {
async jwt({ token, profile, account }) {
if (profile && account) {
if (account.provider === 'authing')
token.userId = account.providerAccountId ?? token.sub;
else if (acount.provider === 'auth0')
token.userId = profile.sub ?? token.sub;
else
// other providers
}
return token;
},
}
Now, you can use Okta as your provider to implement the authentication feature in LobeChat.
This is the 🤯 / 🤖 Lobe Chat wiki. Wiki Home
- Architecture Design | 架构设计
- Code Style and Contribution Guidelines | 代码风格与贡献指南
- Complete Guide to LobeChat Feature Development | LobeChat 功能开发完全指南
- Conversation API Implementation Logic | 会话 API 实现逻辑
- Directory Structure | 目录架构
- Environment Setup Guide | 环境设置指南
- How to Develop a New Feature | 如何开发一个新功能:前端实现
- New Authentication Provider Guide | 新身份验证方式开发指南
- Resources and References | 资源与参考
- Technical Development Getting Started Guide | 技术开发上手指南
- Testing Guide | 测试指南