Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Fitbit API的OAuth2隐式vs授权码授权_Javascript_Node.js_Ajax_Oauth 2.0 - Fatal编程技术网

Javascript Fitbit API的OAuth2隐式vs授权码授权

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构建一个本地服务器来承载应用程序,并能够毫无问题地

这个问题的答案是,我在客户端使用授权代码授权流。。这似乎会导致阻塞错误

在下面检查FITBIT API的功能验证OAUTH2隐式授权

我正在对Fitbit API执行OAuth2身份验证。这一切都使用授权代码授权流。因此,首先获取身份验证代码,将其重定向到我的应用程序,然后将其交换为访问令牌并使用该令牌获取数据

从post_request.html页面的主页开始,按下fitbit按钮,用户将重定向到fitbit的授权端点。我正在使用Node.js构建一个本地服务器来承载应用程序,并能够毫无问题地重定向

在被重定向时,我检索授权代码并发出AJAX POST请求,用授权代码换取访问令牌。然后我提出了这个POST请求,但我得到了以下错误

{"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>

谢谢你,我错过了这个。。我已经尝试使用隐式的授权流,这个函数。。授权授予流似乎仍然阻塞..问题是是否有可能这样做。。我会把你的答案标记为已接受的答案,这样其他人就不会感到困惑。。谢谢你的建议!