Next.jsで使える認証ライブラリ、next-authでGoogle認証を試してみます。
公式を参考にしつつ動くところまでやってみます。永続化とかはしません。
ちなみに今回の内容はこのあたりに何もかも書いてあります。
https://next-auth.js.org/getting-started/example
https://next-auth.js.org/providers/google
https://developers.google.com/identity/protocols/oauth2
実装
next-auth導入
typescriptを導入したNext.jsのアプリを用意しておきます。
これをクローンする形でも問題ないです。
https://github.com/yubachiri/next-ts
npm i next-auth
でnext-authをインストール。
そしたら実装を進めていきましょう。
認証情報の設定
まずはクライアントID・シークレットIDを用意します。
GCP > APIとサービス > 認証情報 より、「OAuthクライアントID」を作成してください。OAuth同意画面の設定を求められたらよしなに作成してください。
このへんが参考になると思います。
https://developers.google.com/identity/protocols/oauth2
今回はローカルで触ってみるところまでにするので、クライアントID作成時に設定することとなる 承認済みの JavaScript 生成元
と 承認済みのリダイレクトURI
はそれぞれ下記の内容にします。
生成元: http://localhost:3000
リダイレクトURI: http://localhost:3000/api/auth/callback/google
です。
そしたらクライアントIDとクライアントシークレットをメモっておきます。
実装
適宜ファイルを作成したり編集したりしてください。
pages/api/auth/[...nextauth].ts
import NextAuth from 'next-auth' import Providers from 'next-auth/providers' const options = { providers: [ Providers.Google({ clientId: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET }) ], } export default (req, res) => NextAuth(req, res, options)
pages/_app.tsx
import { Provider } from 'next-auth/client' export default function App ({ Component, pageProps }) { return ( <Provider session={pageProps.session}> <Component {...pageProps} /> </Provider> ) }
.env
GOOGLE_CLIENT_ID=メモった内容 GOOGLE_CLIENT_SECRET=メモった内容
ここまで書くと、認証処理が動くようになっています。動作確認できるようにしましょう。
pages/index.tsx
import React from 'react' import { signIn, signOut, useSession } from 'next-auth/client' export default function Page() { const [ session, loading ] = useSession() return <> {!session && <> Not signed in <br/> <button onClick={signIn}>Sign in</button> </>} {session && <> Signed in as {session.user.email} <br/> <button onClick={signOut}>Sign out</button> </>} </> }
これでGoogle認証が完了するところまでは実装が完了しました。お疲れ様です!以上です!
おまけ
だけだと味気ないので、ちょっとカスタマイズしてみます。
ログイン画面をいじってみましょうか。2ステップでいけます。
[...nextauth].ts
に pages
を追加
import NextAuth from 'next-auth' import Providers from 'next-auth/providers' const options = { providers: [ Providers.Google({ clientId: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET }) ], // 追加 pages: { signIn: '/auth/signin' } } export default (req, res) => NextAuth(req, res, options)
pages/auth/signin.tsx
を追加
import React from "react"; import { providers, signIn } from "next-auth/client"; export default function SignIn({ providers }) { return ( <> <h2>ログイン</h2> {Object.values(providers).map((provider) => ( <div key={provider.name}> <button onClick={() => signIn(provider.id)}> Sign in with {provider.name} </button> </div> ))} </> ) } export async function getStaticProps(context) { return { props: { providers: await providers(context), }, } }
です。next-authがts対応してない?っぽい?のでところどころ警告出ますが…。
こんな画面になります。
ちなみにこの対応前に表示されていたものはnext-authが自動生成したものみたいですね。
NextAuth.js automatically creates simple, unbranded authentication pages for handling Sign in, Sign out, Email Verification and displaying error messages.
The options displayed on the sign up page are automatically generated based on the providers specified in the options passed to NextAuth.js.
とあります。
というわけで自由にログインページを編集できるようになりました。なお、この実装だとログイン後もこのページに留まるような形になります。気になる場合は手を入れてください。
以上
今回はこんなところです。とても少ないコードでログイン機能を実装できましたね。もちろんGoogle以外にも多くのプラットフォームをサポートしていたり、メール/パスワード認証やJWTにも対応しているみたいです。なんでも来いって感じですね。
今回は触れてませんがTypeORMやPrisma等を通してDB接続もいい感じに連携できるみたいです。