使用 JavaScript 的基本身份验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34860814/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 16:58:31  来源:igfitidea点击:

Basic Authentication Using JavaScript

javascriptauthenticationxmlhttprequest

提问by Rex CoolCode Charles

I am building an application that consumes the Caspio API. I am having some trouble authenticating against their API. I have spent 2-3 days trying to figure this out but it may be due to some understanding on my end. I have read countless articles on stackoverflow post and otherwise but have not solved the issue. Below is a code example of my solution based on what i have looked at and i am getting a 400 Status code message; What am i doing wrong here? (Please provide well commented code example and i would prefer to NOThave links posted here referencing other material as i have looked at these extensively. Thanks!):

我正在构建一个使用Caspio API的应用程序。我在针对他们的 API 进行身份验证时遇到了一些麻烦。我花了 2-3 天的时间试图弄清楚这一点,但这可能是由于我的理解。我已经阅读了无数关于 stackoverflow 帖子的文章,但还没有解决这个问题。下面是我的解决方案的代码示例,基于我所查看的内容,我收到了 400 状态代码消息;我在这里做错了什么?(请提供很好的注释代码示例,我宁愿不要有链接张贴在这里引用正如我在这些都广泛地看着其他感谢的材料。!):

Some references i have looked at:

我看过的一些参考资料:

1) Pure JavaScript code for HTTP Basic Authentication?

1)用于 HTTP 基本身份验证的纯 JavaScript 代码?

2) How to make http authentication in REST API call from javascript

2)如何在 REST API 调用中通过 javascript 进行 http 身份验证

I would like to use this authentication method as described by caspio below:

我想使用下面由 caspio 描述的这种身份验证方法:

As an alternative to including credentials in the request body, a client can use the HTTP Basic authentication scheme. In this case, authentication request will be setup in the following way:

作为在请求正文中包含凭据的替代方法,客户端可以使用 HTTP 基本身份验证方案。在这种情况下,身份验证请求将按以下方式设置:

Method:POST

方法:POST

URL:Your token endpoint

URL:您的令牌端点

Body:grant_type=client_credentials

正文grant_type=client_credentials

Header parameter:

标头参数:

Authorization:Basic Basic authentication realm

授权:Basic Basic 认证领域

Below are my Javascript and HTML code.

下面是我的 Javascript 和 HTML 代码。

JavaScript:

JavaScript:

var userName = "clientID";
var passWord = "secretKey";

function authenticateUser(user, password)
{
    var token = user + ":" + password;

    // Should i be encoding this value????? does it matter???
    // Base64 Encoding -> btoa
    var hash = btoa(token); 

    return "Basic " + hash;
}

function CallWebAPI() {

    // New XMLHTTPRequest
    var request = new XMLHttpRequest();
    request.open("POST", "https://xxx123.caspio.com/oauth/token", false);
    request.setRequestHeader("Authorization", authenticateUser(userName, passWord));  
    request.send();
    // view request status
    alert(request.status);
    response.innerHTML = request.responseText;
}

HTML:

HTML:

<div>
<div id="response">

</div>
<input type="button" class="btn btn-primary" value="Call Web API" onclick="javascript:CallWebAPI();" />

采纳答案by Rex CoolCode Charles

After Spending quite a bit of time looking into this, i came up with the solution for this; In this solution i am not using the Basic authentication but instead went with the oAuth authentication protocol. But to use Basic authentication you should be able to specify this in the "setHeaderRequest" with minimal changes to the rest of the code example. I hope this will be able to help someone else in the future:

在花了很多时间研究这个之后,我想出了解决方案;在这个解决方案中,我没有使用基本身份验证,而是使用了 oAuth 身份验证协议。但是要使用基本身份验证,您应该能够在“setHeaderRequest”中指定它,对代码示例的其余部分进行最少的更改。我希望这将能够在未来帮助其他人:

var token_ // variable will store the token
var userName = "clientID"; // app clientID
var passWord = "secretKey"; // app clientSecret
var caspioTokenUrl = "https://xxx123.caspio.com/oauth/token"; // Your application token endpoint  
var request = new XMLHttpRequest(); 

function getToken(url, clientID, clientSecret) {
    var key;           
    request.open("POST", url, true); 
    request.setRequestHeader("Content-type", "application/json");
    request.send("grant_type=client_credentials&client_id="+clientID+"&"+"client_secret="+clientSecret); // specify the credentials to receive the token on request
    request.onreadystatechange = function () {
        if (request.readyState == request.DONE) {
            var response = request.responseText;
            var obj = JSON.parse(response); 
            key = obj.access_token; //store the value of the accesstoken
            token_ = key; // store token in your global variable "token_" or you could simply return the value of the access token from the function
        }
    }
}
// Get the token
getToken(caspioTokenUrl, userName, passWord);

If you are using the Caspio REST API on some request it may be imperative that you to encode the paramaters for certain request to your endpoint; see the Caspio documentation on this issue;

如果您在某些请求上使用 Caspio REST API,则可能必须对特定请求的参数进行编码到您的端点;请参阅有关此问题的 Caspio 文档;

NOTE: encodedParams is NOT used in this example but was used in my solution.

注意:本示例中未使用编码参数,但在我的解决方案中使用了。

Now that you have the token stored from the token endpoint you should be able to successfully authenticate for subsequent request from the caspio resource endpoint for your application

既然您已经从令牌端点存储了令牌,您应该能够成功地对来自应用程序的 caspio 资源端点的后续请求进行身份验证

function CallWebAPI() {
    var request_ = new XMLHttpRequest();        
    var encodedParams = encodeURIComponent(params);
    request_.open("GET", "https://xxx123.caspio.com/rest/v1/tables/", true);
    request_.setRequestHeader("Authorization", "Bearer "+ token_);
    request_.send();
    request_.onreadystatechange = function () {
        if (request_.readyState == 4 && request_.status == 200) {
            var response = request_.responseText;
            var obj = JSON.parse(response); 
            // handle data as needed... 

        }
    }
} 

This solution does only considers how to successfully make the authenticated request using the Caspio API in pure javascript. There are still many flaws i am sure...

该解决方案只考虑如何在纯 javascript 中使用 Caspio API 成功发出经过身份验证的请求。还是有很多瑕疵,我相信...

回答by V.Tran

Today we use Bearer tokenmore often that Basic Authenticationbut if you want to have Basic Authenticationfirst to get Bearer token then there is a couple ways:

今天我们Bearer token更频繁地使用它,Basic Authentication但是如果您想Basic Authentication首先获得不记名令牌,那么有几种方法:

const request = new XMLHttpRequest();
request.open('GET', url, false, username,password)
request.onreadystatechange = function() {
        // D some business logics here if you receive return
   if(request.readyState === 4 && request.status === 200) {
       console.log(request.responseText);
   }
}
request.send()

Full syntax is here

完整语法在这里

Second Approach using Ajax:

使用 Ajax 的第二种方法:

$.ajax
({
  type: "GET",
  url: "abc.xyz",
  dataType: 'json',
  async: false,
  username: "username",
  password: "password",
  data: '{ "key":"sample" }',
  success: function (){
    alert('Thanks for your up vote!');
  }
});

Hopefully, this provides you a hint where to start API calls with JS. In Frameworks like Angular, React, etc there are more powerful ways to make API call with Basic Authenticationor Oauth Authentication. Just explore it.

希望这为您提供了一个提示,从哪里开始使用 JS 调用 API。在 Angular、React 等框架中,有更强大的方法可以使用Basic Authentication或进行 API 调用Oauth Authentication。只是探索它。

回答by Stelios

EncodedParams variable is redefined as params variable will not work. You need to have same predefined call to variable, otherwise it looks possible with a little more work. Cheers! json is not used to its full capabilities in php there are better ways to call json which I don't recall at the moment.

EncodedParams 变量被重新定义,因为 params 变量将不起作用。您需要对变量进行相同的预定义调用,否则看起来可能需要多做一些工作。干杯! json 并没有在 php 中使用它的全部功能,有更好的方法来调用 json,我现在不记得了。