この記事の目的
- Next.jsでDBを使用してサイト構築する際の備忘録
- SupabaseでPostgreSQLのDB作成する際のフロー確認用
- Next.jsにDBを追加した際にVercelでデプロイするフロー
- Next.jsにDB追加してVercelで公開してみた①の続き
記事の概要
今回はNext.jsにDB追加してVercelで公開してみた①の続きとなり、認証機能を追加しVercelで公開するところまでをまとめています。
また、本記事では自分用にまとめているので、細かい内容については下記の記事を参考にしてみて下さい!
- Next.js、Prisma、および PostgreSQL を使用してフルスタック アプリを構築する方法
-
Next.js、 Prisma、PostgreSQLでフルスタックアプリを作る
後者の記事は前者の記事を日本語に翻訳してくれているみたいです。
使用技術と前提
使用技術
- Next.js(バージョンは12)
- react
- typescript
- prisma
- Supabase
前提
- GitHubアカウント (OAuthアプリを作成するために使用)
- Googleアカウント (OAuthアプリを作成するために使用)
- Vercelアカウント (作成したアプリをデプロイするために使用)
- Supabaseアカウント (PostgreSQLをDBとして用意するために使用)
プロジェクト公開までのフロー
- ①Next.jsのプロジェクト作成
- ②prismaインストール
- ③supabaseの設定
- ④DB設定(schema.prismaでテーブル作成)
- ⑤投稿データ取得等の処理実装(Prisma Client)
- ⑥NextAuth.js ライブラリをインストール
- ⑦ログイン機能追加
- ⑧GitHub認証設定
- ⑨Google認証設定
- ⑩Vercelで公開してみる
※長くなるためこの記事では⑥以降をまとめています
※バックエンドを実装してVercel公開できることを目的としているので、コードは載せていますが細かいは説明せずにさらっと説明しているので、ソースコード全体についてはこちらのGitHubを参考にして下さい。
⑥NextAuth.js ライブラリをインストール
下記のコマンドでNextAuth ライブラリと NextAuth Prisma アダプタをインストールします。
npm install next-auth@4 @next-auth/prisma-adapter
⑦ログイン機能追加
ヘッダーにLoginボタンを追加
components/Header.tsx
を下記のよう変更して下さい。
components/Header.tsxコードをクリックして全て表示
// Header.tsx
import React from 'react';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { signOut, useSession } from 'next-auth/react';
const Header: React.FC = () => {
const router = useRouter();
const isActive: (pathname: string) => boolean = (pathname) =>
router.pathname === pathname;
const { data: session, status } = useSession();
let left = (
<div className="left">
<Link href="/">
<a className="bold" data-active={isActive('/')}>
Feed
</a>
</Link>
<style jsx>{`
.bold {
font-weight: bold;
}
a {
text-decoration: none;
color: var(--geist-foreground);
display: inline-block;
}
.left a[data-active='true'] {
color: gray;
}
a + a {
margin-left: 1rem;
}
`}</style>
</div>
);
let right = null;
if (status === 'loading') {
left = (
<div className="left">
<Link href="/">
<a className="bold" data-active={isActive('/')}>
Feed
</a>
</Link>
<style jsx>{`
.bold {
font-weight: bold;
}
a {
text-decoration: none;
color: var(--geist-foreground);
display: inline-block;
}
.left a[data-active='true'] {
color: gray;
}
a + a {
margin-left: 1rem;
}
`}</style>
</div>
);
right = (
<div className="right">
<p>Validating session ...</p>
<style jsx>{`
.right {
margin-left: auto;
}
`}</style>
</div>
);
}
if (!session) {
right = (
<div className="right">
<Link href="/api/auth/signin">
<a data-active={isActive('/signup')}>Log in</a>
</Link>
<style jsx>{`
a {
text-decoration: none;
color: var(--geist-foreground);
display: inline-block;
}
a + a {
margin-left: 1rem;
}
.right {
margin-left: auto;
}
.right a {
border: 1px solid var(--geist-foreground);
padding: 0.5rem 1rem;
border-radius: 3px;
}
`}</style>
</div>
);
}
if (session) {
left = (
<div className="left">
<Link href="/">
<a className="bold" data-active={isActive('/')}>
Feed
</a>
</Link>
<Link href="/drafts">
<a data-active={isActive('/drafts')}>My drafts</a>
</Link>
<style jsx>{`
.bold {
font-weight: bold;
}
a {
text-decoration: none;
color: var(--geist-foreground);
display: inline-block;
}
.left a[data-active='true'] {
color: gray;
}
a + a {
margin-left: 1rem;
}
`}</style>
</div>
);
right = (
<div className="right">
<p>
{session.user.name} ({session.user.email})
</p>
<Link href="/create">
<button>
<a>New post</a>
</button>
</Link>
<button onClick={() => signOut()}>
<a>Log out</a>
</button>
<style jsx>{`
a {
text-decoration: none;
color: var(--geist-foreground);
display: inline-block;
}
p {
display: inline-block;
font-size: 13px;
padding-right: 1rem;
}
a + a {
margin-left: 1rem;
}
.right {
margin-left: auto;
}
.right a {
border: 1px solid var(--geist-foreground);
padding: 0.5rem 1rem;
border-radius: 3px;
}
button {
border: none;
}
`}</style>
</div>
);
}
return (
<nav>
{left}
{right}
<style jsx>{`
nav {
display: flex;
padding: 2rem;
align-items: center;
}
`}</style>
</nav>
);
};
export default Header;
NextAuth.jsで認証用の特定のルートを設定
pages/api/auth/
配下に[...nextauth].ts
を作成し下記のように編集して下さい。
今回はGitHub認証設定とGoogle認証設定を追加するのでproviders
に2つ追加しています。
他にもFaceBook認証とかと追加する場合は、providers
にさらに追加していくイメージになります。
pages/api/auth/[...nextauth].tsコードをクリックして全て表示
import { NextApiHandler } from 'next';
import NextAuth from 'next-auth';
import { PrismaAdapter } from '@next-auth/prisma-adapter';
import GitHubProvider from 'next-auth/providers/github';
import GoogleProvider from "next-auth/providers/google";
import prisma from '../../../lib/prisma';
// Next.js APIルートのハンドラーを定義
const authHandler: NextApiHandler = (req, res) => NextAuth(req, res, options);
export default authHandler;
const options = {
// 認証プロバイダーのリストを指定
providers: [
// GitHub認証プロバイダーを追加
GitHubProvider({
// GitHub OAuthアプリケーションのクライアントID
clientId: process.env.GITHUB_ID,
// GitHub OAuthアプリケーションのクライアントシークレット
clientSecret: process.env.GITHUB_SECRET,
}),
// Google認証プロバイダーを追加
GoogleProvider({
// Google OAuthクライアントID
clientId: process.env.GOOGLE_CLIENT_ID,
// Google OAuthクライアントシークレット
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
authorization: {
params: {
prompt: "consent",// 認証時Googleに表示されるダイアログの種類を指定
access_type: "offline",// Google OAuthアクセストークン取得に必要な許可を要求
response_type: "code"// Google OAuth認証レスポンスタイプを指定。"code"はアクセストークンを受け取るための認証コードを返す
}
}
}),
],
// データベースアダプターを指定する
adapter: PrismaAdapter(prisma),
// トークン署名に使用する秘密鍵を指定する
secret: process.env.SECRET,
};
⑧GitHub認証設定
GitHub認証はアプリの認証ページのURLごとに作成する必要があるため、ローカル環境とVercelで公開した場合の2パターン作成します。api/auth
は認証画面のURLです。
- ローカル環境 : http://localhost:3000
- Vercelで公開した場合 : https://pikimaru-nps.vercel.app
※.vercel.app
の前のpikimaru-nps
部分は後ほどVercelにデプロイする際につけるプロジェクト名になります
【ローカル環境】GitHubで新しいOAuth applicationを作成
GitHub認証を使用するには、GitHubでOAuth applicationを作成を作成する必要もあります。
GitHubにログインしSettingsのDeveloper Settingsを開きOAuth Appsを選択後、「New OAuth App」を選択します。
【ローカル環境】必要事項の入力
- Application name : 好きな名前で問題ないです。
- Homepage URL : https://www.prisma.io/
- Authorization callback URL : http://localhost:3000/api/auth
Authorization callback URLは、Next.js '/api/auth' route: 'http://localhost:3000/api/auth' になります。URLが複数入力できないため環境ごとに作成する必要があります。
【ローカル環境】Client IDとClient secretsを確認し設定する
OAuth applicationを作成が作成されると下の画像のような画面になるかと思いますので
Client ID
とClient secrets
を確認していきます。
Client secrets
は初期状態だとおそらくないと思うので「Generate a new client secret」を選択し作成して下さい。
確認したら.env
に設定していきます。
- GITHUB_IDにClient ID
- GITHUB_SECRETにClient Secret
- NEXTAUTH_URLにAuthorization callback URL
# GitHub OAuth
GITHUB_ID=XXXXXXXXXXXXXXXXXXX
GITHUB_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
NEXTAUTH_URL=http://localhost:3000/api/auth
⑨Google認証設定
Google認証もGitHub認証と同じくアプリの認証ページのURLごとに作成する必要があるため、ローカル環境とVercelで公開した場合の2パターン作成します。api/auth
は認証画面のURLです。
- ローカル環境 : http://localhost:3000
- Vercelで公開した場合 : https://pikimaru-nps.vercel.app
※.vercel.app
の前のpikimaru-nps
部分は後ほどVercelにデプロイする際につけるプロジェクト名になります
【ローカル環境】Googleで新しいOAuthクライアントを作成
まずはGoogle Cloud Platfom(GCP)にログインする。
初めてGCPにログインした方は利用規約確認の画面が出るかと思うので、問題がなければチェックし、「同意して続行」ボタンをクリックしてください。”最新情報をメールで通知”は必要でなければチェックは不要です。
左側のサイドバーメニューから「APIとサービス」を選択し、「認証情報」を選択
【ローカル環境】プロジェクトを作成
「新しいプロジェクト」を選択(初めてプロジェクトを作成する方は画面は少し異なると思います。)
プロジェクトは「プロジェクト名」だけ入力すれば問題ないです。好きな名前を入力して下さい
【ローカル環境】OAuthクライアントを作成(同意画面)
プロジェクト作成後、「認証情報を作成」選択し「0AuthクライアントID」を選択して下さい
そうすると同意を求められるので「同意画面を設定」を選択し「0Auth同意画面」のUserTypeを外部にチェックをして作成を選択して下さい
次に「①0Auth同意画面」が表示されるので以下の必須項目3点を記入して下さい
- アプリ名 : 好きな名前で問題ないです
- ユーザーサポートメール : 自身のメールアドレス
- デベロッパーの連絡先情報 : 自身のメールアドレス
上記以外は特に「①0Auth同意画面」、「②スコープ」「③テストユーザー」でも入力する必要ないので、「保存して次へ」を選択して下さい
「②スコープ」「③テストユーザー」でも、「保存して次へ」を選択すると「④概要」に進み同意画面の作業が完了になります
【ローカル環境】OAuthクライアントを作成
同意画面の作業が完了したので、目的のOAuthクライアントを作成していきます。
先ほど同様「認証情報を作成」選択し「0AuthクライアントID」を選択して下さい
そうすると今度は「0AuthクライアントIDの作成」画面が表示されるので以下の4項目を選択または入力して下さい。
- アプリケーションの種類 : ウェブアプリケーション
- 名前 : 好きな名前で問題ないです(今回はローカル環境用なので例としてローカルと分かる名前にしています)
- 承認済みのJavaScript生成元 :
http://localhost:3000
- 承認済みのリダイレクトURI :
http://localhost:3000/api/auth/callback/google
※承認済みのリダイレクトURLにはhttp://localhost:3000/api/auth/providers
に対してGETリクエストを送信した際に取得したcallbackUrl
であるhttp://localhost:3000/api/auth/callback/google
を入力する必要があります
作成が完了すると画面上にクライアントIDとクライアントシークレットの情報が表示さるかと思います。
クライアントIDとクライアントシークレットを.env
に設定していきます。
- GOOGLE_CLIENT_IDにクライアントID
- GOOGLE_CLIENT_SECRETにクライアントシークレット
# Google OAuth
GOOGLE_CLIENT_ID=XXXXXXXXXXXXXXXXXXX
GOOGLE_CLIENT_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
【ローカル環境】ローカル環境で認証動作確認
ここまででローカル環境のGitHub認証設定とGoogle認証設定が完了したのでローカル環境(http://localhost:3000/)で確認していきます
わかりやすいように画面を拡大したものを載せています
Loginを選択
http://localhost:3000/
にアクセスしヘッダーの右側に「Login」があると思うので選択する
認証画面確認
「Login」選択すると下のような認証ボタンが出てくるかと思いますので
GitHubまたはGoogle認証を選択しログインできることを確認してみて下さい。
最初の1回目のみ各媒体お馴染みののログイン画面が出てくるかと思います。
ログインが成功するとヘッダー部分にログインしたユーザー情報がでるかと思います。
ログアウトしてもう一方の認証も同じように確認してみて下さい
データベースでユーザー情報確認
ログインを行うとログインしたユーザー情報がデータベースに登録されるのでSupabaseもしくはprisma studioで確認します
Supabase確認
下記のようにレコードが追加され、provider
でどの認証機能を使用しているかなど確認できるかと思います
prisma studio確認
http://localhost:5555/
に遷移するとみれるかと思います。
prisma studioを停止している場合はnpx prisma studio
で起動してアクセスしてみて下さい
⑩Vercelで公開してみる
ローカル環境で確認できたので、実際にVercelにデプロイしバックエンドも備えたサイトを公開していきます。
流れとしては以下になります
- 【公開用】GitHub認証設定
- 【公開用】Google認証設定
- Vercelでプロジェクト作成デプロイ
また、ここからソースコードは変更しないのでGitHubにリポジトリを作成しコミットプッシュまで行って下さい
先ほど編集した.env
はローカルでしか使用されないので削除等はしなくて問題ないです。(GitHubにも載らないので)
【公開用】GitHub認証設定
⑧GitHub認証設定で作成したローカル用のOAuth applicationと同様にして
Vercel公開用のOAuth applicationを作成していきます。
【Vercel公開用】GitHubで新しいOAuth applicationを作成
先ほどと手順は同じくGitHubにログインしSettingsのDeveloper Settingsを開きOAuth Appsを選択後、「New OAuth App」を選択し必要事項の入力していきます
- Application name : 好きな名前で問題ないです。
- Homepage URL : https://www.prisma.io/
- Authorization callback URL : https://Vercelのプロジェクト名.vercel.app/api/auth
※Vercelのプロジェクト名については、Vercelでデプロイする際に決めることができるので、ここで入力したVercelのプロジェクト名を使用して後ほどVercelのプロジェクトを作成していきます
ここではVercelのプロジェクト名をpikimaru-nps
としています
OAuth applicationを作成が作成されると下の画像のような画面になるかと思いますので
Client ID
とClient secrets
を確認していきます。
Client secrets
は初期状態だとおそらくないと思うので「Generate a new client secret」を選択し作成して下さい
Vercelでプロジェクト作成際にClient ID
とClient secrets
が必要になります
【公開用】Google認証設定
⑨Google認証設定で作成したローカル用のOAuthクライアントと同様にして
Vercel公開用のOAuthクライアントを作成していきます。
まずはGoogle Cloud Platfom(GCP)にログインする。
先ほどローカル用で作成しているため「同意画面を設定」は飛ばせるかと思います。
- アプリケーションの種類 : ウェブアプリケーション
- 名前 : 好きな名前で問題ないです
- 承認済みのJavaScript生成元 : https://Vercelのプロジェクト名.vercel.app
- 承認済みのリダイレクトURI : https://Vercelのプロジェクト名.vercel.app/api/auth/callback/google
※Vercelのプロジェクト名については、Vercelでデプロイする際に決めることができるので、ここで入力したVercelのプロジェクト名を使用して後ほどVercelのプロジェクトを作成していきます
Vercelでプロジェクト作成際にClient ID
とClient secrets
が必要になります
Vercelでプロジェクト作成デプロイ
ここからは実際にVercelに認証を設定したプロジェクトを作成し公開していきます。
Vercelプロジェクト作成
Vercelのダッシュボードに移動して「Add New」を選択し「Project」を選択します
「Project」を選択後、リポジトリを選択する画面になるかと思いますので、今回あげたリポジトリの「import」を選択する。
プロジェクト作成画面に遷移するかと思いますので下記の必要項目を入力します。
Environment Variablesを選択すると環境変数が追加できるようになるかと思います。
-
Project name
: Vercelのプロジェクト名(先ほど認証の際に使用していたもの本記事ではpikimaru-nps
) -
DATABASE_URL
: '.env' と同じ値 -
GITHUB_ID
: GitHub OAuth appのClient ID
をコピーして入力してください -
GITHUB_SECRET
: GitHub OAuth appのClient secrets
をコピーして入力してください -
NEXTAUTH_URL
: GitHub OAuth appのAuthorization Callback URL
をコピーして入力してください -
SECRET
:GITHUB_SECRET
と同じものを入力してください。Prismaが使用します。 -
GOOGLE_CLIENT_ID
: Google認証設定で取得したClient ID
をコピーして入力してください -
GOOGLE_CLIENT_SECRET
: Google認証設定で取得したClient secrets
をコピーして入力してください
入力が完了したら「Deploy」を選択するとデプロイが始まります!
デプロイがビジ完了すると下の画像のように表示されるかと思います!
表示されたら「Continue to Dashubooar」を選択し、その後「Visit」を選択すると公開されたページに遷移して確認することができます
本記事で公開したURLはhttps://pikimaru-nps.vercel.app/
となっておりこちらで遷移すると下の画像のように表示されるかと思います。
投稿機能およびログイン認証も確認できたので、DB追加したNext.jsのプロジェクトをVercelで公開できました!!