User management
Understanding how user information is handled by light-auth.
User Object Overview
The user
object is a core component of Light-Auth that stores complete user information retrieved from authentication providers.
It extends the session
object, inheriting its essential authentication properties while adding additional metadata from the JWT token.
Inheritance Structure
Properties
Inherited from Session
- userIdUser's unique identifier
- nameUser's display name
- emailUser's email address
- providerNameName of the authentication provider
User-specific Properties
The properties below are specific to the User object and are not inherited from the Session object. They contain additional metadata and information about the user.
Be careful, these properties depends on the authentication provider used. For example, the picture
property may not be available for all providers.
refreshToken
is only retrieved if the provider supports it, and is configured for offline access. If not, it will be undefined
.
- pictureURL to user's profile picture
- accessTokenOAuth access token for API calls
- accessTokenExpiresAtExpiration timestamp for access token
- refreshTokenToken used to refresh the access token
NOT Inherited from Session
Certain session-specific properties, such as id
and expiresAt
, exist only for the duration of the session and are not passed on to the User object:
- idSession Id
- expiresAtSession expiration timestamp
User Object Example
{
// Inherited from Session
"userId": "user_123456",
"name": "John Doe",
"email": "john.doe@example.com",
"providerName": "google",
// User-specific properties
"picture": "https://example.com/profile.jpg",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"accessTokenExpiresAt": "2023-06-30T23:59:59Z",
"refreshToken": "rt_abcdefghijklmnopqrstuvwxyz",
// Provider-specific data
"firstName": "John",
"lastName": "Doe",
"locale": "en-US"
}
Configuration
Add the user adapter to your config and retrieve it from your page.
Add User Adapter to your configuration
userAdapter
property in your configuration.While the code is redundant—since this behavior occurs by default—it is included to highlight how to explicitly set a user adapter.
export const { providers, handlers, signIn, signOut, getAuthSession, getUser } =
CreateLightAuth({
providers: [googleProvider, microsoftProvider],
userAdapter: createLightAuthUserAdapter({ base: "./users_db", isEncrypted: false })
})
Retrieving the user object from your web application
Like the session object, the user object is easily accessible using the getUser()
method.
import { getAuthSession, getUser } from "@/lib/auth";
import { Avatar, AvatarImage } from "./ui/avatar";
export default async function Home() {
const session = await getAuthSession();
const user = await getUser();
return (
<div>
{session != null ? (
<div>
<p>✅ You are logged in!</p>
{user != null && (
<Avatar className="h-8 w-8">
<AvatarImage src={user.picture} alt={user.name} />
</Avatar>
)}
</div>
) : (
<div>
<p>⚠️ You are not logged in</p>
<a href="/login"> Go to Login Page </a>
</div>
)}
</div>
);
}
Add custom User properties
You can add custom properties to the User object by:
- 1Extending the
User
object with a custom interface - 2Using the
onUserSaving
function in the configuration.
Here is an example where we get additional properties from the id token and add them to the user object.
Add some custom properties to the user object by extending the user interface:
import { LightAuthSession, LightAuthUser } from "@light-auth/core";
export type MyLightAuthUser = LightAuthUser<LightAuthSession> & {
// Add any additional properties you want to include in your custom user type
email_verified?: boolean;
iss?: string;
sub?: string;
};
Get custom properties from the authentication providers:
Add the custom properties values to the user object by using the onUserSaving
function in the configuration:
export const { providers, handlers, signIn, signOut, getAuthSession, getUser } =
CreateLightAuth<LightAuthSession, MyLightAuthUser>({
providers: [googleProvider, microsoftProvider],
onUserSaving: async (user, tokens) => {
if (!tokens) return user;
if (!tokens.idToken()) return user;
// optional: Add custom claims to the user
const idToken = JSON.parse(Buffer.from(tokens.idToken().split(".")[1], "base64").toString());
if ("iss" in idToken && typeof idToken.iss === "string") user.iss = idToken.iss;
if ("email_verified" in idToken && typeof idToken.email_verified === "boolean") user.email_verified = idToken.email_verified;
if ("sub" in idToken && typeof idToken.sub === "string") user.sub = idToken.sub;
return user;
},
});
The UserAdapter
The UserAdapter is an abstract class that defines how User objects are stored and retrieved in Light-Auth. It provides a consistent interface for different storage backends, allowing you to choose the most appropriate storage solution for your application.
Built-in Adapters
FileUserAdapter
Stores user data in JSON files on the server's file system.
- Simple setup with no additional dependencies
- Good for development or small applications
- Not suitable for distributed environments
DatabaseUserAdapter
Stores user data in a database through a configurable database connector.
- Scalable and suitable for production
- Works with various database backends
- Supports distributed environments
UserAdapter Interface
The UserAdapter abstract class defines the following methods that must be implemented by any concrete adapter:
export interface LightAuthUserAdapter {
getUser: (args: { config: LightAuthConfig; userId: string; [key: string]: unknown }) => LightAuthUser | null | Promise<LightAuthUser | null>;
setUser: (args: { config: LightAuthConfig; user: LightAuthUser; [key: string]: unknown }) => Promise<void>;
deleteUser: (args: { config: LightAuthConfig; user: LightAuthUser; [key: string]: unknown }) => Promise<void>;
}