payload-zitadel-plugin
v0.2.42
Published
plugin for Payload CMS, which enables authentication via Zitadel IdP
Downloads
473
Readme
payload-zitadel-plugin
plugin for Payload CMS, which enables authentication via Zitadel IdP.
The default use case is to fully replace PayloadCMS Auth with Zitadel. Thus, the user collection in PayloadCMS becomes just a shadow of the information in Zitadel.
:boom: :boom: :boom: works :100: with PayloadCMS version :three: :boom: :boom: :boom:
Install
pnpm add [email protected]
Configuration
Initialize the plugin in Payload Config File. Change the parameters to connect to your Zitadel Instance.
payload.config.ts
import {buildConfig} from 'payload/config'
import {ZitadelPlugin} from 'payload-zitadel-plugin'
export default buildConfig({
...,
plugins: [
ZitadelPlugin({
// URL of your Zitadel instance
issuerUrl: process.env.ZITADEL_URL,
// in Zitadel create a new App->Web->PKCE, then copy the Client ID
clientId: process.env.ZITADEL_CLIENT_ID,
// interpolation text for the Login Button - "sign in with ..."
label: 'Zitadel',
// change field names, field labels and alse hide them if wanted
/*
fieldConfig: {
image: {
name: 'idp_image',
label: 'some custom label'
}
}
*/
// set the name of the CustomStrategy in PayloadCMS - usually not necessary
// strategyName: 'zitadel'
// set to true if you do not want to use the Zitadel Profile Picture as the Avatar
// disableAvatar: true
// set to true if you want to use your own custom login button
// disableDefaultLoginButton: true
// if you want to manually control what happen after a successful login
// state contains all URLSearchParams that were send to /authorize
// onSuccess: (state) => NextResponse.redirect([serverURL, state.get('redirect')].join(''))
// following properties are only needed if you want to authenticate clients for the API
// if you are just using the CMS you can ignore all of them
// in Zitadel create a new App->API->JWT
// enableAPI: true,
// apiClientId: process.env.ZITADEL_API_CLIENT_ID,
// apiKeyId: process.env.ZITADEL_API_KEY_ID,
// apiKey: process.env.ZITADEL_API_KEY
})
],
...
})
Optionally you could use an .env.local
file for parameters:
.env.local
ZITADEL_URL=https://idp.zitadel.url
ZITADEL_CLIENT_ID=123456789012345678@project_name
ZITADEL_API_CLIENT_ID=123456789123456789@project_name
ZITADEL_API_KEY_ID=123456789012345678
ZITADEL_API_KEY='-----BEGIN RSA PRIVATE KEY----- ... ----END RSA PRIVATE KEY-----'
or use the Next.js Config file:
next.config.js
import {withPayload} from '@payloadcms/next/withPayload'
/** @type {import('next').NextConfig} */
const nextConfig = {
env: {
ZITADEL_URL: 'https://idp.zitadel.url',
ZITADEL_CLIENT_ID: '123456789012345678@project_name',
ZITADEL_API_CLIENT_ID: '123456789123456789@project_name',
ZITADEL_API_KEY_ID: '123456789012345678',
ZITADEL_API_KEY: '-----BEGIN RSA PRIVATE KEY----- ... ----END RSA PRIVATE KEY-----'
}
}
export default withPayload(nextConfig)
further configuration
If you want to use the Zitadel profile picture as the avatar in PayloadCMS (disableAvatar != true
),
you have to manually add the asset URL to the Next.js config file.
Also if you want to automatically redirect to Zitadel without asking the user to click on the login button, you have to add the redirect manually to the Next.js config file.
next.config.js
import {withPayload} from '@payloadcms/next/withPayload'
/** @type {import('next').NextConfig} */
const nextConfig = {
// if Avatar enabled:
// allow loading assets like profile pictures from Zitadel
images: {
remotePatterns: [
{
//protocol: new URL(process.env.ZITADEL_URL).protocol,
hostname: new URL(process.env.ZITADEL_URL).hostname,
//port: new URL(process.env.ZITADEL_URL).port,
pathname: '/assets/**'
}
]
},
// optional: enable auto-redirect to Zitadel login page if not logged in
async redirects() {
return [
{
source: '/:path((?:admin|profile).*)',
destination: '/api/users/authorize?redirect=/:path*',
missing: [
{
type: 'cookie',
key: 'zitadel_id_token'
}
],
permanent: false
}
]
}
}
export default withPayload(nextConfig)