POST请求中缺少授权头

时间:2020-07-23 08:58:20

标签: javascript http sonos

我正在尝试使用fetch().

将POST请求发送到URL

我正在故意设置Authorization标头,但是当我在Firefox Dev Tools中检查响应时,它会输出以下错误“缺少String类型的方法参数的请求标头'Authorization'”

        var target_url = "https://api.sonos.com/login/v3/oauth/access";
        var encoded_msg = btoa(client_id + ':' + secret); // base64-encodes client_id and secret using semicolon as delimiter
        var params = `grant_type=authorization_code` + `&code=${authCode}` + `&redirect_uri=${redirect_uri}`;
        var myHeaders = new Headers({
            'Authorization': `Basic ${encoded_msg}`,
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'POST',
            'Content-Length': params.length,
            'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
        });
    
        fetch(target_url, {
            method: 'POST',
            mode: 'no-cors',
            credentials: 'include',
            redirect: 'follow',
            headers: myHeaders,
            body: params
        })
        .then(response => {
            console.log("Status: " + response.status);
            console.log("StatusText: " + response.statusText);
            console.log("Type: " + response.type);
            console.log("URL: " + response.url);
        });

什么删除了Authorization-Header,为什么以及如何阻止它?

修改:
为了澄清起见,我使用Firebase Cloud Functions托管我的网页,然后将请求从该网页发送到Sonos Authorization API
使用Postman,请求得以处理,我得到了正确的答复。

1 个答案:

答案 0 :(得分:1)

您要执行的用于检索访问令牌的步骤必须在Cloud函数端点中执行。

获取访问令牌
获得授权码后,使用它来获取访问令牌和刷新令牌。使用访问令牌通过Sonos云将API调用发送给家庭。此步骤使用您的客户端密钥,因此它应该是服务器端请求,而不是客户端(基于浏览器)请求。

参考: https://developer.sonos.com/build/direct-control/authorize/

node-fetch作为package.json中的依赖项引入,因为它的API实现与浏览器获取密切相关。

添加端点如下:


const fetch = require('node-fetch');
const functions = require('firebase-functions');

const secret = functions.config().sonos.secret;
const client_id = functions.config().sonos.client_id;
const redirect_uri = functions.config().sonos.redirect_uri;

exports.retrieveAccessToken = functions.https.onRequest(async (req, res) => {
        const {authCode} = req.query;
        const target_url = "https://api.sonos.com/login/v3/oauth/access";
        const encoded_msg = btoa(`${client_id}:${secret}`); // base64-encodes client_id and secret using semicolon as delimiter
        const body = `grant_type=authorization_code&code=${authCode}&redirect_uri=${redirect_uri}`;
        const headers = new Headers({
            'Authorization': `Basic ${encoded_msg}`,
            'Content-Length': body.length,
            'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
        });
    
        const response = await fetch(target_url, {
            method: 'POST',
            redirect: 'follow',
            headers,
            body
        });

       const token_data = await response.json();
       return token_data;
});

在用户从Sonos登录服务返回后,修改网页中的代码以向云功能端点发出请求。

 
 const authCode = new URLSearchParams(window.location.search).get('code');

 fetch(`https://us-central1-<project-id>.cloudfunctions.net/retrieveAccessToken?authCode=${code}`);