2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Next.jsにおける認証

Posted at

認証はユーザーが誰であるかを検証し、承認はユーザーがアクセスできるものを制御します。 Next.js は複数の認証パターンをサポートしており、それぞれが異なるユース ケース向けに設計されています。このページでは、制約に基づいて選択できるように、それぞれのケースについて説明します。

認証パターン

必要な認証パターンを特定するための最初のステップは、必要なデータ取得戦略を理解することです。次に、どの認証プロバイダーがこの戦略をサポートしているかを判断できます。主に次の 2 つのパターンがあります。

  • 静的生成を使用して、ロード状態をサーバーでレンダリングし、続いてクライアント側でユーザー データをフェッチします。
  • ユーザー データをサーバー側でフェッチして、認証されていないコンテンツのフラッシュを排除します。

静的に生成されたページの認証

Next.js は、ブロッキング データ要件がない場合、ページが静的であると自動的に判断します。これは、ページに getServerSideProps と getInitialProps がないことを意味します。代わりに、ページはサーバーからの読み込み状態をレンダリングし、続いてクライアント側でユーザーを取得できます。

このパターンの利点の 1 つは、ページをグローバル CDN から提供し、next/link を使用してプリロードできることです。実際には、これにより TTI (Time to Interactive) が速くなります。

プロフィールページの例を見てみましょう。これにより、最初に読み込み中のスケルトンがレンダリングされます。ユーザーのリクエストが完了すると、ユーザーの名前が表示されます。

// pages/profile.js

import useUser from '../lib/useUser'
import Layout from '../components/Layout'

const Profile = () => {
  // クライアントサイドでユーザの取得
  const { user } = useUser({ redirectTo: '/login' })

  // サーバレンダリングの読み込み状態
  if (!user || user.isLoggedIn === false) {
    return <Layout>Loading...</Layout>
  }

  // リクエスト終了後、ユーザに表示
  return (
    <Layout>
      <h1>Your Profile</h1>
      <pre>{JSON.stringify(user, null, 2)}</pre>
    </Layout>
  )
}

export default Profile

この例を実際に見ることができます。 with-iron-session の例をチェックして、それがどのように機能するかを確認してください。

サーバーでレンダリングされたページの認証

ページから getServerSideProps という非同期関数をエクスポートする場合、Next.js は、getServerSideProps によって返されたデータを使用して、リクエストごとにこのページを事前にレンダリングします。

export async function getServerSideProps(context) {
  return {
    props: {}, // プロパティとしてページコンポーネントに渡されます
  }
}

サーバー側のレンダリングを使用するようにプロファイルの例を変換してみましょう。 セッションがある場合は、ユーザーをプロパティとしてページの Profile コンポーネントに返します。 この例にはロード スケルトンがないことに注意してください。

// pages/profile.js

import withSession from '../lib/session'
import Layout from '../components/Layout'

export const getServerSideProps = withSession(async function ({ req, res }) {
  const { user } = req.session

  if (!user) {
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    }
  }

  return {
    props: { user },
  }
})

const Profile = ({ user }) => {
  // Show the user. No loading state is required
  return (
    <Layout>
      <h1>Your Profile</h1>
      <pre>{JSON.stringify(user, null, 2)}</pre>
    </Layout>
  )
}

export default Profile

このパターンの利点は、リダイレクト前に認証されていないコンテンツのフラッシュを防止できることです。 getServerSideProps でユーザー データを取得すると、認証プロバイダーへの要求が解決されるまでレンダリングがブロックされることに注意してください。 ボトルネックを作成して TTFB (Time to First Byte) を増加させないようにするには、認証ルックアップが高速であることを確認する必要があります。 それ以外の場合は、静的生成を検討してください。

認証プロバイダー

認証パターンについて説明したので、特定のプロバイダーを見て、それらが Next.js でどのように使用されているかを調べてみましょう。

  • Auth0
  • Clerk
  • Firebase
  • Magic
  • Nhost
  • Ory
  • Supabase
  • Supertokens
  • Userbase

公式ドキュメント→Authentication

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?