ホームページ >バックエンド開発 >PHPチュートリアル >OAuth 2.0を理解する
OAuth 2.0 について
OAuth は、世界中で広く使用されているオープン ネットワーク標準です。現在のバージョンはバージョン 2.0 です。
この記事では、OAuth 2.0 の設計思想と運用プロセスについて簡潔に説明します。主な参考資料は RFC 6749 です。
OAuth の適用可能なシナリオを理解するために、仮説的な例を示します。
Google 上にユーザーが保存した写真を印刷できる「クラウド プリント」 Web サイトがあります。このサービスを利用するには、Google に保存されている写真を「クラウド プリント」に読み込ませる必要があります。
問題は、Google がユーザーの承認を得た場合にのみ、「クラウド プリント」にこれらの写真の読み取りを許可することです。では、「クラウドプリント」はどのようにしてユーザーの承認を得ているのでしょうか?
従来の方法では、ユーザーは「クラウド プリント」に Google ユーザー名とパスワードを伝え、後者はユーザーの写真を読み取ることができます。このアプローチにはいくつかの重大な欠点があります。
(1) 「クラウド プリント」は、以降のサービスのためにユーザーのパスワードを保存するため、非常に安全ではありません。
(2) Google はパスワード ログインを導入する必要がありますが、単純なパスワード ログインが安全ではないことはわかっています。
(3) 「クラウド プリント」は、Google に保存されているユーザーのすべてのデータを取得する権利を有し、ユーザーは「クラウド プリント」権限の範囲および有効期間を制限することはできません。
(4) ユーザーは、パスワードを変更することによってのみ、「クラウド印刷」に付与された権限を取り戻すことができます。ただし、これを行うと、ユーザーが許可した他のすべてのサードパーティ アプリケーションが無効になります。
(5) サードパーティ製アプリケーションがクラックされる限り、ユーザーのパスワードが漏洩し、パスワードで保護されたすべてのデータが漏洩する可能性があります。
OAuth は、上記の問題を解決するために生まれました。
OAuth 2.0 を詳しく説明する前に、いくつかの特殊名詞を理解する必要があります。これらは、以下の説明、特にいくつかの図を理解するために非常に重要です。
(1) サードパーティ アプリケーション: サードパーティ アプリケーション。この記事では「クライアント」とも呼ばれます。前の例では「クラウド印刷」です。セクション "。
(2)HTTP サービス: HTTP サービス プロバイダー。この記事では「サービス プロバイダー」と呼びます。前のセクションの例では Google です。
(3) リソース所有者: リソース所有者。この記事では「ユーザー」とも呼ばれます。
(4)ユーザー エージェント: この記事ではユーザー エージェントはブラウザーを指します。
(5)認可サーバー: 認証サーバー、つまり、サービスプロバイダーが認証を処理するために特別に使用するサーバー。
(6) リソース サーバー: リソース サーバー、つまり、サービス プロバイダーがユーザー生成のリソースを保存するサーバー。これと認証サーバーは同じサーバーであっても、異なるサーバーであっても構いません。
上記の用語を理解すると、OAuth の機能は、「クライアント」が安全かつ制御可能な方法で「ユーザー」の承認を取得し、対話できるようにすることであることを理解するのは難しくありません。 「サービスプロバイダー」と。
OAuth は、「クライアント」と「サービスプロバイダー」の間に認可層を設定します。 「クライアント」は「サービスプロバイダー」に直接ログインすることはできませんが、ユーザーとクライアントを区別するために認可層にのみログインできます。 「クライアント」が認可レイヤーにログインするために使用するトークンは、ユーザーのパスワードとは異なります。ユーザーはログイン時に認可レイヤートークンの権限範囲と有効期間を指定できます。
「クライアント」が認可レイヤーにログインすると、「サービスプロバイダー」は、トークンの権限範囲と有効期間に基づいて、ユーザーの保存情報を「クライアント」に公開します。
OAuth 2.0の動作プロセスは以下の通りです(RFC 6749より抜粋)。
(A) ユーザーがクライアントを開いた後、クライアントはユーザーに承認を要求します。
(B) ユーザーはクライアントに権限を付与することに同意します。
(C) クライアントは、前の手順で取得した認可を使用して、認証サーバーにトークンを申請します。
(D) 認証サーバーはクライアントを認証した後、それが正しいことを確認し、トークンの発行に同意します。
(E) クライアントはトークンを使用してリソースサーバーに適用し、リソースを取得します。
(F) リソースサーバーはトークンが正しいことを確認し、クライアントにリソースをオープンすることに同意します。
上記の 6 つのステップのうち、B が鍵となること、つまり、ユーザーがクライアントをどのように承認できるかが重要であることを理解するのは難しくありません。この認可により、クライアントはトークンを取得し、そのトークンに基づいてリソースを取得できます。
以下では、クライアントが認可を取得するための 4 つのモードを 1 つずつ説明します。
クライアントはアクセストークンを取得するためにユーザーから認可グラントを取得する必要があります。 OAuth 2.0 では 4 つの認証方法が定義されています。
認可コードモード(認可コード)は、最も充実した機能と最も厳格な処理を備えた認可モードです。その特徴は、クライアントのバックエンドサーバーを介して「サービスプロバイダー」の認証サーバーと対話することです。
その手順は次のとおりです。
(A) ユーザーはクライアントにアクセスし、クライアントはクライアントを認証サーバーに転送します。
(B) ユーザーはクライアントを認可するかどうかを選択します。
(C) 認証サーバーは、ユーザーが認可を与えたと仮定して、クライアントから事前に指定された「リダイレクトURI」(リダイレクトURI)にユーザーを誘導し、認可コードを付加します。
(D) クライアントは認可コードを受け取り、先ほどの「リダイレクト URI」を添付して、認証サーバーからトークンを申請します。このステップはクライアントのバックエンドのサーバー上で完了し、ユーザーには見えません。
(E) 認証サーバーは認可コードとリダイレクト URI が正しいことを確認した後、アクセストークンとリフレッシュトークンをクライアントに送信します。
上記の手順に必要なパラメータは次のとおりです。
手順 A では、クライアントが認証を申請するために使用する URI には次のパラメーターが含まれます。
これが例です。
<code class=" language-http">GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1<span class="token keyword">Host: server.example.com</span></code>
ステップ C では、サーバーは次のパラメータを含むクライアントの URI に応答します。
これが例です。
<code class=" language-http">HTTP/1.1 302 Found<span class="token keyword">Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA &state=xyz</span></code>
ステップ D では、クライアントは次のパラメータを含むトークンの HTTP リクエストを認証サーバーに申請します:
これが例です。
<code class=" language-http">POST /token HTTP/1.1<span class="token keyword">Host: server.example.com<span class="token keyword">Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW<span class="token keyword">Content-Type: application/x-www-form-urlencodedgrant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb</span></span></span></code>
ステップ E では、認証サーバーによって送信された HTTP 応答には次のパラメーターが含まれています。
これが例です。
<code class=" language-http"> HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache<span class="token application/json"> <span class="token punctuation">{ <span class="token string">"access_token"<span class="token punctuation">:<span class="token string">"2YotnFZFEjr1zCsicMWpAA"<span class="token punctuation">, <span class="token string">"token_type"<span class="token punctuation">:<span class="token string">"example"<span class="token punctuation">, <span class="token string">"expires_in"<span class="token punctuation">:<span class="token number">3600<span class="token punctuation">, <span class="token string">"refresh_token"<span class="token punctuation">:<span class="token string">"tGzv3JOkF0XG5Qx2TlKWIA"<span class="token punctuation">, <span class="token string">"example_parameter"<span class="token punctuation">:<span class="token string">"example_value" <span class="token punctuation">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
上記のコードからわかるように、関連するパラメーターは JSON 形式 (Content-Type: application/json) で送信されます。さらに、HTTP ヘッダー情報は、キャッシュしてはならないことを明示的に指定します。
簡易モード(暗黙的付与型)は、サードパーティアプリケーションのサーバーを経由せず、ブラウザ上の認証サーバーから直接トークンを申請します。 「認証コード」をスキップする 「このステップがその名前の由来です。すべての手順はブラウザーで完了し、トークンは訪問者に表示され、クライアント側での認証は必要ありません。
その手順は次のとおりです。
(A) クライアントはユーザーを認証サーバーに誘導します。
(B) クライアントを認可するかどうかはユーザーが決定します。
(C) ユーザーが認可を与えると仮定して、認証サーバーはクライアントによって指定された「リダイレクト URI」にユーザーを誘導し、URI のハッシュ部分にアクセス トークンを含めます。
(D) ブラウザは、前の手順で受信したハッシュ値を含まないリクエストをリソース サーバーに送信します。
(E) リソース サーバーは、ハッシュ値のトークンを取得するコードを含む Web ページを返します。
(F) ブラウザは前の手順で取得したスクリプトを実行し、トークンを抽出します。
(G) ブラウザはトークンをクライアントに送信します。
上記の手順に必要なパラメータは次のとおりです。
ステップ A で、クライアントによって送信された HTTP リクエストには次のパラメータが含まれています:
下面是一个例子。
<code class=" language-http"> GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 Host: server.example.com</code>
C步骤中,认证服务器回应客户端的URI,包含以下参数:
下面是一个例子。
<code class=" language-http"> HTTP/1.1 302 Found Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA &state=xyz&token_type=example&expires_in=3600</code>
在上面的例子中,认证服务器用HTTP头信息的Location栏,指定浏览器重定向的网址。注意,在这个网址的Hash部分包含了令牌。
根据上面的D步骤,下一步浏览器会访问Location指定的网址,但是Hash部分不会发送。接下来的E步骤,服务提供商的资源服务器发送过来的代码,会提取出Hash中的令牌。
OAuth 2.0を理解する(Resource Owner Password Credentials Grant)中,用户向客户端提供自己的用户名和密码。客户端使用这些信息,向"服务商提供商"索要授权。
在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分,或者由一个著名公司出品。而认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。
它的步骤如下:
(A)用户向客户端提供用户名和密码。
(B)客户端将用户名和密码发给认证服务器,向后者请求令牌。
(C)认证服务器确认无误后,向客户端提供访问令牌。
B步骤中,客户端发出的HTTP请求,包含以下参数:
下面是一个例子。
<code class=" language-http"> POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=password&username=johndoe&password=A3ddj3w</code>
C步骤中,认证服务器向客户端发送访问令牌,下面是一个例子。
<code class=" language-http"> HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache<span class="token application/json"> <span class="token punctuation">{ <span class="token string">"access_token"<span class="token punctuation">:<span class="token string">"2YotnFZFEjr1zCsicMWpAA"<span class="token punctuation">, <span class="token string">"token_type"<span class="token punctuation">:<span class="token string">"example"<span class="token punctuation">, <span class="token string">"expires_in"<span class="token punctuation">:<span class="token number">3600<span class="token punctuation">, <span class="token string">"refresh_token"<span class="token punctuation">:<span class="token string">"tGzv3JOkF0XG5Qx2TlKWIA"<span class="token punctuation">, <span class="token string">"example_parameter"<span class="token punctuation">:<span class="token string">"example_value" <span class="token punctuation">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
上面代码中,各个参数的含义参见《OAuth 2.0を理解する》一节。
整个过程中,客户端不得保存用户的密码。
OAuth 2.0を理解する(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行认证。严格地说,OAuth 2.0を理解する并不属于OAuth框架所要解决的问题。在这种 模式中,用户直接向客户端注册,客户端以自己的名义要求"服务提供商"提供服务,其实不存在授权问题。
它的步骤如下:
(A)客户端向认证服务器进行身份认证,并要求一个访问令牌。
(B)认证服务器确认无误后,向客户端提供访问令牌。
A步骤中,客户端发出的HTTP请求,包含以下参数:
<code class=" language-http"> POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=client_credentials</code>
认证服务器必须以某种方式,验证客户端身份。
B步骤中,认证服务器向客户端发送访问令牌,下面是一个例子。
<code class=" language-http"> HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache<span class="token application/json"> <span class="token punctuation">{ <span class="token string">"access_token"<span class="token punctuation">:<span class="token string">"2YotnFZFEjr1zCsicMWpAA"<span class="token punctuation">, <span class="token string">"token_type"<span class="token punctuation">:<span class="token string">"example"<span class="token punctuation">, <span class="token string">"expires_in"<span class="token punctuation">:<span class="token number">3600<span class="token punctuation">, <span class="token string">"example_parameter"<span class="token punctuation">:<span class="token string">"example_value" <span class="token punctuation">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
上面代码中,各个参数的含义参见《OAuth 2.0を理解する》一节。
如果用户访问的时候,客户端的"访问令牌"已经过期,则需要使用"更新令牌"申请一个新的访问令牌。
客户端发出更新令牌的HTTP请求,包含以下参数:
下面是一个例子。
<code class=" language-http"> POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA</code>