0Pricing
Vue Academy · レッスン

JWT認証:ログインとリフレッシュ

アクセストークンとリフレッシュトークンのフロー、httpOnly Cookie、インターセプターによるサイレントリフレッシュ

「JWT認証:ログインとリフレッシュ」はCoddyKit上の無料Vue Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはVue Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Vue Academyコースには全4レッスンが含まれています。

アクセストークンとリフレッシュトークンのモデル

堅牢なJWT方式では、2種類のトークンを使用します。1つは、すべてのAPIリクエストに付けて送信する短期間(数分)有効なaccess token、もう1つは、新しいアクセストークンの発行にのみ使用する長期間(数日)有効なrefresh tokenです。アクセストークンが漏えいした場合の影響を抑えられます。

JWTプラグインを登録する

Fastifyで@fastify/jwtを登録し、強力なシークレットを指定します。これにより、アプリとリクエストのオブジェクトに署名用および検証用のヘルパーが追加されます。

import jwt from '@fastify/jwt'

await app.register(jwt, {
  secret: process.env.JWT_SECRET
})

ログインルート

POST /auth/loginで認証情報を検証し、2種類のトークンを発行します。平文のパスワードは決して保存せず、ハッシュ(bcrypt/argon2)と比較してください。

app.post('/auth/login', async (req, reply) => {
  const { email, password } = req.body
  const user = await findUser(email)
  if (!user || !(await verifyHash(password, user.hash))) {
    return reply.code(401).send({ error: 'Invalid credentials' })
  }
  // ... sign tokens (next scene)
})

アクセストークンに署名する

ユーザーIDと最小限のクレームを含めた短期間有効なアクセストークンに署名します。有効期限は短く設定してください(例: 15分)。

const accessToken = app.jwt.sign(
  { sub: user.id, role: user.role },
  { expiresIn: '15m' }
)

リフレッシュトークンに署名する

異なるペイロード識別子(または別のシークレット)を含めた長期間有効なリフレッシュトークンに署名します。このトークンはリフレッシュエンドポイントでのみ使用します。

const refreshToken = app.jwt.sign(
  { sub: user.id, type: 'refresh' },
  { expiresIn: '7d' }
)

httpOnly Cookieにリフレッシュトークンを保存する

リフレッシュトークンはhttpOnly、SameSite、Secure属性のCookieに保存します。JavaScriptから読み取れないためXSSによる窃取を緩和でき、ブラウザーはリフレッシュエンドポイントに自動的に送信します。

reply.setCookie('refreshToken', refreshToken, {
  httpOnly: true,
  sameSite: 'strict',
  secure: true,        // HTTPS only
  path: '/auth/refresh',
  maxAge: 60 * 60 * 24 * 7
})

ボディでアクセストークンを返す

アクセストークンはJSONレスポンスのボディで返します。VueアプリはこれをlocalStorageではなくメモリ上に保持し、APIリクエストに付加します。リフレッシュトークンがボディに現れることはありません。

return reply.send({
  accessToken,
  user: { id: user.id, name: user.name }
})
// refreshToken is only in the httpOnly cookie

アクセストークンをlocalStorageに保存しない理由

localStorageはあらゆるスクリプトから読み取れるため、XSSの脆弱性があると保存されたトークンを窃取される可能性があります。アクセストークンをJavaScriptのメモリ上に、リフレッシュトークンをhttpOnly Cookieに保持することで、XSSの被害範囲を抑えられます。

リフレッシュルート

POST /auth/refreshでCookieからリフレッシュトークンを読み取り、検証して新しいアクセストークンを発行します。新しいアクセストークンはボディで返します。

app.post('/auth/refresh', async (req, reply) => {
  const token = req.cookies.refreshToken
  if (!token) return reply.code(401).send()
  try {
    const payload = app.jwt.verify(token)
    const accessToken = app.jwt.sign(
      { sub: payload.sub }, { expiresIn: '15m' }
    )
    return reply.send({ accessToken })
  } catch {
    return reply.code(401).send({ error: 'Invalid refresh' })
  }
})

ルートを保護する

Authorizationヘッダーからアクセストークンを検証するpreHandlerを追加します。@fastify/jwtのrequest.jwtVerify()は無効または期限切れのトークンで例外をスローし、401を返します。

app.get('/api/me', {
  preHandler: async (req, reply) => {
    try { await req.jwtVerify() }
    catch { reply.code(401).send({ error: 'Unauthorized' }) }
  }
}, async (req) => getProfile(req.user.sub))

ログアウト: Cookieを削除する

ログアウト時にリフレッシュCookieを削除すると、新しいアクセストークンを発行できなくなります。より強固にするには、サーバー側でもリフレッシュトークンを追跡・失効させてください(拒否リストまたはローテーション)。

app.post('/auth/logout', async (req, reply) => {
  reply.clearCookie('refreshToken', { path: '/auth/refresh' })
  return reply.send({ ok: true })
})

確認テスト

JWT認証についての理解度を確認しましょう。

まとめ

JWTによるログインとリフレッシュについて学びました。

  • 短期間有効なaccessトークンと長期間有効なrefreshトークンを組み合わせます
  • POST /auth/loginで認証情報を検証し、両方に署名します
  • リフレッシュトークンはhttpOnly SameSite Secure Cookieに保存します
  • アクセストークンはボディで返し、JavaScriptのメモリ上に保持します
  • POST /auth/refreshでCookieから新しいアクセストークンを発行します

よくある質問

「JWT認証:ログインとリフレッシュ」レッスンは無料ですか?

はい。「JWT認証:ログインとリフレッシュ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Vue Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Vue Academyコースには全4レッスンが含まれています。

「JWT認証:ログインとリフレッシュ」で何を学びますか?

アクセストークンとリフレッシュトークンのフロー、httpOnly Cookie、インターセプターによるサイレントリフレッシュ ブラウザで直接実行するハンズオンコードでVue Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Vue Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのVue Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「JWT認証:ログインとリフレッシュ」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このVue Academyレッスンでコードを書いて実行できますか?

はい。すべてのVue Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Vue SPA向けFastifyバックエンド
  2. JWT認証:ログインとリフレッシュ
  3. Axiosインターセプターによる認証API呼び出し
  4. フルスタックVueの本番デプロイ
← Vue Academyに戻る