5

Ember.js(和 Ember-data)中是否有办法将凭据发送到需要基本 HTTP 身份验证的 api ?我可以在这里看到它在 JQuery 中是如何完成的,但在 Ember 中看不到任何直接的方法。我想也许在标题中添加一些东西会起作用(见下文咖啡脚本),但没有成功:

App.AuthAdapter =  DS.RESTAdapter.extend(
    host: 'https://my-api.example.com'
    namespace: 'v1'
    headers:
        "Authorization Basic fooUsername:barPassword"
    ...
4

3 回答 3

3

您可以扩展默认的 Rest 适配器并添加一个标头散列,该散列将包含在发送的 ajax 中。

App.ApplicationAdapter = DS.RESTAdapter.extend(
   headers:
     withCredentials: true
     Authorization: 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
)

或者您可以更进一步并覆盖 ajax 方法

App.ApplicationAdapter = DS.RESTAdapter.extend(
  ajax: (url, type, hash) ->
    adapter = this
    new Ember.RSVP.Promise((resolve, reject) ->
      hash = hash or {}
      hash.url = url
      hash.type = type
      hash.dataType = "json"
      hash.context = adapter

      if hash.data and type isnt "GET"
        hash.contentType = "application/json; charset=utf-8"
        hash.data = JSON.stringify(hash.data)

      if adapter.headers isnt `undefined`
        headers = adapter.headers
        hash.beforeSend = (xhr) ->
          forEach.call Ember.keys(headers), (key) ->
            xhr.setRequestHeader key, headers[key]

    hash.success = (json) ->
      Ember.run null, resolve, json

    hash.error = (jqXHR, textStatus, errorThrown) ->
      Ember.run null, reject, adapter.ajaxError(jqXHR)

    Ember.$.ajax hash
  )
)
于 2013-11-15T00:54:31.490 回答
2

你能用$.ajaxPrefilter吗?例如

Ember.$.ajaxPrefilter (options) ->
  options.xhrFields = { withCredentials: true }
  options.username = 'fooUsername'
  options.password = 'barPassword'
  true # need to return non-falsy here
于 2013-11-15T00:54:20.647 回答
2

正如@gerry3 所说$.ajaxPrefilter,这是一个有效的解决方案。

但是,如果您想解决在事件之后动态更改标题的问题,例如,成功的 LOGIN 尝试,那么您需要放置更多连线。在我的情况下,我需要在成功的 AJAX 登录后发回服务器提供的“令牌”标头。但是,当然,当用户启动应用程序时,他还没有登录。

问题是,一旦您重新打开扩展RESTAdapter,或定义一个ajaxPrefilter,即使您将其绑定到一个值(或在我的情况下为 localStorage),该类也不会遵循当前变量 value。这就像在某个时刻拍摄的快照。所以在我的场景中它是没用的。

我正在关注Embercast 客户端身份验证,这是一个好的开始(代码可用),但我使用的是Ember-Data而不是 jQuery 数据获取。

所以诀窍是观察令牌并根据需要多次重新定义 ajaxPrefilter。

tokenChanged: function() {
    this.get('token')=='' ? 
        localStorage.removeItem('token') : 
            localStorage.token = this.get('token');

    $.ajaxPrefilter(function(options, originalOptions, xhr) {
        return xhr.setRequestHeader('Token', localStorage.token);
    });

}.observes('token')

因此,当用户登录时,他将拥有一个有效的令牌,并在每个请求中通过 RESTAdapter 将其发送到服务器。

希望这可以帮助某人。

于 2014-04-21T10:29:34.953 回答