Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 45 additions & 89 deletions docs/authentication.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
---
description: Learn about authentication patterns in Next.js apps and explore a few examples.
description: Next.js アプリケーションにおける認証のパターンについて説明し、いくつかの具体例を見ていきます。
---

# Authentication
# 認証

Authentication verifies who a user is, while authorization controls what a user can access. Next.js supports multiple authentication patterns, each designed for different use cases. This page will go through each case so that you can choose based on your constraints.
認証 (authentication) とは「ユーザーが何者であるか」を検証するものであり、一方で認可 (authorization) は「ユーザーがアクセスできるものは何か」を管理するものです。Next.js は複数の認証パターンをサポートしていて、それぞれが異なるユースケースのために設計されています。このページではそれらのユースケースについて紹介していきますので、自分の要件にしたがって適切な方法を選択できるでしょう。

## Authentication Patterns
## 認証パターン

The first step to identifying which authentication pattern you need is understanding the [data-fetching strategy](/docs/basic-features/data-fetching.md) you want. We can then determine which authentication providers support this strategy. There are two main patterns:
どの認証パターンが必要か考えるときの最初のステップは、自分がどのような[データ取得](/docs/basic-features/data-fetching/overview.md)方法を取ろうとしているかについて正しく理解することです。それによって、そのデータ取得方法に適切な認証パターンはどれかを判断できます。データ取得方法というのは、主に以下の 2 種類に大別されます:

- Use [static generation](/docs/basic-features/pages.md#static-generation-recommended) to server-render a loading state, followed by fetching user data client-side.
- Fetch user data [server-side](/docs/basic-features/pages.md#server-side-rendering) to eliminate a flash of unauthenticated content.
- [静的生成](/docs/basic-features/pages.md#static-generation-recommended)を利用して、読み込み中の状態をサーバーでレンダリングする方法。その後で、クライアント側でユーザーデータを取得する
- 認証前のコンテンツがフラッシュ (一瞬表示されること) するのを完全に防ぐために、[サーバーサイドで](/docs/basic-features/pages.md#server-side-rendering)ユーザーデータを取得する方法

### Authenticating Statically Generated Pages
### 静的生成されたページの認証

Next.js automatically determines that a page is static if there are no blocking data requirements. This means the absence of [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering) and `getInitialProps` in the page. Instead, your page can render a loading state from the server, followed by fetching the user client-side.
Next.js は、ブロッキングを伴うデータの取得がページに必要ではないとき、そのページが静的生成されたページであることを自動的に判定します。言い換えると、これは、ページに [`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md) と `getInitialProps` が存在しないことを意味しています。その代わりに、ページは読み込み中の状態を表示し、その後、クライアントサイドでユーザーの取得が実行されます。

One advantage of this pattern is it allows pages to be served from a global CDN and preloaded using [`next/link`](/docs/api-reference/next/link.md). In practice, this results in a faster TTI ([Time to Interactive](https://web.dev/interactive/)).
このパターンの利点の 1 つは、ページをグローバルな CDN から配信し、[`next/link`](/docs/api-reference/next/link.md) によってページの先読みができることです。これは、実用面では TTI ([Time to Interactive](https://web.dev/interactive/)) がより高速になるという効果に繋がります。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「実用面では」という訳がちょっと引っかかりました 👀 この文では CDN などの文脈があり, この "In practice" はフィールドデータというか, 実際の ユーザー環境では, みたいな意味だと感じていて, "実用面" という訳でもそのニュアンスは伝わるんですが文全体の意味も相まって初心者の人は フィールドデータ というニュアンスが抜けて単純に「メリットがある」みたいな感じで理解してしまうんじゃないかなと感じました 👀 (みなさんの意見も聞いてみたいです)

Copy link
Collaborator Author

@5t111111 5t111111 Feb 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。ここ結構悩んだんですよね。

前段の、

One advantage of this pattern is it allows pages to be served from a global CDN and preloaded using next/link.

これが「メリット」として書かれていて、同じ「メリット」であっても、それによって実際の世界で得られる現象としての「メリット」が "In practice..." 以降と考えていて、それは多分 @Shinyaigeek さんの言う フィールドデータ 的なものとズレはないと思ってます。

ただ、そこで原文から意訳になりすぎないように選んだ言葉が「実用面では」というもので、実際にユーザーが享受できるメリットというニュアンスを感じてもらうつもりでしたが、確かに受け取り方によってはニュアンスが損なわれてしまいますね…
それを簡潔に表現できるいい案が思いついていないので、僕も他の方の意見をまず待ちたいと思います!

(コミットの方に返信しちゃっていたのでこっちにも転記)


Let's look at an example for a profile page. This will initially render a loading skeleton. Once the request for a user has finished, it will show the user's name:
プロフィールページを例として見てみましょう。以下は、まず最初に読み込み中のスケルトン表示をレンダリングします。そして、ユーザーを取得するためのリクエストが完了した時点でユーザーの名前を表示します:

```jsx
// pages/profile.js
Expand All @@ -28,15 +28,15 @@ import useUser from '../lib/useUser'
import Layout from '../components/Layout'

const Profile = () => {
// Fetch the user client-side
// クライアントサイドでユーザーを取得する
const { user } = useUser({ redirectTo: '/login' })

// Server-render loading state
// サーバーが読み込み中の状態をレンダリングする
if (!user || user.isLoggedIn === false) {
return <Layout>Loading...</Layout>
}

// Once the user request finishes, show the user
// ユーザー取得リクエストが完了したらユーザーを表示する
return (
<Layout>
<h1>Your Profile</h1>
Expand All @@ -48,32 +48,30 @@ const Profile = () => {
export default Profile
```

You can view this example in action [here](https://next-with-iron-session.vercel.app/). Check out the [`with-iron-session`](https://github.com/vercel/next.js/tree/canary/examples/with-iron-session) example to see how it works.
[実際に動作する例](https://iron-session-example.vercel.app/)でこれを確認できます。[`with-iron-session`](https://github.com/vercel/next.js/tree/canary/examples/with-iron-session) を見て、これがどのように動作しているかを確認してみてください。

### Authenticating Server-Rendered Pages
### サーバーレンダリングされるページの認証

If you export an `async` function called [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering) from a page, Next.js will pre-render this page on each request using the data returned by `getServerSideProps`.
[`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md) という `async` 関数をページで export すると、Next.js はリクエストのたびに、`getServerSideProps` が返すデータを使ってページをプリレンダリングします。

```jsx
export async function getServerSideProps(context) {
return {
props: {}, // Will be passed to the page component as props
props: {}, // props としてページコンポートネントに渡される
}
}
```

Let's transform the profile example to use [server-side rendering](/docs/basic-features/pages#server-side-rendering). If there's a session, return `user` as a prop to the `Profile` component in the page. Notice there is not a loading skeleton in [this example](https://next-with-iron-session.vercel.app/).
先ほどのプロフィールページの例を[サーバーサイドレンダリング](/docs/basic-features/pages#server-side-rendering)を使うように書き換えてみましょう。もしセッションが有効であれば、`user` が props としてページの `Profile` コンポーネントに渡されます。[この例](https://iron-session-example.vercel.app/)のような読み込み中のスケルトン表示がないことに気づいたでしょうか。

```jsx
// pages/profile.js

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

export const getServerSideProps = withSession(async function ({ req, res }) {
// Get the user's session based on the request
const user = req.session.get('user')
const { user } = req.session

if (!user) {
return {
Expand All @@ -90,7 +88,7 @@ export const getServerSideProps = withSession(async function ({ req, res }) {
})

const Profile = ({ user }) => {
// Show the user. No loading state is required
// ユーザーを表示する。読み込み中の状態は不要
return (
<Layout>
<h1>Your Profile</h1>
Expand All @@ -102,107 +100,65 @@ const Profile = ({ user }) => {
export default Profile
```

An advantage of this pattern is preventing a flash of unauthenticated content before redirecting. It's important to note fetching user data in `getServerSideProps` will block rendering until the request to your authentication provider resolves. To prevent creating a bottleneck and decreasing your TTFB ([Time to First Byte](https://web.dev/time-to-first-byte/)), you should ensure your authentication lookup is fast. Otherwise, consider [static generation](#authenticating-statically-generated-pages).
このパターンの利点は、認証前のコンテンツがリダイレクト前にフラッシュするのを防ぐことができる点です。ただ、`getServerSideProps` でユーザーデータを取得すると、認証プロバイダーがリクエストを完了するまでの間レンダリングがブロックされるということは認識しておくべきです。これがボトルネックとなってしまい、TTFB ([Time to First Byte](https://web.dev/time-to-first-byte/)) が増加してしまうことを避けるには、認証処理が高速に実行されることを確認しておかなければいけません。もしそうでないのであれば、[静的生成](#authenticating-statically-generated-pages)を検討してください。

## Authentication Providers
## 認証プロバイダー

Now that we've discussed authentication patterns, let's look at specific providers and explore how they're used with Next.js.
ここまで認証のパターンを見てきました。ここからは、具体的な認証プロバイダーと、Next.js でそれらを利用する方法について見ていきます。

### Bring Your Own Database
### 自前のデータベースを利用する

<details open>
<summary><b>Examples</b></summary>
<summary><b></b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-iron-session">with-iron-session</a></li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-next-auth">with-next-auth</a></li>
<li><a href="https://github.com/nextauthjs/next-auth-example">next-auth-example</a></li>
</ul>
</details>

If you have an existing database with user data, you'll likely want to utilize an open-source solution that's provider agnostic.
ユーザーデータの格納された既存のデータベースがある場合は、特定のプロバイダーに依存しないオープンソースのソリューションを利用するのがよいでしょう。

- If you need email/password log-in, use [`next-iron-session`](https://github.com/vercel/next.js/tree/canary/examples/with-iron-session).
- If you need to persist session data on the server, use [`next-auth`](https://github.com/vercel/next.js/tree/canary/examples/with-next-auth).
- If you need to support social login (Google, Facebook, etc.), use [`next-auth`](https://github.com/vercel/next.js/tree/canary/examples/with-next-auth).
- If you want to use [JWTs](https://jwt.io/), use [`next-auth`](https://github.com/vercel/next.js/tree/canary/examples/with-next-auth).
- 低レベルで暗号化されたステートレスなセッションを扱いたいときは [`iron-session`](https://github.com/vercel/next.js/tree/canary/examples/with-iron-session) を利用する
- 組み込みのプロバイダー(Google、Facebook、GitHub...)、JWT、JWE、E メール/パスワード、マジックリンクなど、フル機能の認証システムが欲しいときには [`next-auth`](https://github.com/nextauthjs/next-auth-example) を利用する

Both of these libraries support either authentication pattern. If you're interested in [Passport](http://www.passportjs.org/), we also have examples for it using secure and encrypted cookies:
どちらの認証パターンにも上記のライブラリは対応しています。もし、[Passport](http://www.passportjs.org/) に興味があれば、安全で暗号化された cookies を使用した例も用意しています:

- [with-passport](https://github.com/vercel/next.js/tree/canary/examples/with-passport)
- [with-passport-and-next-connect](https://github.com/vercel/next.js/tree/canary/examples/with-passport-and-next-connect)

### Firebase

<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-firebase-authentication">with-firebase-authentication</a></li>
</ul>
</details>

When using Firebase Authentication, we recommend using the static generation pattern.

It is possible to use the Firebase Client SDK to generate an ID token and forward it directly to Firebase's REST API on the server to log-in. However, requests to Firebase might take some time to resolve, depending on your user's location.
### その他のプロバイダー

You can either use [FirebaseUI](https://github.com/firebase/firebaseui-web-react) for a drop-in UI, or create your own with a [custom React hook](https://usehooks.com/useAuth/).

### Magic (Passwordless)
その他の認証プロバイダーを使った例については、[examples フォルダー](https://github.com/vercel/next.js/tree/canary/examples) を参照ください。

<details open>
<summary><b>Examples</b></summary>
<summary><b></b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-firebase-authentication">with-firebase-authentication</a></li>
<li><a href="https://github.com/vercel/examples/tree/main/solutions/auth-with-ory">auth-with-ory</a></li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-magic">with-magic</a></li>
</ul>
</details>

[Magic](https://magic.link/), which uses [passwordless login](https://magic.link/), supports the static generation pattern. Similar to Firebase, a [unique identifier](https://w3c-ccg.github.io/did-primer/) has to be created on the client-side and then forwarded as a header to log-in. Then, Magic's Node SDK can be used to exchange the indentifier for a user's information.

### Auth0

<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/auth0">auth0</a></li>
</ul>
</details>

[Auth0](https://auth0.com/) can support both authentication patterns. You can also utilize [API routes](/docs/api-routes/introduction.md) for logging in/out and retrieving user information. After logging in using the [Auth0 SDK](https://github.com/auth0/nextjs-auth0), you can utilize static generation or `getServerSideProps` for server-side rendering.

### Supabase

<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-supabase-auth-realtime-db">with-supabase-auth-realtime-db</a></li>
</ul>
</details>

[Supabase](https://supabase.io/) is an open source Firebase alternative that supports many of its features, including authentication. It allows for row level security using JWT tokens and supports third party logins. Either authentication pattern is supported.

### Userbase

<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-userbase">with-userbase</a></li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-supertokens">with-supertokens</a></li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-nhost-auth-realtime-graphql">with-nhost-auth-realtime-graphql</a></li>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-clerk">with-clerk</a></li>
</ul>
</details>

[Userbase](https://userbase.com/) supports the static generation pattern for authentication. It's open source and allows for a high level of security with end-to-end encryption. You can learn more about it in their [official site](https://userbase.com/).

## Related
## 関連事項

For more information on what to do next, we recommend the following sections:
より理解を深めるために、次は以下のセクションに目を通すことをお勧めします。

<div class="card">
<a href="/docs/basic-features/pages.md">
<b>Pages:</b>
<small>Learn more about pages and the different pre-rendering methods in Next.js.</small>
<b>ページ:</b>
<small>Next.js のページと異なるプリレンダリング方法についてより詳しく学びます</small>
</a>
</div>

<div class="card">
<a href="/docs/basic-features/data-fetching.md">
<b>Data Fetching:</b>
<small>Learn more about data fetching in Next.js.</small>
<b>データ取得:</b>
<small>Next.js でのデータ取得についてより詳しく学びます</small>
</a>
</div>