web-dev-qa-db-ja.com

Javascriptで安全なOAuth2消費を実装するにはどうすればよいですか?

私はPHP OAuth2.0を使用するAPIを設計しています。私の最終目標は、このAPIに直接アクセスするjavascript(AngularJSを使用)でフロントエンドアプリケーションを構築することです。従来、JavaScriptでトランザクションを保護する方法はなく、APIに直接アクセスすることは不可能であることがわかっています。フロントエンドは、APIと直接通信するサーバーコードと通信する必要がありますが、OAuth2の調査ではUser-Agent Flowは、この状況に役立つように設計されているように見えます。

私が助けを必要とするのは、OAuth2 User-Agent Flowをjavascriptで実装することです(特にフロントエンドに使用しているので、可能であれば特にAngularJSです)。これを行う例やチュートリアルを見つけることができませんでした。どこから始めればいいのかまったくわからないので、OAuth2仕様全体を読みたいとは思わないでしょう。したがって、例、チュートリアル、リンクなどは大歓迎です。

45
David Myers

Implicit Grant flowUser-Agent Flowと呼んでいるもの)がまさにその方法です:

暗黙的な許可は、JavaScriptなどのスクリプト言語を使用してブラウザに実装されたクライアント向けに最適化された、単純化された承認コードフローです。

フローを理解するには、Googleの client-side applications に関するドキュメントを参照するのが本当に良いでしょう。追加のトークン検証ステップを実行して、 混乱した代理問題 を回避することをお勧めします。

this answer から取得した、Soundcloud APIとjQueryを使用したフローの簡単な実装例を次に示します。

_<script type="text/javascript" charset="utf-8">
  $(function () {
    var extractToken = function(hash) {
      var match = hash.match(/access_token=([\w-]+)/);
      return !!match && match[1];
    };

    var CLIENT_ID = YOUR_CLIENT_ID;
    var AUTHORIZATION_ENDPOINT = "https://soundcloud.com/connect";
    var RESOURCE_ENDPOINT = "https://api.soundcloud.com/me";

    var token = extractToken(document.location.hash);
    if (token) {
      $('div.authenticated').show();

      $('span.token').text(token);

      $.ajax({
          url: RESOURCE_ENDPOINT
        , beforeSend: function (xhr) {
            xhr.setRequestHeader('Authorization', "OAuth " + token);
            xhr.setRequestHeader('Accept',        "application/json");
          }
        , success: function (response) {
            var container = $('span.user');
            if (response) {
              container.text(response.username);
            } else {
              container.text("An error occurred.");
            }
          }
      });
    } else {
      $('div.authenticate').show();

      var authUrl = AUTHORIZATION_ENDPOINT + 
        "?response_type=token" +
        "&client_id="    + clientId +
        "&redirect_uri=" + window.location;

      $("a.connect").attr("href", authUrl);
    }
  });
</script>
<style>
  .hidden {
    display: none;
  }
</style>

<div class="authenticate hidden">
  <a class="connect" href="">Connect</a>
</div>

<div class="authenticated hidden">
  <p>
    You are using token
    <span class="token">[no token]</span>.
  </p>

  <p>
    Your SoundCloud username is
    <span class="user">[no username]</span>.
  </p>
</div>
_

AngularJSを使用して XMLHttpRequests (jQueryでajax()関数が行うこと)を送信するには、 _$http_ service のドキュメントを参照してください。

状態を保持する場合は、ユーザーを承認エンドポイントに送信するときに、 state パラメーターをチェックアウトします。

50
Jan Gerlinger

OAuthサーバーからトークンを取得するAuthorization Code Grantアプローチの例があります。jQuery($)を使用していくつかの操作を行いました。

最初に、ユーザーを認証ページにリダイレクトします。

var authServerUri = "http://your-aouth2-server.com/authorize",
authParams = {
  response_type: "code",
  client_id: this.model.get("clientId"),
  redirect_uri: this.model.get("redirectUri"),
  scope: this.model.get("scope"),
  state: this.model.get("state")
};

// Redirect to Authorization page.
var replacementUri = authServerUri + "?" + $.param(authParams);
window.location.replace(replacementUri);

トークンを取得するために認証パスを与えた場合:

var searchQueryString = window.location.search;
if ( searchQueryString.charAt(0) === "?") {
  searchQueryString = searchQueryString.substring(1);
}
var searchParameters = $.deparam.fragment(searchQueryString);

if ( "code" in searchParameters) {
  // TODO: construct a call like in previous step using $.ajax() to get token.
}

JQueryまたは純粋なXMLHttpRequestを使用してResource Owner Password Credentials Grantを同じ方法で実装し、リダイレクトを行わないようにすることができます。リダイレクトごとにアプリケーションの状態が失われるためです。

私にとっては、HTML5ローカルストレージを使用して、セキュリティの脅威をもたらす可能性が低いデータのアプリケーションの状態を維持しました。

1
Artem Oboturov