ご存じの方も多いと思いますが、わたしはAuthlete社1の社外取締役2もやっています。にも関わらず、最新の状況にキャッチアップできていなかったので、先日行われた森川氏のセミナーの動画で学習することにしました。FAPI WGでここ数週間ずっとリフレッシュトークンのローテーションのときの実装における動作に対するガイダンスの書き方が課題になっているのもあります。
本動画では、森川氏がOAuthとOIDCのプロファイリングを実現するAuthleteの機能について紹介しました。以下の主要な項目です:
- プロファイリングとは:OAuth/OIDCの仕様を自分で選び、細かい設定を行うこと。
- Authleteの紹介:OAuth/OIDC対応の認可サーバーやIDプロバイダーを構築するためのWeb APIサービス。
- トークン発行のコンテキスト:トークンのライフサイクル管理と発行の背景。
- クライアントの特性:クライアント属性をキーバリュー形式で管理し、認可決定に利用。
- スコープ管理:スコープの詳細な管理とRAR3による柔軟な認可要求。
- エンティティとメッセージの確からしさ
- クライアント認証:複数の認証方式に対応
- リクエスト・レスポンス認証:複数の認証方式(PKCE、PAR、JARM)対応。
- リソースオーナーの意図:セキュリティとユーザーエクスペリエンスの向上
- 発行するトークンの特性:有効期間、属性、プルーフオブポゼッション(MTLS、DPoP)の設定と管理。
- 発行後のトークン管理:ローテーションとリフレッシュトークンの冪等性保持。
- トークン失効API:トークンを無効化する新しいAPIの紹介。
以下、それぞれをもう少し細かく見ていきたいと思います。例によって Otio AI を駆使したまとめです。また、もとの動画を補うコンテンツが若干入っています4例によって、まちがっているところなどご指摘いただければ幸いです。
プロファイリングとは (0:48)
プロファイリングとは、OAuthやOIDCを実際に適用する際に必要な細かい設定や選択を行うことです。具体的には、仕様が示す選択肢から必要なものを選び、後から出てきた拡張仕様の中からどれを使うかを決めること、更に仕様の範囲外でも様々な決定を行うことが含まれます。例えば、ユーザー認証やスコープ設定などが代表的な例です。プロファイリングには以下のようなものが含まれます。
- OAuth/OIDCを実際に適用するための詳細な設定・選択の作業。
- 仕様が示す選択肢から必要なものを選び、拡張仕様をどのように使うかを決定する。
- 仕様の範囲外での決定事項も多い(例:ユーザー認証、スコープ設定)。
- スコープの名前や構造化など、細部まで決める作業を含む。
Authleteの紹介 (1:35)
Authleteは、認可サーバー(Authorization Server)やIDプロバイダー(Identity Provider)を構築するための部品をWeb APIで提供するサービスです。これにより、開発者は複雑なOAuth/OIDCのプロトコル処理やトークンのライフサイクル管理を簡単に実装することができます。Authleteの主な特徴は以下の通りです:
- Web APIとしての提供:
- Authleteは認可サーバーの機能をWeb APIとして提供します。これにより、開発者は自分のアプリケーションから簡単に認可の処理を呼び出すことができます。
- 認可エンジンとOIDCエンジン:
- 認可サーバーやIDプロバイダーを「認可エンジン」や「OIDCエンジン」として表現することが多いです。これは、Authleteが複数の仕様やプロファイリングに対応し、自由に選択・実装できる柔軟性を持っているためです。
- OAuth/OIDCコンポーネントアズアサービス:
- 最近では、Authleteを「OAuth/OIDCコンポーネントアズアサービス」として紹介することが増えています。これは、Authleteのサービスが単なるAPI提供に留まらず、認可サーバーの構築と運用に必要なコンポーネントを包括的に提供することを意味します。
- プロトコル処理とトークンのライフサイクル管理:
- Authleteは受け取った認可リクエストのパラメーターをチェックし、それに基づいて次のステップを案内する役割を担います。この流れは、受け取ったリクエスト情報をチェックし、問題がなければトークンの発行やライフサイクル管理を行うことを含みます。
- 多様な仕様とプロファイリングへの対応:
- Authleteは様々なOAuth/OIDC仕様とプロファイリングの実装をサポートしています。これにより、開発者は自分のユースケースに最適な仕様を自由に選択して実装することができます。
- ナレッジベースの運営:
- Authleteはナレッジベースを運営しており、Authleteの使い方や機能に関する情報を公開しています。これは、非ユーザーでもOAuth/OIDCサーバーの設計や実装に役立つ情報を提供しています。
Authleteは、認可サーバーやIDプロバイダーを簡単に構築し、運用するための包括的なソリューションを提供しています。 各種仕様やプロファイリングに対応できる柔軟性があり、開発者に自由度を与える点が特徴です。
トークン発行のコンテキスト (03:42)
トークンの発行に至るまでの経緯や背景(コンテキスト)は、多岐にわたる要素から成り立っています。このコンテキストを理解することで、アクセス制御や認可プロセスがどのように構築されているかが明確になります。主な要素は以下の通りです:
- クライアントの特性:
- 認可サーバーはクライアントの多くの属性を管理します。例えば、クライアントがファーストパーティアプリケーションかサードパーティアプリケーションか、コンフィデンシャルクライアントかパブリッククライアントか、Webアプリケーションかネイティブアプリケーションかなど。
- Authleteでは、クライアント属性をキーバリュー形式で管理し、認可リクエスト時にこの属性情報を活用して認可決定を行います。
- スコープ:
- スコープは、リソースに対する操作権限を記述しますが、単なる文字列で定義されるため、そのままでは詳細な権限管理が難しい場合があります。
- Authleteではスコープ属性機能を提供し、スコープに任意の情報をキーバリュー形式で紐付けることができます。また、クライアントごとに要求可能なスコープを制限する設定も可能です。
- エンティティとメッセージの確からしさ:
- クライアント認証とリクエストレスポンスの保護(例えばPKCE、PAR、JARMなど)が含まれます。
- クライアント認証方式やリクエストパラメータの保護方法に関する設定をサポートしています。
- リソースオーナーの意図:
- 認可リクエストで要求されたスコープをエンドユーザーに提示し、どのスコープを許可するか選ばせることができます。この実装方法もAuthleteのAPIを使って構築できます。
- トークンのライフサイクル:
- アクセストークンとリフレッシュトークンの発行から、利用、更新、無効化、削除に至るまでのライフサイクルを管理します。
- 各トークンの有効期間を認可サーバー単位、スコープ単位、クライアント単位で設定可能にする機能も提供しています。
- 証明のプルーフオブポゼッション(PoP):
- MTLSやDPoPを利用することで、アクセストークンの使用者が正当な持ち主であることを証明する仕組みを提供しています。
Authleteは、これらの要素を通じて、複雑な認可プロセスとトークンのライフサイクル管理を支援します。認可決定やトークン管理のための多様な設定と機能があるため、開発者は自分のアプリケーションに最適な構成を選択・実装することが可能です。
クライアントの特性 (05:20)
クライアントの特性は、認可サーバーがトークンを発行する際に重要な役割を果たします。具体的には以下の要素が考慮されます:
- 管理主体:
- ファーストパーティアプリケーションとサードパーティアプリケーションの区別。
- ファーストパーティの場合、開発者が直接管理しているアプリケーションであり、サードパーティの場合、第三者が提供するアプリケーションです。
- クライアントの種類:
- コンフィデンシャルクライアントとパブリッククライアントの区別。
- コンフィデンシャルクライアントは、クライアントシークレット(秘密キー)を安全に保持できるクライアント(サーバーサイドアプリケーション)。
- パブリッククライアントは、クライアントシークレットを安全に保持できないクライアント(ネイティブアプリケーションやシングルページアプリケーション)。
- アプリケーション形態:
- Webアプリケーション、ネイティブアプリケーション、シングルページアプリケーション(SPA)など、クライアントの形態によって特性が異なります。
- クライアント属性管理:
- Authleteでは、クライアントごとに任意の属性をキーバリュー形式で管理する機能を提供しています。
- これにより、クライアント属性として設定した情報を基に、認可リクエストの処理を柔軟に行えます。
- 認可リクエストの処理:
- 認可サーバーは、クライアントから受け取った認可リクエストに含まれるクライアントIDを参照し、それに紐付いたクライアント属性を確認します。
- このクライアント属性情報を用いて、認可決定を行います。
クライアントの属性設定の例
Authleteの管理コンソール画面では、以下のようにクライアント属性を設定できます:
- キー:
affiliation
- バリュー:
partner
この情報を基にして、認可サーバーは特定のクライアントに特有の処理を適用することができます。
具体例
- ファーストパーティクライアント(自社アプリ):高い権限を持つスコープのリクエストを許可。
- サードパーティクライアント(他社アプリ):限定的なスコープのみを許可。
以上が、クライアントの特性およびそれを管理・活用する方法の概要です。詳細はクライアント属性のKBを参照。
スコープ管理 (07:02)
スコープはOAuthやOIDCにおいて、リソースへのアクセス権限を表現するためのパラメータです。スコープ管理は、そのスコープの設定や制限を行うことで、ユーザーやクライアントがどの程度のアクセス権を持つかを制御する重要な要素です。Authleteでは、スコープ管理に関するいくつかの機能を提供しています:
- スコープの基本構造:
- スコープパラメータ:単純に文字列で定義され、リクエストに含められることで特定の権限を要求します。しかし、文字列としてのスコープ名だけでは、そのスコープが持つ詳細な権限を表現できないことがあります。
- スコープの構造化:
- スコープ属性:Authleteでは、スコープに任意の情報をキーバリュー形式で紐付ける「スコープ属性」機能を提供しています。これにより、スコープに関する詳細なメタデータを管理することができます。
- スコープの例:
- スコープ名:
read_profile
- スコープ属性:キーバリュー(例:キー
level
、バリューhigh
)
- スコープ名:
- クライアントごとのスコープ制限:
- Authleteでは、クライアントごとに要求できるスコープを制限する機能を提供しています。これにより、特定のクライアントが利用できるスコープを細かく制御することができます。
- 例:クライアントAはスコープ
read_profile
のみ許可、クライアントBはスコープread_profile
とedit_profile
を許可。
- 動的スコープ:
- ダイナミックスコープ:スコープ名をパラメーター化する手法です。例えば、
consent:12345
のように、スコープ名と追加情報を組み合わせて使用します。 - 正規表現:スコープ名に対して正規表現を使用して、要件に適合するスコープ名を動的に生成できます。Authleteではスコープ属性として正規表現を指定することで、動的スコープの管理が可能です。
- ダイナミックスコープ:スコープ名をパラメーター化する手法です。例えば、
- リッチオーソライゼーションリクエスト(RAR):
- RAR(Rich Authorization Requests):スコープよりも詳細で柔軟な認可要求を可能にする拡張仕様です。
authorization_details
パラメータを使用して、より細かいアクセス権限を指定します。 - Authleteでは、このRARの設定をクライアントごとに行うことができ、詳細な権限管理を実現します。
- RAR(Rich Authorization Requests):スコープよりも詳細で柔軟な認可要求を可能にする拡張仕様です。
スコープ管理の実装例
Authleteの管理コンソールでは、以下のようにスコープと属性を設定できます:
- スコープ名:
read_profile
- 属性キー:
level
- 属性バリュー:
high
これにより、スコープread_profile
の詳細な管理が可能になります。
エンティティとメッセージの確からしさ (10:06)
クライアント認証 (10:50)
クライアント認証は、クライアントが認可サーバーと安全に通信するための重要な仕組みです。特にコンフィデンシャルクライアントの場合、トークンエンドポイントでクライアント認証が求められます。具体的には以下の内容が含まれます:
1. 認証方式の選択
- クライアント認証方式として、主に以下の方法があります:
- クライアントシークレット:最も基本的な方法であり、クライアントIDとクライアントシークレット(パスワードに相当するもの)を使用します。
- クライアント証明書(mTLS):クライアント証明書を使用して相互TLSを確立し、認証を行います。
- JWTベース:JSON Web Token (JWT) を使用したクライアント認証方法です。
- その他:クライアントによってはデバイスごとに特殊な方法が要求される場合もあります。
2. Authleteでの設定
- Authleteは、サービス(認可サーバー)側の設定としてサポートするクライアント認証方式のセットを定義できます。この設定により、認可サーバー側でどの認証方式を許可するかを決めることができます。
- クライアント設定:クライアントごとにどの認証方式を利用するかを設定します。これにより各クライアントに対して適切な認証方式を選択し、セキュリティレベルを確保します。
3. Authleteの提供機能
- 認証方式の強制化:Authleteでは認証方式の利用を強制化できる機能を提供しています。これには、すべてのクライアントに対して特定の認証方式を強制する設定も含まれます。
- サービスレベルとクライアントレベルの両方で柔軟な設定を行うことができ、セキュリティ要件に応じた認証が可能です。
4. 具体例
- サービス設定:Authleteの管理コンソールで、認可サーバーに対してサポートするクライアント認証方式(例:
client_secret_basic
、client_secret_post
、client_secret_jwt
など)を設定します。 - クライアント設定:個々のクライアント設定で、上記の方法の中からそのクライアントが使用する認証方式を選択します。例えば、あるクライアントでは
client_secret_basic
を使用し、別のクライアントではclient_secret_jwt
を使用する設定が可能です。
また、いわゆるクライアント認証ではありませんが、パブリッククライアントでは必須、そうでなくてもやはり必須とされるPKCE[RFC7636]5についてもサポートしています。
リクエスト・レスポンス認証 (12:02)
リクエスト・レスポンス認証に関しては、PKCEとPARとJARMに対応しています。
PKCE (12:02)
概要
- 説明:PKCEは、OAuth 2.0の認可コードフローをセキュアにするための拡張仕様です。特にパブリッククライアントのセキュリティを向上させるために設計されています。
- 導入理由:クライアントシークレットを安全に保持できないパブリッククライアント(例えばモバイルアプリやシングルページアプリケーション)が、認可コードを窃取されるリスクを軽減します。
仕組み
- コードチャレンジ:クライアントが認可リクエストを行う際に
code_challenge
というパラメータを送信します。 - コードベリファイア:後続のトークンリクエストでは、クライアントが
code_verifier
を送信します。認可サーバーはこのcode_verifier
をcode_challenge
と比較して一致すればトークンを発行します。
Authleteのサポート
- 強制化:Authleteでは、PKCEの利用を強制化する設定があります。例えば、すべてのクライアントに対してPKCEの使用を義務付けることができます。
- チャレンジ方式の指定:
S256
などのコードチャレンジ方式を強制することも可能です。
PAR [RFC9126] (13:36)
概要
- 説明:PARは、認可リクエストのパラメータを事前に認可サーバーに登録し、それを保護するための仕様です。認可リクエストをユーザーエージェント(ブラウザ)経由で送信することで発生するセキュリティリスクを軽減します。
- 導入理由:認可リクエストのパラメータがフロントエンドに露出すると改ざんされる可能性があるため、それを防ぐためのメカニズムです。
仕組み
- 事前登録:クライアント認証を含め、すべての認可リクエストパラメータを事前に認可サーバーに送信する。
- リクエストURI:認可サーバーがリクエストURIを返し、そのURIを用いて認可リクエストを実行。
Authleteのサポート
- 専用API:Authleteでは、PARリクエストを処理する専用のAPIを提供しており、これを使用することで認可サーバーが簡単にPARを実装できます。
JARM (14:43)
概要
- 説明:JARM6は、認可レスポンスをJWT形式で保護する仕様です。これにより、認可レスポンスの完全性と信頼性を確保します。
- 導入理由:認可レスポンスの内容を暗号化および署名することで、途中で改ざんされるリスクを防止します。
仕組み
- JWT形式:認可サーバーが認可レスポンスをJWT(JSON Web Token)として返す。JWTは署名されており、場合によっては暗号化されている。
- レスポンス検証:クライアントがレスポンスを受け取った際にJWTを検証し、その完全性と発行元の正当性を確認します。
Authleteのサポート
- 複数の署名アルゴリズム:Authleteでは、JARMのレスポンスに対して複数の署名アルゴリズムや暗号化アルゴリズムに対応しています。
- 設定の柔軟性:クライアントごとにJARMの利用を設定することができます。
リソースオーナーの意図 (15:13)
リソースオーナーの意図は、認可リクエストが送信される際にリソースオーナー(通常はエンドユーザー)がどのスコープを許可するかを明確にするプロセスを指します。Authleteを使用することで、リソースオーナーの意図を反映した柔軟な認可フローを構築できます。
1. 基本的な考え方
- ユーザー参加:リソースオーナーに認可リクエストに含まれるスコープを提示し、どのスコープを許可するかを選択させます。
- 柔軟な許可:リソースオーナーが特定のスコープのみを許可することで、過剰な権限付与を防ぎます。
2. 実装方法
- AuthleteのAPIを活用:認可リクエストの処理をカスタマイズし、自社で作成するユーザーインターフェース(UI)でリソースオーナーにスコープを確認・選択させることができます。
- ナレッジベースのガイド:Authleteのナレッジベースには、これを実装するための具体的な手順が詳しく説明されています。
- 認可リクエストで要求されたスコープをエンドユーザーに提示。
- エンドユーザーが許可するスコープを選択。
- 選択結果を元に、最終的な認可レスポンスを生成。
3. 具体例
- 認可リクエストの提示:
- クライアントからの認可リクエストを受け取る。
- リソースオーナーにリクエストされたスコープ(例:
read_profile
、edit_profile
)をUI画面上で表示。 - リソースオーナーが特定のスコープ(例えば
read_profile
のみ)を選択。
- スコープの許可とレスポンス:
- リソースオーナーの選択内容を基に最終的なスコープを決定。
- 認可レスポンスに選択されたスコープを含めて生成。
- 選択されたスコープのみを認可トークンに含める。
4. ナレッジベースの利用
- 具体的なコードとガイド:
- Authleteのナレッジベースには、これらのプロセスを実装するための具体的なAPI使用例やコードサンプルが含まれています。
- 実装の詳細やステップバイステップのガイドが提供されていますので、これを参考にすることで効率的に開発が進められます。
リソースオーナーの意図を反映する認可フローを設計することで、エンドユーザーにとってより細かい制御が可能となり、セキュリティとユーザーエクスペリエンスの向上が期待できます。また、Authleteの機能を活用することで、このプロセスをスムーズに実装することができます。
ここまでで、トークンの発行まではできるようになりました。次に発行するトークンの特性について説明します。
発行するトークンの特性 (16:05)
有効期間
- 決定方法:トークンの有効期間は、認可サーバー、スコープ、クライアントの各単位で設定できます。また、トークン発行時に特定の有効期間をリクエストパラメーターとして指定することも可能です。
- 優先順位:複数の条件に合致する場合、最も短い有効期間が適用されます。
- 設定の柔軟性:Authleteでは、トークンごとに有効期間を秒単位で細かく設定でき、発行時に特定の条件を満たすために有効期間を動的に変更できるAPIも提供しています。
トークン属性
- 概要:トークンに任意の属性をキーバリュー形式で紐付けることができます。
- 代表的な属性:クライアントID、ユーザー識別子、スコープ、クライアント区分、ユーザーのロールなど。
- 用途:リソースサーバーがトークンを検証する際に、単に有効かどうかだけでなく、トークンの発行元やコンテキストに関する詳細な情報を取得するために利用されます。
トークンに任意のプロパティをひもづける方法はKnowldege Baseを参照。
リソースサーバーへの属性の渡し方
- アクセストークンの形式:
- 識別子型:リソースサーバーがトークンをイントロスペクトして情報を取得します。
- 内包型:トークン自体に属性情報を直接埋め込んでいます。
- ハイブリッド型:上記2つの利点を併せ持つアプローチ。
プルーフオブポゼッション
- MTLS(相互TLS):
- 仕組み:TLSクライアント証明書を用いて認証し、トークンとクライアント証明書を紐付けます。認可サーバーは証明書が事前に登録されているか確認します。リソースサーバーでも同様に証明書を確認します。
- TLS クライアント証明書を結びつけたアクセストークンの発行 参照
- DPoP(デモンストレーティブ・プルーフオブポゼッション):
- 仕組み:公開鍵と秘密鍵のペアを用いて、DPoP Proof JWTを生成し、これをアクセストークンに紐付けます。アプリケーションレイヤーでプルーフオブポゼッションを実現するメカニズムです。
- 設定:Authleteでは、クライアント単位でDPoPの利用を強制する設定が可能です。
- DPoP の利用 参照
発行後のトークン管理 (22:38)
リフレッシュトークンの継続利用とローテーション
- 継続利用:リフレッシュトークンの値を更新せず、そのまま利用し続ける設定。
- ローテーション(継続利用しない):リフレッシュトークンの値を更新し、新しいトークンとして発行。トークンをリフレッシュするたびに値が変わります。
- 有効期間のリセット:リフレッシュトークンの値を更新する際に、有効期間をリセットするかどうかを選択可能です。リセットすると、有効期間のカウントが新たに始まります。
- 有効期間引き継ぎ:新しいリフレッシュトークンの有効期限は古いリフレッシュトークンの有効期限にセットされます。
- 詳細は、リフレッシュトークンの継続利用設定にあります。
リフレッシュトークンの冪等性 (24:27)
- トークン並行リフレッシュ問題:トークンの値を更新するに設定してあるとき、トークンリフレッシュを行うたびにリフレッシュトークンの値が更新されます。すると、複数のクライアントから短い間に複数のトークンリクエストが来た時、最初のもの以外は無効なトークンエラーとなります。
- 解決策:Authleteでは、リフレッシュトークンの冪等性という設定により、短期間に同じリフレッシュトークンを使った複数のリフレッシュリクエストがあった場合、すべてのリクエストに同じ新しいリフレッシュトークンを返すことで、この問題を緩和しています。
トークン失効API (26:02)
トークン失効(Revoke)APIは、特定のトークンや条件に基づいて関連するすべてのトークンを無効化(リボーク)するための機能を提供します。これは、セキュリティを維持しつつ、不要なトークンの利用を防ぐ上で重要です。
1. 基本機能
- 個別トークンの失効:特定のアクセストークンやリフレッシュトークンを無効化することができます。
- 条件に基づく失効:特定のクライアントまたはリソースオーナーに関連するすべてのトークンを無効化することができます。
2. 失効のリクエスト方法
- クライアントからのリクエスト:
- RFC 7009に準拠:アクセストークンやリフレッシュトークンの値を指定してトークンを無効化する標準仕様。実装方法:AuthleteのトークンリボークAPIを利用して、クライアントが特定のトークンを無効化。
POST /revoke HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
token=45ghiukldjahdnhzdauz&token_type_hint=refresh_token
- リソースオーナー・認可サーバーからのリクエスト:
- 条件に基づく失効:クライアントやリソースオーナーに関連するすべてのトークン(アクセストークンおよびリフレッシュトークン)を一括で無効化。
- APIの使用:Authleteの新しいトークンリボークAPIでは、より柔軟に失効条件を設定できます。
POST /api/auth/token/revoke
Host: api.authlete.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
{
"subject": "リソースオーナーの識別子",
"client_id": "クライアントID"
}
3. 利用例
- 例1:ユーザーがパスワードを変更した場合、そのユーザーに関連するすべてのアクセストークンとリフレッシュトークンを失効させる。
- 例2:あるクライアントアプリケーションが不正行為を行っていることが判明した場合、そのクライアントに関連するすべてのトークンを一括で失効させる。
4. 有効期限とトークン管理
- 有効期限切れのトークン:トークンの失効処理は、基本的に有効期限内のトークンを対象としていますが、有効期限が過ぎたトークンに関してもデータベースから削除するなどの管理が必要です。
- 失効後の取り扱い:失効したトークンは再利用できず、リソースサーバーはイントロスペクションを行ってトークンの有効性を確認します。
Authleteのトークン失効APIは、このようにさまざまなシナリオに対応できる柔軟性と高いセキュリティを提供します。これにより安全かつ効果的にトークン管理が行えます。
まとめ
- OAuth/OIDCのプロファイリングには、認可に至った経緯やリソースサーバーの要求情報、ライフサイクル管理とセキュリティ対策などを考慮する必要がある
- ベストカレントプラクティス(BCP)やFAPIなどを参考にするとよい
- Authlete社のテンプレートやAPIリファレンスを参考にできる
脚注
- Authleteは高セキュリティなOAuth/OIDC実装をサポートし、FAPI(Financial-grade API)などの規格も推進。
- 新しく作る仕様を次々に実装してくれることもあり、社外取締役として参加させていただいています
- Rich Authorization Request
- Otio は、対象としている文書等のみを使って資料を作ることになっていますが、動画を読み込ませるときGPT-4oによる文章化をしているので、そのときに補完されてしまうように見えています。
- 読み方:ピクシー(妖精)
- JWT Secured Authorization Mode
@_Nat Zoneをもっと見る
購読すると最新の投稿がメールで送信されます。