Open5
NextAuth.js を触ってみる
NextAuth.js
- OAuth service, it supports OAuth 1.0, 1.0A, 2.0 and OpenID Connect をサポート
- 多くの認証プロバイダーをサポート
- 電子メール、パスワードレス認証をサポート
- Active Directory、LDAP などのステートレス認証をサポート
- JWT や データベースセッションをサポート
- AWS Lambda、Docker、Heroku などのサーバーレス環境で動作するように設計されている
- MySQL, MariaDB, Postgres, SQL Server, MongoDB and SQLite をビルトインサポート
- データベースなしでも仕様可能
- あらゆるデータベースと併用可能
- デフォルトでセキュア
Next.js に NextAuth.js を組み込む
-
pages/api/auth
に[...nextauth].js
を作成する
import NextAuth from "next-auth"
import GithubProvider from "next-auth/providers/github"
export default NextAuth({
// Configure one or more authentication providers
providers: [
GithubProvider({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
// ...add more providers here
],
})
上記ルーティングにファイルを置くことで、api/auth/*
へのすべてのリクエスト(signIn、callback、signOutなど)は、自動的に NextAuth.js によって処理されるようになります。
認証プロバイダを追加する方法について
一般的な OAuth のフロー
ビルトイン OAuth 認証プロバイダーの使い方
- 該当の認証プロバイダーの開発者ポータルでアプリケーションを登録する
- リダイレクト URL は
/api/auth/callback/[provider]
のフォーマットに従う- Twitter の場合 e.g. http://localhost:3000/api/auth/callback/twitter
- Google の場合 e.g. https://next-auth-example.vercel.app/api/auth/callback/google
- .env ファイルをルートに作成する
TWITTER_ID=YOUR_TWITTER_CLIENT_ID
TWITTER_SECRET=YOUR_TWITTER_CLIENT_SECRET
-
pages/api/auth/[...nextauth].js
に使用したい認証プロバイダーを追加する
import TwitterProvider from "next-auth/providers/"
...
providers: [
TwitterProvider({
clientId: process.env.TWITTER_ID,
clientSecret: process.env.TWITTER_SECRET
})
],// 配列に認証プロバイダーを追加する
...
- プロバイダーの設定が完了すると、
/api/auth/signin
でサインインすることができる
Twitter 認証を行う例
該当の認証プロバイダーの開発者ポータルでアプリケーションを登録する
Twitter の場合は、Developer Portal 上からアプリを作成できる
-
process.env.TWITTER_ID つまり clientId
は API Key -
process.env.TWITTER_SECRET つまり clientSecret
は API Key Secret
を設定する
リダイレクト URL は /api/auth/callback/[provider] のフォーマットに従う
callback 先は、ローカル環境の Next.js の URL を設定する
http://localhost:3000/api/auth/callback/twitter
callback 先を設定するには、3-legged OAuth
を有効にする必要がある
pages/api/auth/[...nextauth].ts に使用したい認証プロバイダーを追加する
export default NextAuth({
providers: [
Providers.Twitter({
clientId: process.env.TWITTER_CLIENT_ID,
clientSecret: process.env.TWITTER_CLIENT_SECRET
})
],
})
プロバイダーの設定が完了すると、/api/auth/signin でサインインすることができる
import {signIn, signOut, useSession} from "next-auth/client";
// 略
<Button onClick={()=>signIn()}>ログイン</Button>
siginIn()
すると NextAuth のログイン画面を経由して、Twitter のログイン画面が表示される
ユーザーから見た画面遷移
const [session, loading] = useSession();
console.log(session);
認証を通すと、session
から以下のようなユーザー情報が取得できる
{
"user": {
"name": "izuchy | UI でワクワクしたいエンジニア",
"email": null,
"image": "https://pbs.twimg.com/profile_images/1460468685269733379/tvbUktX1.png"
},
"expires": "2021-12-25T06:30:36.608Z"
}
LINE 認証を行う例
アプリの作成
から LINE ログインのアプリを作成する
Provider の追加
pages/api/auth/[...nextauth].ts
に LINE の Provider を追加する
export default NextAuth({
providers: [
Providers.LINE({
clientId: process.env.LINE_CLIENT_ID,
clientSecret: process.env.LINE_CLIENT_SECRET
})
],
})
.env の設定
- LINE_CLIENT_ID は チャネルID
- LINE_CLIENT_SECRET は チャネルシークレット
を設定する
LINE ログインする
<Button onClick={()=>signIn("line")}>LINE ログイン</Button>
LINE のログイン画面が表示され許可すると、ログインできる
認証を通すと、session から以下のようなユーザー情報が取得できる
{
"user": {
"name": "Izuchi Takahiro",
"email": null,
"image": "https://profile.line-scdn.net/ch/v2/p/u4389e516fcb74cde112e54b1eea25fe9/1350387500003"
},
"expires": "2021-12-25T07:53:16.489Z"
}
REST API で使われている各エンドポイントについて
GET /api/auth/signin
- サインイン画面を表示する
POST /api/auth/signin/:provider
- 指定したプロバイダーの OAuth のサインインを開始
-
/api/auth/csrf
で取得した CSRF トークンが必要
GET /api/auth/callback/:provider
- OAuth の認証プロバイダーから返ってくるリクエストを処理する
- state オプションをサポートしている OAuth 2.0 プロバイダの場合、state パラメーターはサインインフローが開始されたときのものと照合する
GET /api/auth/signout
- サインアウトページを表示する
POST /api/auth/signout
- サインアウトとの処理
- 悪意のあるリンクでユーザーの同意無しにサインアウトが行われることを防ぐための POST リクエスト
-
/api/auth/csrf
で取得した CSRF トークンが必要
GET /api/auth/session
- セッションオブジェクトを応答する
- 応答されるセッションオブジェクトの内容は callback の設定で設定可能
GET /api/auth/csrf
- CSRF トークンを返す
- NextAuth.js は、すべての認証ルートに CSRF 対策が行われている
- 「ダブルサブミットクッキー方式」という方法
- 署名入り HTTPOnly、ホストオンリーのクッキーを使用
- CSRF トークンは POST 送信時に
csrfToken
というフォーム変数で渡す必要がある
GET /api/auth/providers
- 設定されている OAuth のサービスリスト、サービスの詳細(サインインやコールバック URL)などを返す
- 動的にカスタムサインアップページを作ったり、設定されているコールバック URL の確認が可能