ろぼいんブログ

Payload CMSでパスキーを使えるようにする「payload-passkey」を公開しました

Payload CMSでパスキーを使ったパスワードレスログインができるようにする「payload-passkey」を公開しました。この記事では、payload-passkeyの特徴や使い方について紹介します。

目次

開発の経緯

Payload CMSは素晴らしいCMSですが、標準ではメールアドレスとパスワードによるログインにしか対応していないため、二要素認証やパスキーなどを利用したい場合はサードパーティのプラグインを利用する必要があります。

広告

筆者はもともと、TOTPの二要素認証を追加するPayload TOTPというプラグインを利用していました。これは、Payload CMSの標準のログイン画面でメールアドレスとパスワードを入力したあとに、ワンタイムパスワードを入力する画面に遷移するようにするプラグインです。

Payload TOTPは非常によくできておりしばらく使っていたのですが、ログインのたびに認証アプリを開いてワンタイムパスワードを入力することを手間に感じ始めました。

そこで、パスキーの導入を検討し始めました。Payload CMS向けの既存のプラグインではパスキーにフォーカスしたものがなく、基本的にはBetter Authのプラグインを使うことになります。

私が求めていた条件として、次のような条件が挙げられます。

  • 互換性とデザインの観点から、Payload CMSの既存の認証戦略を維持する
  • Payload TOTPと共存可能
  • パスワードはPayload CMSのデフォルトの認証戦略、TOTPはPayload TOTP、パスキーはBetter Authを使う
  • (メールアドレス AND パスワード AND TOTP) OR パスキーでログイン可能

Payload CMSでBetter Authを利用できるようにする主要なプラグインとしては次のようなものが挙げられますが、既存のプラグインはどれも私のユースケースに合いませんでした。

このように既存のいずれのプラグインも私の求める条件を満たしていませんでした。

広告

しかし、@delmaredigital/payload-better-authはBetter Authのデータベースアダプターを個別にエクスポートしており、これをラップする形で私の条件に合うプラグインを開発できることが判明しました。そこで開発したのが、payload-passkeyです。

payload-passkeyの特徴

payload-passkeyは、Payload CMSのデフォルトのログイン画面にパスキーでログインするボタンを追加し、アカウント管理画面からパスキーを管理できるようにします。payload-passkeyには、次のような特徴があります。

  • Payload CMSのデフォルトのログイン画面にパスキーでログインするボタンを追加
  • アカウントの管理画面にパスキー管理機能を追加
  • Payload CMS側の設定で有効な場合、トークンの自動リフレッシュをサポート
  • Payload TOTPと併用可能
  • パスキーのオートフィルに対応
  • i18nサポート
  • Payload CMSのUIコンポーネントを使用しており、ダッシュボードに馴染むデザイン

payload-passkeyを有効化すると、ログイン画面に画像のようにパスキーでログインするボタンが追加されます。

Payload CMSのログイン画面の下部に[Login with a passkey]ボタンが追加されているようすのスクリーンショット

アカウントの管理画面にはパスキーを管理するセクションが追加されます。

Payload CMSのアカウントの管理画面にパスキーを管理するセクションが追加されているようすのスクリーンショット

payload-passkeyの使い方

payload-passkeyを使うにはまず、パッケージをインストールします。

広告
Terminal window
pnpm add payload-passkey

次に、環境変数BETTER_AUTH_SECRETに32に文字以上のランダムな文字列を設定します。

.env
BETTER_AUTH_SECRET=your-secret-key-longer-than-32-characters

payload.config.tsでpayload-passkeyをプラグインとして追加します。このとき、ユーザーの情報を格納しているコレクションのスラッグをpayload-passkeyのuserCollectionに設定してください。また、modelNameuserCollectionから末尾の「s」を取り除いたものに設定します。

payload.config.ts
import { buildConfig } from "payload";
import { payloadPasskey } from "payload-passkey";
const config = buildConfig({
collections: [
{
slug: "users",
auth: true,
fields: [...],
},
],
plugins: [
payloadPasskey({
rpID: "your-domain.example.com",
rpName: "Example App",
origin: "https://your-domain.example.com",
modelName: "user",
userCollection: "users",
baseURL: "https://your-domain.example.com",
secret: process.env.BETTER_AUTH_SECRET,
trustedOrigins: ["https://your-domain.example.com"],
generateId: "serial",
firstUserAdmin: true,
enablePasskeyAutofill: true
})
]
});
export default config;

Payload TOTPと併用したい場合は、次のようにします。

payload.config.ts
import { buildConfig } from "payload";
import { payloadPasskey } from "payload-passkey";
const config = buildConfig({
collections: [
{
slug: "users",
auth: true,
fields: [...],
},
],
plugins: [
payloadPasskey({
enableTotpCompatibility: true,
rpID: "your-domain.example.com",
rpName: "Example App",
origin: "https://your-domain.example.com",
modelName: "user",
userCollection: "users",
baseURL: "https://your-domain.example.com",
secret: process.env.BETTER_AUTH_SECRET,
trustedOrigins: ["https://your-domain.example.com"],
generateId: "serial",
firstUserAdmin: true,
enablePasskeyAutofill: true
}),
// `payloadTotp()` must be called after `payloadPasskey()`;
// otherwise, the collection generated by payload-passkey won't be protected by Payload TOTP.
payloadTotp({
collection: "users",
totp: {
issuer: "Example App"
}
})
]
});
export default config;

あとは、データベースのマイグレーションを実行すればPayload CMSでパスキーを利用できるようになります。

Terminal window
npm run payload migrate:create
npm run payload migrate

まとめ

Payload CMSのデフォルトの認証戦略やPayload TOTPとの互換性を維持しつつ、パスキーのサポートを追加できるpayload-passkeyを公開しました。

広告

ソースコードはGitHubで公開しているので、バグなどがありましたらissueやPRをぜひ送ってください!

記事をシェア

フォローして最新情報を入手

Googleの優先ソースに追加すると、このサイトの記事をGoogleで見つけやすくなります。また、ぜひXやRSSフィードもフォローしてください。

Googleの優先ソースとして追加するGoogleの優先ソースとして追加する
著者のアイコン画像

生まれた時から、母国語よりも先にJavaScriptを使っていました。ネットの海のどこにもいなくてどこにでもいます。

Webフロントエンドプログラマーとして、TypeScriptを用いたWebアプリやブラウザー拡張機能を制作。Xのシャドウバン検知ツール「Shadowban Scanner」やリンクカード復活ツール「Restore Link Card」を公開し、国内外のメディアで紹介されました。iGEM 2023ではJapan-UnitedチームのWikiを制作してGrand Prizeの獲得に貢献。ブログではXやSNSの最新ニュース、不具合の検証と対処法、フロントエンド開発の知見を発信しています。