我正在尝试使用fetch().
我正在故意设置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,请求得以处理,我得到了正确的答复。
答案 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}`);