概要
マイクロサービスにおけるセッション管理の手法として再び注目されているJWTですが、今一度JWTについて理解を深めましょう!
JWTをしっかり理解すれば、アクセス制御、認証、認可においても困ることが少なくなるはずです。
JWTとは
JWT(JSON Web Token)とは、当事者間でデータをJSONとして安全に送信するための規格です。
コンパクトでURLセーフな表記ルールが定められています。
jwt.io は、JSON Web Token (JWT) のデコード、検証、生成を可能にする無料のWebサイトです。開発者はこのツールを活用することで、JWT の仕組みを理解し、実際にトークンを生成・検証することができます。
JWTは、認証や認可の仕組みにおいて広く活用されており、セキュアなデータ交換を実現するための重要な技術となっています。
JWTの特徴
まずはJWTの特徴を理解しておきましょう。
- コンパクト
よく使うデータ項目のキー名を省略形にすることで、データサイズをコンパクトにしています。
- URLセーフ
JSONデータをBASE64URLエンコードすることで、URLに直接記載できる(URLセーフな)エンコード方式を採用しています。
つまり、JWTは少ない文字数でエンコードされた文字列を送信する際に重宝されています。
JWTの主な利用用途
一般的なJWTの利用用途は以下のようなものがあります。
- OAuth 2.0、OpenID Connectなどの認証プロトコルにおけるトークン
- Cokkieを使うのが難しいマイクロサービスやモバイルアプリでのセッション管理
- シングルサインオン(SSO)での認証
- RESTful APIの認証
- ステートレス認証
ここで疑問に思うのは、なぜエンコードされただけのJWTが認証に使われるのでしょうか?
その理由は、セキュアなデータ転送を実現するJWTのルールにあります。
JWTのルール
ルール
- クレームをJSON形式で表現した文字列であること
- JOSEに従って署名 or 暗号化がされていること
- BASE64URLでエンコードされた文字列であること
- 複数ブロックに分かれる場合は、
.(ピリオド)
で区切る
(※クレーム、JOSEは後述)
クレームとは
- JWTではJSONのキーと値のペアをクレームと呼び、キーをクレーム名、値をクレーム値と呼びます。
- クレームの集合体はクレームセットと呼びます。
クレームには主にユーザー情報や、アプリケーションが利用する情報などが記載されています。
JWTの例
エンコード前
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
エンコード後
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
JOSEとは
「JOSEに従って署名 or 暗号化がされていること」がJWTのルールの一つとして出てきました。
この署名 or 暗号化のルールこそがJWTの肝になっています。
定義
JOSE(JSON Object Signing and Encryption)とは、JWTの署名と暗号化に関するルールを定めた規格です。
そのうち、JWTの署名に関するルールをJWS、JWTの暗号化に関するルールをJWEと呼びます。
(※JWSは後述)
JWSとは
定義
JWS(JSON Web Signature)とは、JWTにデジタル署名を付与する際のルールを定めた規格です。
JWTに署名を使用することで、JWTの改ざんを検知することができるようになります。
【補足】JWTの改ざんとは
JWT単体ではBASE64URLでエンコードしただけの文字列です。
もし悪意のある攻撃者がいれば、JWTをデコードした後、権限を修正し、再びエンコードするだけで簡単に不正アクセスできてしまいます。
そこで、改ざんされた場合のリスクが大きい情報の送受信にJWTを使う場合は、改ざんを検知できるJWSを使用しているのです。
(※トークンの有効期限を短く設定したり、クレームを正確に設定することも改ざんリスクの対策になります。)
JWSのルール
JWSは、ヘッダー
.ペイロード
.シグネチャー
の3つから構成されます。
それぞれをBASE64URLエンコーディングした後、ピリオドで結合します。
ヘッダー
JWTの署名に必要な以下の2つの情報を記載する部分です。
- 使用されている署名アルゴリズム (HMAC SHA256 や RSA など)
- トークンの種類 (通常はJWTを指定)
ペイロード
実際のデータ(クレーム)を記載する部分です。
主にユーザー情報や有効期限、発行者などを記載します。
シグネチャー
署名を記載する部分です。
署名とは、 ヘッダー
と ペイロード
を結合したあと、暗号化して生成したトークンのことです。
この暗号化された署名と、実際のデータを照らし合わせることで、改ざんが行われたかどうかを検知することができます。
JWSの例
JWS準拠のJWTの例(エンコード前)
{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "1234567890",
"exp": 1634710708
}
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secretKey
)
JWS準拠のJWTの例(エンコード後)
それぞれをエンコードした後、さらに .(ピリオド)
で結合します。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwiZXhwIjoxNjM0NzEwNzA4fQ.
v40uDSCoa14j59CVD0bH-ZqnwYA_XF4aS7QEM_FZ8HM
JWTを利用したアクセス制御
JWSを用いたJWTは、改ざんを検知できるうえに、ユーザー情報やアクセス権限を含むこともできるという利点があります。
これを活かして、アクセス制御を簡素化するためにJWTを使用することが多いようです。
Webサイトでの使用例
Webサイトで認証・認可にJWTを使用した場合、以下のようになります。
- クライアントがID・パスワードなどの認証情報をサーバーに送信
- サーバーがDBの情報と照合し、認証に成功すればJWT形式のアクセストークンを発行してレスポンスで返す(認証)
- クライアントがリソースにアクセスするときは、発行されたアクセストークンを付けてリクエストを送信
- サーバーがアクセストークン(JWT)を検証し、トークンに含まれる権限に基づいてリソースへのアクセスを許可/拒否する(認可)
このように、JWTのアクセストークンを使用することで、リソースへのアクセス制御が簡単かつ安全に実現できます。
認証プロトコルでの使用例
OpenID ConnectやOAuth 2.0という認証プロトコルでは、トークンの記述方法にJWTを採用しています。
-
例 : OAuth 2.0 Authorization Grants (認可)
POST /token.oauth2 HTTP/1.1 Host: as.example.com Content-Type: application/x-www-form-urlencoded grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer& assertion=eyJhbGciOiJFUzI1NiIsImtpZCI6IjE2In0.eyJpc3Mi[...omitted for brevity...].J9l-ZhwP[...omitted for brevity...]
他にもOAuth 2.0の認証や、OpenID ConnectのIDトークンにも使用されています。
アクセス制御にJWTを使用するメリット
JWTをアクセス制御に使うメリットは、主に認可処理の簡素化にあります。
- ステートレスな認可処理 JWT内にユーザー情報やスコープが含まれているので、サーバー側でセッション管理を実装する必要がなくなる
- 整合性の確保 JWSでデータが改ざんを検知することができる
- 発行者の証明 JWSで署名に発行者の秘密鍵が使用されるので、発行者によるリクエストであると証明できる
- 機密性の確保 JWEと組み合わせることで暗号化もできる
認証処理自体へのメリットは少ないですが、一度認証が済めば、JWTによってユーザー情報やアクセストークンなどを安全にやり取りできるので、それ以降の認可処理が簡素化されるのです。
他の規格との比較
ここで、よく比較対象としてあがるSAMLについても少しだけ理解しておきましょう。
どちらも認証・認可に使用される規格です。
SAML (Security Assertion Markup Language)
- XMLベースのトークンの規格 (※)
- IDプロバイダ(IdP)がトークンを発行するので、セキュリティ面で安心できる
- 有効期限や発行者など必須項目が多く、複数のサービス間で連携しやすい(相互運用性)という点でシングルサインオン(SSO)に特化した設計
- 認証コンテキスト(ユーザーがどんな認証方式で認証されたかという情報)を記載できる
※JSONベースの形式(SAML2.0のJSONプロファイル)もある
JWTとSAMLの比較表
項目 | JWT | SAML |
---|---|---|
主な目的 | 認可処理の簡素化 | 認証処理の相互運用性の向上 |
用途 | アクセストークン | SSO認証 |
サイズ | コンパクト | 大きい |
属性情報 | 最小限の情報 | ユーザー情報などを多く記載 |
有効期限 | オプション(expで指定可) | 必須 |
認証コンテキスト | 記載できない | 記載できる |
発行ロジックの実装者 | リソース所有者が自ら実装 | IdPが実装 |
JWTとSAMLのどちらを使うべきか
どちらも認証・認可に使う規格ですが、用途が異なるため適切な規格を選ばなければなりません。
それでもどちらを使用すべきか悩む場合は、以下の項目を参考にしてみてください。
【JWTを使うべきケース】
- アクセストークンの発行を目的とする場合
- ステートレスなアーキテクチャが求められる場合
- モバイルアプリなどクライアント側でトークンを保持する必要がある場合
- データペイロードをコンパクトに保ちたい場合
- 柔軟性が求められ、独自の属性をクレームに含める場合
- シンプルかつ簡単に認証を実装したい場合
【SAMLを使うべきケース】
- シングルサインオン(SSO)の実現を主な目的とする場合
- 統合された認証基盤が必要な場合(IDプロバイダからのトークン発行)
- 認証コンテキストの伝達や、厳密な属性要件がある場合
- XML形式での運用が前提の既存システムとの連携が必要な場合
まとめ
JWTは認証・認可、アクセス制御においてとても重要なので、理解しておけば必ず役に立ちます。
ここで豆知識ですが、JWTは「ジョット」と発音するのが一般的で、文脈によっては「ジェイ・ダブリュー・ティー」「ジェイソン・ウェブ・トークン」とも言います。
JWTの仕組みと合わせて発音も知っておけば、突然「ジョットが~」と話題に上がった時、焦らなくて済むでしょう。
【番外編】USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話
プログラミング塾に半年通えば、一人前になれると思っているあなた。それ、勘違いですよ。「なぜ間違いなの?」「正しい勉強法とは何なの?」ITを学び始める全ての人に知って欲しい。そう思って書きました。是非読んでみてください。
「フリーランスエンジニア」
近年やっと世間に浸透した言葉だ。ひと昔まえ、終身雇用は当たり前で、大企業に就職することは一種のステータスだった。しかし、そんな時代も終わり「優秀な人材は転職する」ことが当たり前の時代となる。フリーランスエンジニアに高価値が付く現在、ネットを見ると「未経験でも年収400万以上」などと書いてある。これに釣られて、多くの人がフリーランスになろうとITの世界に入ってきている。私もその中の1人だ。数年前、USBも知らない状態からITの世界に没入し、そこから約2年間、毎日勉学を行なった。他人の何十倍も努力した。そして、企業研修やIT塾で数多くの受講生の指導経験も得た。そこで私は、伸びるエンジニアとそうでないエンジニアをたくさん見てきた。そして、稼げるエンジニア、稼げないエンジニアを見てきた。
「成功する人とそうでない人の違いは何か?」
私が出した答えは、「量産型エンジニアか否か」である。今のエンジニア市場には、量産型エンジニアが溢れている!!ここでの量産型エンジニアの定義は以下の通りである。
比較的簡単に学習可能なWebフレームワーク(WordPress, Rails)やPython等の知識はあるが、ITの基本概念を理解していないため、単調な作業しかこなすことができないエンジニアのこと。
多くの人がフリーランスエンジニアを目指す時代に中途半端な知識や技術力でこの世界に飛び込むと返って過酷な労働条件で働くことになる。そこで、エンジニアを目指すあなたがどう学習していくべきかを私の経験を交えて書こうと思った。続きはこちらから、、、、
エンベーダー編集部
エンベーダーは、ITスクールRareTECHのインフラ学習教材として誕生しました。 「遊びながらインフラエンジニアへ」をコンセプトに、インフラへの学習ハードルを下げるツールとして運営されています。
関連記事
2020.02.25
完全未経験からエンジニアを目指す爆速勉強法
USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話
- キャリア・学習法
- エンジニア
2023.08.29
WEB開発の基礎 フロントエンドとバックエンドの連携とAPIの役割
この記事ではWeb開発の核心となる「フロントエンドとバックエンドの違い」とその連携でいられる「API」についてご紹介します。
- プログラミング
2024.04.29
超初心者向け!プログラミングの基礎を30分で身につける
「副業できたらな」「リモートで仕事したいな」と考えたことはありませんか?スキル次第では実現可能です。とりあえず、プログラミングスキルを身につけると、次のようなメリットがあります。
- Python
- プログラミング
2023.01.31
静的型付け言語とは何か?特徴や適したプロジェクトを解説
こちらの記事では型付けとは何か、その必要性について解説し、併せて静的型付け言語の特徴についてまとめています。
- プログラミング