【问题标题】:Basic HTTP Authentication in Ember Data REST AdapterEmber 数据 REST 适配器中的基本 HTTP 身份验证
【发布时间】:2013-11-15 00:19:17
【问题描述】:

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

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

【问题讨论】:

    标签: ember.js ember-data basic-authentication


    【解决方案1】:

    您可以扩展默认的 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
      )
    )
    

    【讨论】:

    • 感谢您的回复!我认为这会让我朝着正确的方向前进。在这之后我意识到因为我的开发位置与我们的 api 位置不同,所以 Ember 会先发送一个 HTTP OPTIONS 请求,所以在我们的后端人员调整他们的东西后,我会再试一次。
    • 另外,我发现如果想在Adapter启动后更改header,可以这样:adapter = this.get('container').lookup('adapter:auth'); adapter.set('headers', { 'Authorization': 'Basic ' + token });
    • ajax方法在源码中被标记为private。我相信这不是未来的安全,请依赖它。另一种方法是在您的 RESTAdapter 中覆盖使用它的方法(查找等)
    【解决方案2】:

    你能用$.ajaxPrefilter吗?例如

    Ember.$.ajaxPrefilter (options) ->
      options.xhrFields = { withCredentials: true }
      options.username = 'fooUsername'
      options.password = 'barPassword'
      true # need to return non-falsy here
    

    【讨论】:

      【解决方案3】:

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

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

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

      我正在关注 Embercast Client Authentication,这是一个好的开始 (code available),但我使用的是 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 将其发送到服务器。

      希望这对某人有所帮助。

      【讨论】:

        猜你喜欢
        • 2012-02-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-04
        • 2014-06-24
        • 2011-11-03
        • 1970-01-01
        相关资源
        最近更新 更多