カテゴリ: Spring認証(Spring Security) 更新日: 2026/01/02

JWTの発行と検証の流れを初心者向けにやさしく解説!Spring環境で学ぶトークン管理の基本

JWTの発行と検証の流れ
JWTの発行と検証の流れ

新人と先輩の会話形式で理解しよう

新人

「先輩、JWTっていう単語をよく見かけるんですが、これは何なんですか?」

先輩

「JWTはJSON Web Tokenの略で、システム間やクライアントとサーバー間で安全に情報をやり取りするための仕組みだよ。」

新人

「安全にやり取りって具体的にどういうことですか?」

先輩

「簡単に言うと、サーバーが発行する署名付きの情報パッケージをクライアントが保持して、それを使ってログイン状態や権限を確認できる仕組みなんだ。」

新人

「なるほど!じゃあまずは基本から教えてください!」

1. JWTとは何か

1. JWTとは何か
1. JWTとは何か

JWT(JSON Web Token)は、JSON形式のデータを安全にやり取りするためのトークンフォーマットです。特にWebアプリケーションやAPIでの認証や情報の安全な伝達に使われます。JWTの発行と検証の流れを理解すると、ログイン機能やアクセス制御を効率的に実装できるようになります。

JWTは暗号化された署名を含んでおり、改ざんを防ぐことができます。そのため、クライアントとサーバー間で信頼できる情報を送受信できます。Spring Frameworkでも、JWTの発行検証は簡単に組み込むことが可能です。

2. JWTが使われる背景と目的

2. JWTが使われる背景と目的
2. JWTが使われる背景と目的

従来のWebアプリケーションでは、ユーザーのログイン状態を維持するためにサーバー側でセッション情報を管理していました。しかし、APIやマイクロサービスの普及により、セッション管理だけでは不便になってきました。

そこで登場したのがJWTです。JWTを使えば、ユーザー情報や認証状態をトークンに含めてクライアント側で保持できます。サーバーはそのトークンを検証するだけで認証が可能になるため、ステートレスな認証を実現できます。

例えば、ショッピングサイトやSNSでは、ログイン後に複数のサーバーを経由しても認証情報が維持されます。これはJWTによる発行と検証の仕組みが支えているからです。

3. JWTの基本構造

3. JWTの基本構造
3. JWTの基本構造

JWTは3つの部分で構成されています。

  • Header(ヘッダー):トークンの種類や署名アルゴリズムの情報
  • Payload(ペイロード):ユーザーIDや有効期限などの実際のデータ
  • Signature(署名):ヘッダーとペイロードを秘密鍵で署名したもの

それぞれの部分はBase64でエンコードされ、ドット.で区切られた文字列になります。


public class JwtExample {
    public static void main(String[] args) {
        String header = "{ \"alg\": \"HS256\", \"typ\": \"JWT\" }";
        String payload = "{ \"sub\": \"user123\", \"exp\": 1672531199 }";
        String signature = "署名部分";
        String jwt = header + "." + payload + "." + signature;
        System.out.println(jwt);
    }
}

{ヘッダー}.{ペイロード}.{署名}

実際には、このJWTをサーバーが発行し、クライアントがHTTPリクエストのヘッダーに付けて送信します。そしてサーバー側で検証を行い、正しいトークンであればアクセスを許可します。

Spring環境でのJWT発行と検証の前提

この記事では、pleiadesを使用してGradleプロジェクトを作成し、@Controllerで処理を行います。依存関係はpleiadesのチェック機能で追加し、Spring以外の不要なライブラリは使いません。このように環境を統一することで、初心者でも迷わずにJWTの発行と検証を学べます。

4. JWTの発行手順(Spring環境での実装例)

4. JWTの発行手順(Spring環境での実装例)
4. JWTの発行手順(Spring環境での実装例)

JWTの発行は、ユーザーがログインに成功したタイミングで行うのが一般的です。Spring環境では、認証処理を行ったあとにトークンを生成し、そのトークンをクライアントへ返します。トークンにはユーザーの識別情報や有効期限などを含めます。

ここでは、pleiadesで作成したGradleプロジェクトにおいて、@Controllerを使ったシンプルなJWT発行の例を紹介します。依存関係はpleiadesのチェックで追加し、外部ライブラリは最小限にします。


@Controller
public class AuthController {

    @PostMapping("/login")
    public ResponseEntity<String> login(@RequestParam String username, @RequestParam String password) {
        if ("user".equals(username) && "pass".equals(password)) {
            String token = JwtUtil.generateToken(username);
            return ResponseEntity.ok(token);
        }
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("認証失敗");
    }
}

public class JwtUtil {
    private static final String SECRET_KEY = "mysecretkey";
    public static String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 1000))
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }
}

この例では、ユーザー名とパスワードを受け取り、認証に成功した場合にJWTを発行します。トークンは有効期限付きで生成され、改ざん防止のために署名が付けられます。

5. JWTの署名と秘密鍵の役割

5. JWTの署名と秘密鍵の役割
5. JWTの署名と秘密鍵の役割

JWTの重要なポイントのひとつが署名部分です。署名は、トークンが改ざんされていないことを保証するために使われます。Spring環境では、この署名を生成するために秘密鍵(または共有鍵)を使用します。

秘密鍵はサーバー側で厳重に管理し、絶対に外部に漏らさないようにします。この鍵を使って署名を作成し、クライアントから送られてきたトークンの検証時にも同じ鍵で署名をチェックします。


public static boolean validateToken(String token) {
    try {
        Jwts.parser()
            .setSigningKey(SECRET_KEY)
            .parseClaimsJws(token);
        return true;
    } catch (JwtException e) {
        return false;
    }
}

この検証処理では、署名が一致すればトークンは正しいと判断されます。逆に署名が異なればトークンは無効となり、アクセスは拒否されます。これにより、JWTの検証プロセスは安全性を高めます。

6. JWTをHTTPレスポンスに含めて送信する方法

6. JWTをHTTPレスポンスに含めて送信する方法
6. JWTをHTTPレスポンスに含めて送信する方法

JWTの発行後、クライアントに返す方法はいくつかありますが、最も一般的なのはHTTPレスポンスのボディに含める方法です。また、Authorizationヘッダーに設定して返すことも多いです。


@PostMapping("/login")
public ResponseEntity<String> login(@RequestParam String username, @RequestParam String password) {
    if ("user".equals(username) && "pass".equals(password)) {
        String token = JwtUtil.generateToken(username);
        return ResponseEntity.ok()
                .header(HttpHeaders.AUTHORIZATION, "Bearer " + token)
                .body("ログイン成功");
    }
    return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("認証失敗");
}

このようにヘッダーに含めて返せば、クライアント側は次回以降のリクエストでこのトークンをそのまま使えます。例えば、APIアクセス時にAuthorizationヘッダーを付けて送信することで、サーバーはトークンを検証してアクセスを許可します。

HTTPレスポンスにJWTを含める際は、HTTPS通信を必ず使うことで盗聴や改ざんを防止できます。これにより、JWTの発行から検証までの流れが安全に実現できます。

補足:SpringでのJWT運用のポイント

JWTを使うと、サーバー側でセッション情報を保持せずに認証が可能になりますが、いくつかの注意点があります。有効期限を短く設定して不正利用を防ぐこと、リフレッシュトークンを活用して安全に再発行すること、そして秘密鍵の管理を徹底することです。これらのポイントを押さえて運用すれば、JWTの発行と検証は非常に強力な認証手段となります。

7. JWTの検証手順(Spring環境での実装例)

7. JWTの検証手順(Spring環境での実装例)
7. JWTの検証手順(Spring環境での実装例)

JWTの検証は、クライアントから送られてきたトークンが正しいかどうかを確認するための重要な工程です。サーバーは受け取ったトークンの署名や有効期限をチェックし、不正なトークンや期限切れのトークンを拒否します。これにより、認証されたユーザーだけが保護されたリソースへアクセスできるようになります。

Spring環境では、リクエストを受け取るコントローラの処理内やフィルタを使ってこの検証を行います。秘密鍵を使ってトークンを解析し、署名や発行者、有効期限を確認します。


@Controller
public class SecureController {

    @GetMapping("/secure-data")
    public ResponseEntity<String> getSecureData(@RequestHeader("Authorization") String authHeader) {
        String token = authHeader.replace("Bearer ", "");
        if (JwtUtil.validateToken(token)) {
            return ResponseEntity.ok("保護されたデータにアクセス成功");
        }
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("トークンが無効または期限切れです");
    }
}

この例では、HTTPリクエストヘッダーからAuthorizationを取得し、Bearerスキームを取り除いたトークンを検証メソッドに渡しています。検証に成功すればアクセスを許可し、失敗すればエラーレスポンスを返します。

8. JWTの有効期限と更新(トークンのリフレッシュ)

8. JWTの有効期限と更新(トークンのリフレッシュ)
8. JWTの有効期限と更新(トークンのリフレッシュ)

JWTには有効期限が設定されており、この期限を過ぎるとトークンは無効になります。有効期限はexpクレームとしてペイロードに含まれ、サーバーの検証時にチェックされます。

短い有効期限はセキュリティを高めますが、ユーザーは頻繁に再ログインが必要になります。そのため、実際の運用では「リフレッシュトークン」を使ってアクセス用トークンを再発行する仕組みがよく利用されます。


public static String refreshAccessToken(String refreshToken) {
    if (validateToken(refreshToken)) {
        String username = getUsernameFromToken(refreshToken);
        return generateToken(username); // 新しい有効期限で発行
    }
    throw new RuntimeException("無効なリフレッシュトークン");
}

この例では、リフレッシュトークンの検証に成功した場合に新しいアクセス用JWTを発行しています。こうすることで、ユーザーは長期間ログイン状態を維持できますが、万一トークンが漏洩した場合のリスクもあるため、リフレッシュトークンの保存や送信には特に注意が必要です。

9. JWT利用時のセキュリティ上の注意点

9. JWT利用時のセキュリティ上の注意点
9. JWT利用時のセキュリティ上の注意点

JWTを安全に利用するためには、いくつかの重要なポイントを守る必要があります。以下に代表的な注意点を挙げます。

  • HTTPS通信の使用:JWTは暗号化されない部分(ペイロード)を含むため、平文通信では盗聴される可能性があります。常にHTTPSを使用しましょう。
  • 短めの有効期限設定:トークンの寿命を短くすることで、万が一盗まれても悪用できる時間を制限できます。
  • 署名鍵の厳重管理:秘密鍵は絶対に外部に漏らさないようにし、アクセス制御の厳しい場所に保管します。
  • 不要な情報の格納禁止:ペイロードには機密情報を直接含めないようにします。JWTは誰でもデコード可能であるためです。
  • トークンの無効化戦略:ログアウト時や権限変更時に特定のトークンを無効化する仕組みを設けます。

特に、JWTは発行後にサーバー側で内容を変更できないため、発行時点で必要な情報だけを入れる設計が重要です。また、長期間の利用や高セキュリティが求められる場合は、署名アルゴリズムの選択や鍵管理の仕組みを慎重に設計する必要があります。

まとめに代えて:安全なJWT運用のために

JWTの発行と検証は、Webアプリケーションの認証とセキュリティにおいて非常に有用ですが、使い方を誤ると脆弱性を生む原因にもなります。今回解説したSpring環境での発行手順、検証方法、有効期限の管理、セキュリティ上の注意点を押さえることで、安全で信頼性の高いトークンベース認証を実装できます。

最終的には、運用環境やアプリケーションの特性に応じて、JWTの発行ポリシーや検証ルールを柔軟に設計し、必要に応じて他のセキュリティ技術と組み合わせて防御力を高めることが重要です。

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

JWTとは何ですか?JSON Web Tokenの意味と役割について知りたいです。

JWT(JSON Web Token)とは、WebアプリケーションやAPIで使われる認証情報を含むトークンのことです。署名付きのJSON形式で、ユーザー情報やログイン状態を安全にクライアントとサーバー間でやり取りできます。
コメント
コメント投稿は、ログインしてください

まだ口コミはありません。

カテゴリの一覧へ
新着記事
New1
SpringのWeb開発(Spring MVC)
ViewResolverの設定と使い方を完全ガイド!初心者でもわかるSpring MVCのビュー解決
New2
Thymeleaf
Thymeleaf th属性の種類まとめ!初心者向けに解説
New3
Thymeleaf
初心者向けにThymeleaf 公式ドキュメントの活用法とおすすめ情報
New4
Spring認証(Spring Security)
ユーザー認証・認可ログの種類を完全解説!Spring Securityで理解するログの基本
人気記事
No.1
Java&Spring記事人気No1
SpringのWeb開発(Spring MVC)
ルーティングとは?基本概念(Spring MVCのURL制御を理解)
No.2
Java&Spring記事人気No2
Thymeleaf
Thymeleaf とは?初心者向けにThymeleafの基本を徹底解説
No.3
Java&Spring記事人気No3
Springの基本
Spring Bootの環境変数の設定方法をやさしく解説!初心者向けapplication.propertiesの使い方
No.4
Java&Spring記事人気No4
SpringのDB操作
JPAの標準クエリメソッド(findById, findAll)を完全解説!初心者でもわかるデータ取得の基本
No.5
Java&Spring記事人気No5
Springの基本
application.properties と YAML の基本をやさしく解説!初心者向けSpring Boot設定ファイル入門
No.6
Java&Spring記事人気No6
Springの基本
Spring Bootのデフォルトログ設定を徹底解説(Logback / SLF4J)
No.7
Java&Spring記事人気No7
Spring認証(Spring Security)
セッション管理の基本(@SessionAttributes)を完全解説!初心者でもわかるセッションの仕組み
No.8
Java&Spring記事人気No8
SpringのDB操作
@Queryを使ったカスタムクエリの作成を完全解説!Spring Data JPAでの使い方と基礎知識