【问题标题】:Connect AngularJS app to backend using credentials (Beginner/Intermediate)使用凭据将 AngularJS 应用程序连接到后端(初级/中级)
【发布时间】:2015-10-30 10:06:48
【问题描述】:

经过相当广泛的研究,我缩小了我的问题范围。我有一个 curl 请求

curl -X POST -vu sampleapp:samplekey http://sampleurl:8090/oauth/token -H "Accept: application/json" -d "password=pass&username=username&grant_type=password&scope=read%20write&client_secret=samplekey&client_id=sampleapp"

它向我发送了类似

的响应
    {
    
"access_token":"blah", 
"token_type":"bearer", 
"refresh_token":"blah", 
"expires_in":43199,
    
"scope":"read write"
}

我有一个客户端应用程序 (AngularJS) 正在尝试与后端通信。它具有在服务器端实现的所有 CORS 标头和方法。

我从客户端获取登录信息并将其发布到 api 以尝试获取访问令牌。

现在,当我写作时(在 Issac 下面的第一个答案后更新)我的登录功能如下。有人告诉我我需要 3 个标头值:Authorization、Accept 和 Content-type

var _login = function (loginData) {

var theauthdata = Base64.encode('sampleapp:samplekey');

    var deferred = $q.defer();

    var headers2 = {
        'Accept' : 'application/json',
        'Authorization': 'Basic' + theauthdata,
        'Content-Type': 'application/x-www-form-urlencoded'
    };



        // For JSON authorization 
        var data = {
            'grant_type': 'password',
            'scope' : 'read write',
            'username' : loginData.username,
            'password' : loginData.password,
            // withCredentials : true,
            'client_id' : 'sampleapp',
            'client_secret' : 'samplekey'
        }

         $http.post(serviceBase + 'token', data, { headers: headers2},{withCredentials:true})

        .success(function (response) 
        {

            localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName });

            _authentication.isAuth = true;
            _authentication.userName = loginData.userName;

            deferred.resolve(response);

        }).error(function (err, status) {
            _logOut();
            deferred.reject(err);
        });

        return deferred.promise;

    };

即使在添加了所需的标头之后,在此过程中我还是从 api 服务器获得了一个 401 error

在 curl 请求中 -u 部分表示 url unname/pwd,我想确保我以正确的方式编写调用。任何帮助将不胜感激。

编辑/更新:正如问题的第一条评论所说,是的,我应该发送 URL 的用户名/密码组合,而不是用户数据。

这就是我猜测的 curl 请求的 -u 部分的含义。

我在第一个答案后做了一些研究,显然我正在尝试 Basic HTTP authentication ?但我想澄清一下,我仍在将 clientUserData(登录信息)作为有效负载发送。那我做对了吗?我的印象是我在做resource-owner-grant-credentials,但这是基本的http auth,正如我被告知的那样?显然,我是 OAuth 的新手并且很困惑。有人可以根据上面的 curl 调用详细说明我正在实施的方法吗?基本上,我试图模仿上面给出的 curl 调用。

更新:我已经更新了登录代码。我有一个工厂设置来处理这些功能,我还建立了一个 Base64 工厂来对数据进行编码。我忍不住想我还是做错了什么或打电话错了?

【问题讨论】:

  • 您的意思是除了用于登录的用户名/密码之外,还有一个用户名/密码可以POST到URL?
  • “网址的用户名和密码”是什么意思?为什么你有 2 个单独的用户凭据?

标签: angularjs curl http-headers xmlhttprequest basic-authentication


【解决方案1】:

我假设您正在询问如何将基本 HTTP 身份验证与 $http 服务一起使用。以下是如何做到这一点。

var authdata = Base64.encode(username + ':' + password);
var headers2 = {
    'Accept' : 'application/json',
    'Authorization' : 'Basic ' + authdata;
}

您需要包含一个用于编码为 Base64 的库,如下所示:

var keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
var Base64 = {
    encode: function (input) {
        var output = "";
        var chr1, chr2, chr3 = "";
        var enc1, enc2, enc3, enc4 = "";
        var i = 0;

        do {
            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);

            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;

            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }

            output = output +
                keyStr.charAt(enc1) +
                keyStr.charAt(enc2) +
                keyStr.charAt(enc3) +
                keyStr.charAt(enc4);
            chr1 = chr2 = chr3 = "";
            enc1 = enc2 = enc3 = enc4 = "";
        } while (i < input.length);

        return output;
    },

    decode: function (input) {
        var output = "";
        var chr1, chr2, chr3 = "";
        var enc1, enc2, enc3, enc4 = "";
        var i = 0;

        // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
        var base64test = /[^A-Za-z0-9\+\/\=]/g;
        if (base64test.exec(input)) {
            window.alert("There were invalid base64 characters in the input text.\n" +
                "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
                "Expect errors in decoding.");
        }
        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

        do {
            enc1 = keyStr.indexOf(input.charAt(i++));
            enc2 = keyStr.indexOf(input.charAt(i++));
            enc3 = keyStr.indexOf(input.charAt(i++));
            enc4 = keyStr.indexOf(input.charAt(i++));

            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;

            output = output + String.fromCharCode(chr1);

            if (enc3 != 64) {
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64) {
                output = output + String.fromCharCode(chr3);
            }

            chr1 = chr2 = chr3 = "";
            enc1 = enc2 = enc3 = enc4 = "";

        } while (i < input.length);

        return output;
    }
};

代码修改自here

更新:

您的 curl 请求以两种不同的方式进行身份验证。

  1. 使用基本 HTTP 身份验证,此处:-vu sampleapp:samplekey
  2. 使用用户登录凭据,此处:-d "password=pass&amp;username=username"

第 1 部分由标头处理(即header2)。第 2 部分由 data 变量中的用户名和密码处理。这对我来说似乎有点矫枉过正,但在某些情况下需要双重身份验证。

更新: Basic 后面缺少一个空格,该行应为:

    'Authorization': 'Basic ' + theauthdata,

【讨论】:

  • @issac-mann 你能详细说明我的疑问吗?在此先感谢:)!
  • @issac-mann 嘿,Issac 我刚刚更新了这个问题。请看看你是否可以。非常感谢大家的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-05
  • 1970-01-01
相关资源
最近更新 更多