【Symfony】JWT(JSON Web Token)を用いた認証について

こんにちは、masumasuです。
日増しに寒さが厳しくなり、冬の訪れを感じる季節ですね。皆様いかがお過ごしでしょうか。
現在、 SymfonyにおけるJWT(JSON Web Token)を用いた認証 についての学習を行っていますがそこで躓いた箇所を書いていきます。

基本的な概念からSymfonyでの実装手順まで詳しくご紹介します。

JWTとは?

JWT(JSON Web Token)は、ユーザー認証やデータ交換のために広く利用されるトークンベースの認証技術です。以下の特徴を持っています:

軽量性: JSON形式で構成されており、HTTPヘッダーやURLクエリ文字列に埋め込んで送信可能。

自己完結性: トークン自体に認証情報やその他の必要なデータが含まれているため、状態を保存する必要がありません。

安全性: トークンは署名(HMACやRSAなど)されており、改ざんを防ぐ仕組みを備えています。

JWTは大きく以下の3つの部分で構成されています:

Header(ヘッダー): アルゴリズムやトークンのタイプを指定。

Payload(ペイロード): ユーザー情報やカスタムクレーム(データ)を含む。

Signature(署名): HeaderとPayloadを基に生成された暗号化された文字列。

これらをドット (.) で区切った形(例: xxxx.yyyy.zzzz)で表現され、サーバーとクライアント間でやり取りされます。

SymfonyでのJWT認証を構築する

SymfonyでJWTを用いた認証を実装するには、主に以下のステップを踏みます。

1. 必要なライブラリをインストール

SymfonyでJWT認証を扱うには、lexik/jwt-authentication-bundle が便利です。

以下のコマンドでインストールします:

composer require lexik/jwt-authentication-bundle

また、トークン生成に必要なOpenSSLをセットアップしておきましょう:

mkdir -p config/jwt
openssl genrsa -out config/jwt/pri
vate.pem -aes256 4096
openssl rsa -pubout -in config/jwt/private.pem -out config/jwt/public.pem
2. バンドルの設定

次に、インストールしたバンドルを設定します。

以下のように config/packages/lexik_jwt_authentication.yaml を編集します:

lexik_jwt_authentication:
secret_key: '%kernel.project_dir%/config/jwt/private.pem'
public_key: '%kernel.project_dir%/config/jwt/public.pem'
pass_phrase: 'your-passphrase' # OpenSSLで設定したパスフレーズ
token_ttl: 3600 # トークンの有効期限(秒)
3. ユーザー認証の設定

Symfonyのセキュリティシステムと連携させるために、security.yaml を設定します:

security:
firewalls:
api:
pattern: ^/api
stateless: true
jwt: ~
providers:
app_user_provider:
entity:
class: App\Entity\User
property: email
encoders:
App\Entity\User:
algorithm: bcrypt
4. ログインエンドポイントの作成

トークンを発行するためのエンドポイントを作成します。

例えば /api/login を使用する場合、コントローラを作成する必要がありますが、LexikJWTAuthenticationBundle が提供するデフォルトの /login_check を利用することも可能です。

routes:
login_check:
path: /api/login
methods: [POST]

まとめ

今回は SymfonyにおけるJWT(JSON Web Token)を用いた認証 について書きました。

ご覧いただきありがとうございます。