A Payload CMS 3 (beta) plugin for integrating Auth.js 5 (beta).
âš This plugin is in beta and under construction. Payload CMS 3 and Auth.js 5 are also in beta.
Install the plugin using any JavaScript package manager like PNPM, NPM, or Yarn:
pnpm i payload-authjs
Fist of all, setup Auth.js like you would do in a Next.js application. You can follow the Auth.js documentation.
âš Make sure you define your config in a separate file (e.g.
auth.config.ts
) than where you create the NextAuth instance (e.g.auth.ts
) to avoid circular dependencies. âš
// auth.config.ts
import github from "next-auth/providers/github";
export const authConfig: NextAuthConfig = {
providers: [
github, // <-- Add your provider here
],
};
Wrap your Auth.js configuration with the withPayload
function before creating the NextAuth instance:
// auth.ts
import payloadConfig from "@payload-config";
import NextAuth from "next-auth";
import { withPayload } from "payload-authjs";
import { authConfig } from "./auth.config"; // âš Import the config from a separate file
export const { handlers, signIn, signOut, auth } = NextAuth(
withPayload(authConfig, {
payloadConfig,
}),
);
Add the authjsPlugin
in your Payload configuration file:
// payload.config.ts
import { authjsPlugin } from "payload-authjs";
import { authConfig } from "./auth.config";
export const config = buildConfig({
plugins: [
authjsPlugin({
authjsConfig: authConfig,
}),
],
});
And that's it! Now you can sign-in via Auth.js and you are automatically authenticated in Payload CMS. Nice 🎉
You don't need to create a collection for users. This plugin automatically creates a collection with the slug users
.
But if you want to customize the users collection, you can create a collection with the slug users
and add the fields you need.
// users.ts
import type { CollectionConfig } from "payload";
const Users: CollectionConfig = {
slug: "users",
fields: [
{
name: "roles",
type: "json",
},
],
};
export default Users;
Next, you need to extend the user object returned by your Auth.js provider. You can do this like this example:
const authConfig: NextAuthConfig = {
providers: [
github({
profile(profile) {
return {
id: profile.id.toString(),
name: profile.name,
email: profile.email,
image: profile.avatar_url,
roles: ["user"], // <-- Extend the user object with a custom field
};
},
}),
],
...
};
âš Keep in mind that Auth.js doesn't update the user after the first sign-in. If you want to update the user on every sign-in, you can use the updateUserOnSignIn
option in the withPayload
function:
// auth.ts
export const { handlers, signIn, signOut, auth } = NextAuth(
withPayload(authConfig, {
payloadConfig,
updateUserOnSignIn: true, // <-- Update the user on every sign-in
}),
);
Now you could access your custom field, e.g. in the access control operations:
const Examples: CollectionConfig = {
slug: "examples",
access: {
read: ({ req: { user } }) => {
return user?.roles?.includes("user") ?? false; // <-- Check if the user has the role "user"
},
},
fields: [
...
],
};
This plugin also export a utility function to get the current payload user
// ServerComponentExample.tsx
const ServerComponentExample = async () => {
const payloadUser = await getPayloadUser();
return (
<div>
<h3>Payload CMS User</h3>
<div>{JSON.stringify(payloadUser)}</div>
</div>
);
};