こんにちは、柴田です。
今回は「会員制メディア」のチュートリアルを全3回に分けてお届けします。
===
===
会員制メディアは、一部の記事は会員しか見れないような形式のメディアです。
ビジネスでは近年よくあるユースケースであり、もしかしたら個人ブログに導入してみても一風変わっていて面白いかもしれません。
また、応用すれば課金しないと見れない記事のような仕組みも作れると思います。
今回想定している仕様は以下の通りです。
- 記事一覧画面と全公開記事(/public配下)は事前生成をしておき、静的に配信する
- 会員向け記事(/private配下)はログイン済みユーザーのみ閲覧可能とし、SSRで配信する
Next.jsを用いてJamstackとSSRの合わせ技を行い、認証にはAuth0を用います。
1. Next.jsプロジェクトを用意
まずは、Next.jsのプロジェクトを作成していきます。
プロジェクトの雛形を作成するCLIがあるので、コマンドを入力して作成していきましょう。
今回はTypeScriptも合わせて導入していきます。
$ npx create-next-app@latest --ts
作成したプロジェクトに移動して、開発サーバーを立ち上げます。
$ npm run dev
http://localhost:3000
にアクセスすると下記の画像のように、アプリケーションが立ち上がります。
2. Auth0を用意
今回は認証用にAuth0という認証プラットフォームを用います。
まずはアカウント作成を行い、サービスにログインしましょう。
ログイン後は「Create Application」からアプリケーションを作成していきます。
application typeは、「Regular Web Applications」を選択してください。
次に利用するフレームワークとしてNext.jsを選択します。
これでアプリケーションの作成は完了です。
3. SDKをインストール
Next.jsとAuth0の連携のために@auth0/nextjs-auth0
というSDKをインストールします。
$ npm install @auth0/nextjs-auth0
4. 環境変数設定
環境変数設定のため、ルートディレクトリに.env.local
ファイルを作成し、下記のような値を設定します。
(例ですので、この通り入力しても動きません)
// .env.local
# A long, secret value used to encrypt the session cookie
AUTH0_SECRET='9orhWZmRvlmTUUTTrWJ58NscW28BUkIl593peuU1O6YQkYZQWjuX3A0YFD6ihTjy'
# The base url of your application
AUTH0_BASE_URL='http://localhost:3000'
# The url of your Auth0 tenant domain
AUTH0_ISSUER_BASE_URL='https://dev-dsc5a7wm.us.auth0.com'
# Your Auth0 application's Client ID
AUTH0_CLIENT_ID='QBN70Fwb041BkZhwfKoMHkbNTKraC3ni'
# Your Auth0 application's Client Secret
AUTH0_CLIENT_SECRET='dDQFkQeKRm86D0za-4dbgTqe8t_WkVcrULANw2JsBo2AdBg-8ZGS6WXVVeRPdjmk'
AUTH0_SECRET
下記コマンドを実行するなどして32bytesの文字列を生成してください。
$ openssl rand -hex 32
AUTH0_BASE_URL
Next.jsのベースURLを入力してください。
AUTH0_ISSUER_BASE_URL
Auth0のテナントドメインを入力してください。
AUTH0_CLIENT_ID
Auth0のアプリケーション内「Settings > Basic Information > Client ID」の値を入力してください。
AUTH0_CLIENT_SECRET
Auth0のアプリケーション内「Settings > Basic Information > Client Secret」の値を入力してください。
5. Auth0ダッシュボードの設定
同じくAuth0のアプリケーション内「Settings > Applications URIs」の下記項目を設定してください。
Allowed Callback URLs: http://localhost:3000/api/auth/callback
Allowed Logout URLs: http://localhost:3000/
最後に保存するのを忘れずに。
6. 認証用APIの作成
/pages/api/
配下にauth
ディレクトリを作成します。
その後、/pages/api/auth/[...auth0].ts
ファイルを作成しましょう。
// [...auth0].ts
import { handleAuth } from '@auth0/nextjs-auth0';
export default handleAuth();
これにより、下記のルーティング処理が追加されます。
- /api/auth/login
- /api/auth/callback
- /api/auth/logout
- /api/auth/me
7. UserProviderの用意
/pages/_app.tsx
にてUserProvider
を導入します。
// pages/_app.tsx
import '../styles/globals.css';
import type { AppProps } from 'next/app';
import { UserProvider } from '@auth0/nextjs-auth0';
function MyApp({ Component, pageProps }: AppProps) {
const { user } = pageProps;
return (
<UserProvider user={user}>
<Component {...pageProps} />
</UserProvider>
);
}
export default MyApp;
8. 認証用のヘッダーコンポーネントを用意
ルート直下に新たにcomponents
ディレクトリを作成し、認証を行うためのヘッダーコンポーネントを用意しましょう。/components/Header.tsx
ファイルを作成します。
// components/Header.tsx
import { FC } from 'react';
import Link from 'next/link';
import { useUser } from '@auth0/nextjs-auth0';
const Header: FC = () => {
const { user, error, isLoading } = useUser();
if (isLoading) return <div>Loading...</div>;
if (error) return <div>{error.message}</div>;
if (user) {
return (
<header>
Welcome {user.name}! <Link href="/api/auth/logout">Logout</Link>
</header>
);
}
return (
<header>
<Link href="/api/auth/login">Login</Link>
</header>
);
};
export default Header;
アプリケーション全体でヘッダーコンポーネントを共通で読み込みたいので、_app.tsx
に追記します。
// pages/_app.tsx
import '../styles/globals.css';
import type { AppProps } from 'next/app';
import { UserProvider } from '@auth0/nextjs-auth0';
import Header from '../components/Header';
function MyApp({ Component, pageProps }: AppProps) {
const { user } = pageProps;
return (
<UserProvider user={user}>
<Header />
<Component {...pageProps} />
</UserProvider>
);
}
export default MyApp;
9. 認証動作確認
http://localhost:3000
にて確認すると、画面左上にLoginリンクが表示されるようになっているはずです。
こちらからAuth0経由でログイン、ログアウトがうまく動作すれば成功です。
もしうまくいかない場合は環境変数あたりを再度見直してみてください。
次回
今回はNext.jsとAuth0の連携部分について解説しました。
次回はここに対してさらにmicroCMSを連携し、公開用と会員向けコンテンツをそれぞれ表示させていきます。
お楽しみに!