通过ajax请求向API发送身份验证标头的正确方法

时间:2018-07-02 11:56:18

标签: ruby-on-rails ajax api xmlhttprequest

我有一个将身份验证密钥存储在隐藏字段中的表格。

hidden_field_tag 'auth_key', Settings.biometric.auth_key

我正在向API发送ajax请求,在其中我在需要密钥的标头中设置auth密钥:

var authKey = $("input[id='auth_key']").val();
beforeSend: function (xhr) {
  xhr.setRequestHeader ("auth", authKey);
}

一切正常,只是auth密钥位于表单中,并且容易被任何恶意用户检查。

我认为这可能不是正确的方法 执行此操作的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

TL; DR:

任何有权访问客户端(也就是使用浏览器的用户)的人,最终都可以找到获取此auth_key的方法,因为客户端用户将拥有并且将永远有权访问/访问什么内容。发送/接收/存储“数据”,由于内置的​​浏览器开发人员工具,在Web应用程序中尤其容易实现。

一些解释:

免责声明:我对此领域并不精通,所以如果有人,请告诉我。

  • 是的,可以在客户端对其进行加密,但是用户/黑客可以对其进行解密,因为可以在您的JS脚本文件中的某个位置找到“ encryption”跟踪:

    // application.js example
    ...beforeSend: function (xhr) {
      var encryptedAuthKey = localstorage.get('encrypted-auth-key');
      var decryptionPassword = 'abcd';
      var authKey = doSomeFancyDecryption(encryptedAuthKey, decryptionPassword);
      xhr.setRequestHeader ("auth", authKey);
    }
    
  • 但是,一种安全的方法是使用服务器端存储的密码对它们进行加密,以使客户端无法在JS代码中调试/检查/查找此密码...除非不是可能,请参见下文:

    // application.js example
    ...beforeSend: function (xhr) {
      var encryptedAuthKey = localstorage.get('encrypted-auth-key');
    
      var decryptionPassword = someFunctionThatPerformsAjaxRequestToServerAndReturnsTheDecryptionPassword();
      var authKey = doSomeFancyDecryption(encryptedAuthKey, decryptionPassword);
    
      function someFunctionThatPerformsAjaxRequestToServerAndReturnsTheDecryptionPassword() {
        // do some ajax request with Auth header equals Something...
        // ummm... what's the value of this something?
        // ummm... I cannot pass in my Username and Password, of course!
        // ummm... I cannot pass in another-kind of "auth_key", which just basically loops this process itself.
      }
    
      xhr.setRequestHeader ("auth", authKey);
    }
    
  • 您可以“签署”您的请求,这样您就不再需要直接提供auth_key作为请求的一部分(但是客户端用户仍然可以破解此请求并获得身份验证键并自己创建自己的请求,正是因为他们可以看到并访问您的基础代码,如下所示:

    // application.js example
    ...beforeSend: function (xhr) {
      var authKey = localstorage.get('auth-key');
      var params = // assign all input fields as key-values object here
      var url = this.url;
      var signature = generateSignatureUsingHMAC(authKey, url, params)
    
      xhr.setRequestHeader ("Signature", signature);
    }
    

我个人会做类似上面基于签名的授权