47

我正在用 PHP 设计一个将使用 OAuth2.0 的 API。我的最终目标是用 javascript(使用 AngularJS)构建一个直接访问这个 API 的前端应用程序。我知道传统上没有办法保护 javascript 中的事务,因此直接访问 API 是不可行的。前端需要与服务器代码通信,而服务器代码又直接与 API 通信。但是,在研究 OAuth2 时,似乎用户代理流程旨在帮助解决这种情况。

我需要帮助的是在 javascript 中实现 OAuth2 用户代理流程(特别是 AngularJS,如果可能的话,因为这是我在前端使用的)。我还没有找到任何可以做到这一点的示例或教程。我真的不知道从哪里开始,也不想通读整个 OAuth2 规范,至少没有看到我将要做什么的例子。因此,任何示例、教程、链接等都将不胜感激。

4

2 回答 2

50

隐式授予流程(您称为User-Agent Flow 的流程)正是要走的路:

隐式授权是一种简化的授权代码流,针对使用 JavaScript 等脚本语言在浏览器中实现的客户端进行了优化。

要了解流程,Google 的客户端应用程序文档是一个非常好的起点。请注意,他们建议您采取额外的令牌验证步骤以避免混淆代理问题

以下是使用 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(该ajax()函数在 jQuery 中的作用),请参阅他们的$http服务文档。

如果要保留状态,在将用户发送到授权端点时,请检查state参数。

于 2012-07-17T08:55:36.770 回答
2

Authorization Code Grant有一个从 OAuth 服务器获取令牌的方法示例。我使用 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.
}

您可以Resource Owner Password Credentials Grant使用 jQuery 或纯 XMLHttpRequest 以相同的方式实现,并且不进行任何重定向 - 因为在每次重定向时,您都会失去应用程序的状态。

对我来说,我使用 HTML5 本地存储来保存不太可能构成安全威胁的数据的应用程序状态。

于 2012-07-15T09:59:29.580 回答