🔐
NextAuthを試す
NextAuth
Authentication for Next.js
各Version
"next": "13.0.6",
"next-auth": "^4.18.6",
パッケージインストール
yarn add next-auth
簡単なサンプル実装
今回はGoogle認証を試して見たいと思います。
Google側のキー取得や設定
OAuth 同意画面の設定
- Google API Console から「OAuth 同意画面」を選択
- 今回はテスト用なので外部を選択し作成
- アプリの情報を設定します
- スコープの設定はそのままで次に進みます
参考URL
クライアントIDとクライアントシークレットを取得
- Google API Console から「認証情報」を選択
- 「認証情報を作成」>「OAuth クライアント ID」を選択
- アプリケーションの種類は「ウェブアプリケーション」を選択
- 名前を適当な名前に設定
- リダイレクトURIは
http://localhost:3000/api/auth/callback/google
を設定
作成するとクライアントIDとクライアントシークレットが表示されるので保存しておきます。
API route を追加
pages/api/auth/[...nextauth].ts
を以下内容で作成します。
import NextAuth from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';
export default NextAuth({
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID ?? '',
clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? '',
}),
],
session: { strategy: 'jwt' },
});
各Providerに関してはこちら参照
GoogleのOAuth2.0に関連するドキュメントはこちら
callbacksに関して
呼ばれる順番
- signIn
- jwt
- redirect
- session
signIn後に特定のページに遷移させる方法
-
signIn()
の第二引数のcallbackUrl
に特定のページを設定 - ただし
redirect
を設定しているとそちらが優先されるので、必要ない場合は削除しとく
sessionに関して
- strategy
- デフォルトは
jwt
- デフォルトは
_app.tsxにSessionProvider追加
import { SessionProvider } from 'next-auth/react';
import type { AppProps } from 'next/app';
function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
return (
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
);
}
export default MyApp;
SignIn, SignOutを試す画面を作成
import { signIn, signOut, useSession } from 'next-auth/react';
export default function Page() {
const { data: session } = useSession();
return session ? (
<>
Signed in <br />
<button onClick={() => signOut()}>Sign Out</button>
</>
) : (
<>
Not signed in <br />
<button onClick={() => signIn()}>Sign In</button>
</>
);
}
middlewareでページに認証をかける
NEXTAUTH_SECRET を設定する必要があります。以下コマンドで生成したランダムな値を .env.local
に設定しときます。
openssl rand -base64 32
.env.local
NEXTAUTH_SECRET=生成したランダムな値
次に middleware.ts
を以下内容でプロジェクトのルートディレクトリ、または pages
と同階層に作成します。
export { default } from 'next-auth/middleware';
↑だけで、全ページにSignInしているかのチェックがかかります。
特定のページのみチェックしたい場合は
export { default } from 'next-auth/middleware';
export const config = {
matcher: ['/xxx'],
};
特定のページを指定した config
を返す事で実現できます。
バックエンド側での認証チェック
バックエンド サーバーで認証する | Authentication | Google Developers
↑こちらを参考に実装してみます。バックエンド側はNode.jsサーバーの想定です。
googleapis/google-auth-library-nodejs: 🔑 Google Auth Library for Node.js
↑こちらのパッケージを使えばverify部分はサクッと実装できます。
import { OAuth2Client } from 'google-auth-library';
const client = new OAuth2Client();
const verify = async (
idToken: string,
sub: string
): Promise<boolean> => {
const ticket = await client.verifyIdToken({
idToken,
});
const payload = ticket.getPayload();
return payload?.sub === sub;
};
Discussion