Javascript Fitbit API的OAuth2隐式vs授权码授权
这个问题的答案是,我在客户端使用授权代码授权流。。这似乎会导致阻塞错误 在下面检查FITBIT API的功能验证OAUTH2隐式授权 我正在对Fitbit API执行OAuth2身份验证。这一切都使用授权代码授权流。因此,首先获取身份验证代码,将其重定向到我的应用程序,然后将其交换为访问令牌并使用该令牌获取数据 从post_request.html页面的主页开始,按下fitbit按钮,用户将重定向到fitbit的授权端点。我正在使用Node.js构建一个本地服务器来承载应用程序,并能够毫无问题地重定向 在被重定向时,我检索授权代码并发出AJAX POST请求,用授权代码换取访问令牌。然后我提出了这个POST请求,但我得到了以下错误Javascript Fitbit API的OAuth2隐式vs授权码授权,javascript,node.js,ajax,oauth-2.0,Javascript,Node.js,Ajax,Oauth 2.0,这个问题的答案是,我在客户端使用授权代码授权流。。这似乎会导致阻塞错误 在下面检查FITBIT API的功能验证OAUTH2隐式授权 我正在对Fitbit API执行OAuth2身份验证。这一切都使用授权代码授权流。因此,首先获取身份验证代码,将其重定向到我的应用程序,然后将其交换为访问令牌并使用该令牌获取数据 从post_request.html页面的主页开始,按下fitbit按钮,用户将重定向到fitbit的授权端点。我正在使用Node.js构建一个本地服务器来承载应用程序,并能够毫无问题地
{"errors":[{"errorType":"invalid_client","message":"Invalid authorization header format. The header was not recognized to be a valid header for any of known implementations or a client_id was not specified in case of a public client Received header = BasicdW5kZWZpbmVk. Visit https://dev.fitbit.com/docs/oauth2 for more information on the Fitbit Web API authorization process."}],"success":false}
我想我的url编码客户端id和客户端密码可能有错误。或者在我设置标题的时候。但我看不出来。有人能帮我吗
我的HTML文件如下
<body>
<button onclick="fitbitAuth()">Fitbit</button>
<!-- action = route, method = method -->
<form action="/" method="POST" id="form">
<h3>Email Address:</h3>
<input type="email">
<br>
<h3>Password:</h3>
<input type="password">
<br>
<br>
<button type="submit">Send Request</button>
</form>
</body>
</html>
我的脚本如下,它由3个函数组成。。
-base64编码函数
-用于启动OAuth2进程的onclick函数
-用于交换访问令牌的身份验证代码的函数
// run this script upon landing back on the page with the authorization code
// specify and/ or calculate parameters
var url_terug = window.location.search;
var auth_code = url_terug.substr(6);
var granttype = "authorization_code";
var redirect_uri = "http://localhost:3000/fitbit";
var client_id = "xxxxx";
var client_secret = "xxxxxxxxxxxx";
var stringto_encode = client_id + ":" + client_secret;
var encoded_string = "";
console.log("auth code = " + auth_code);
function baseEncode(stringto_encode){
encoded_string = btoa(stringto_encode);
console.log(encoded_string);
}
function getTokenFitBit(){
baseEncode();
// execute a POST request with the right parameters
var request = new XMLHttpRequest();
request.open('POST', "https://api.fitbit.com/oauth2/token?client_id=" + client_id + "&grant_type=" + granttype + "&redirect_uri=" + redirect_uri + "&code=" + auth_code);
request.setRequestHeader('Authorization', 'Basic'+ encoded_string);
request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
// Setup our listener to process completed requests
request.onload = function () {
// Process our return data
// status code between 200 and 300 indicates success
if (request.status >= 200 && request.status < 300) {
console.log('success!', request);
console.log(request.responseText);
// continue with API calls..
// you could set up a broader response handling if there is a use case for it
} else {
console.log('The current token request failed!');
}
};
request.send();
}
getTokenFitBit();
// get the access token out of the JSON response
// execute a GET request on the API endpoint
// handle the data
// upon clicking fitbit button, starting off the oauth2 authentication
function fitbitAuth() {
window.location.href = 'https://www.fitbit.com/oauth2/authorize?client_id=xxxxx&response_type=code&scope=activity&redirect_uri=http://localhost:3000/fitbit&prompt=consent';
}
在上面的示例中,您似乎在基本标题和此行中的值之间缺少分隔符:
request.setRequestHeader('Authorization', 'Basic'+ encoded_string);
如果您正在构建一个基于web的应用程序,您可能还需要考虑使用“隐式”流:以下代码函数并使用隐式授权流。它与FitBit API、Node.js一起重定向到应用程序,然后进行客户端身份验证 Node.js本地服务器模块的代码
// PROJECT authenticating Fitbit OAuth2 Implicit Grant
const express = require("express");
const app = express();
const filesys = require("fs");
const path = require("path");
// body parser module parses form data into server
const body_parse = require("body-parser");
// middleware to encrypt folder structure for users : can look into DevTools
app.use('/public', express.static(path.join(__dirname, 'static')));
// allows us to parse url encoded forms
app.use(body_parse.urlencoded({extended: false}));
// using readstream with chunks in buffer with security on the path
app.get("/fitbit", (req, res) => {
const readStream = filesys.createReadStream(path.join(__dirname,'static','post_request.html'));
readStream.on('error', function(){
/*handle error*/
res.write("there is an error authenticating against fitbit api endpoint");
});
res.writeHead(200, {'Content-type' : 'text/html'});
readStream.pipe(res);
});
// bodyparser parses data and adds to the body of the request
app.get("/", (req, res, err) => {
const readStream = filesys.createReadStream(path.join(__dirname,'static','start_page.html'));
res.writeHead(200, {'Content-type' : 'text/html'});
readStream.pipe(res);
});
app.listen(3000);
HTML文件,只需一个按钮即可启动OAuth2进程
<body>
<button onclick="fitbitAuth()">Fitbit</button>
<script>
// define variables
var cli_id = "xxxxx";
var res_typ = "token";
var scope_typ = "activity";
var redirect = "http://localhost:3000/fitbit";
var expires = "31536000";
var prompt_var = "consent";
// upon clicking fitbit button, starting off the oauth2 authentication
function fitbitAuth() {
window.location.href = "https://www.fitbit.com/oauth2/authorize?client_id=" + cli_id + "&response_type=" + res_typ + "&scope=" + scope_typ + "&redirect_uri=" + redirect + "&expires_in=" + expires + "&prompt=" + prompt_var;
}
</script>
</body>
</html>
重定向页面,用户同意使用其数据后返回的页面。。只需一个按钮就可以在生命周期活动统计数据上启动API调用
<body>
<!-- action = route, method = method -->
<button type="submit" onclick="getActivityData()">Send Request</button>
<script>
// get out the accesstoken from the provided data
var url_terug = window.location.href;
var split_after = "access_token=";
var split_before = "&user_id";
var after_string = url_terug.split(split_after).pop();
var accesstoken = after_string.slice(0, after_string.indexOf(split_before));
console.log(accesstoken);
// getActivityData();
function getActivityData(){
// execute a POST request with the right parameters
var request = new XMLHttpRequest();
request.open('GET', "https://api.fitbit.com/1/user/-/activities.json");
request.setRequestHeader('Authorization', 'Bearer '+ accesstoken);
// Setup our listener to process completed requests
request.onload = function () {
// Process our return data
// status code between 200 and 300 indicates success
if (request.status >= 200 && request.status < 300) {
console.log('success!', request);
console.log(request.responseText);
// continue with API calls..
// you could set up a broader response handling if there is a use case for it
} else {
console.log('The current token request failed!');
}
};
request.send();
}
</script>
</body>
谢谢你,我错过了这个。。我已经尝试使用隐式的授权流,这个函数。。授权授予流似乎仍然阻塞..问题是是否有可能这样做。。我会把你的答案标记为已接受的答案,这样其他人就不会感到困惑。。谢谢你的建议!