【发布时间】:2021-08-12 15:13:48
【问题描述】:
我正在尝试构建一个允许我通过nodejs express 服务器从create-react-app 客户端调用Spotify 的API 的应用程序。我正在尝试使用Authorization Code Flow。
它可以使用以下代码获取授权代码以生成 URL,完全在客户端(是否以及如何使用服务器端是另一个问题):
getSpotifyCodeUrl() {
const authEndPoint = 'https://accounts.spotify.com/authorize'
const clientId = CLIENT_ID;
const responseType = 'code';
const redirectUrl = 'http://localhost:3000/';
// TODO: state for cross-site request forgery protection
// cont state = '...';
const scope = 'user-read-private user-read-email';
return(
authEndPoint +
'?response_type=' + responseType +
'&client_id=' + clientId +
(scope ? '&scope=' + encodeURIComponent(scope) : '') +
'&redirect_uri=' + encodeURIComponent(redirectUrl)
)
}
用户只需单击上面生成的带有 href 的链接。
{!this.state.token ? <a className="btn btn--loginApp-link" href={this.getSpotifyCodeUrl()}>
Login to Spotify
</a> : ""}
用户被重定向回来后,我使用以下函数从中提取授权码
componentDidMount() {
this.setState({code: new URLSearchParams(window.location.search).get('code')});
}
我使用代码检索访问令牌。来自客户的电话:
getSpotifyAccessToken() {
fetch('/auth?code=' + this.state.code)
.then((res) => res.json())
.then(data => {
this.setState({token: data.token});
localStorage.setItem('token', this.state.token);
});
}
服务器上的 API 调用:
app.get("/auth", (req, res) => {
let code = req.query.code;
let authOptions = {
url: 'https://accounts.spotify.com/api/token',
form: {
code: code,
redirect_uri: 'http://localhost:3000/',
grant_type: 'authorization_code'
},
headers: {
'Authorization': 'Basic ' + (new Buffer.from(clientId + ':' + clientSecret).toString('base64'))
},
json: true
};
request.post(authOptions, function(error, response, body){
if (!error && response.statusCode === 200) {
token = body.access_token;
res.json({ token: "Token: " + body.access_token});
} else {
console.log("/auth response body")
console.log(body)
}
});
});
奇怪的是我得到了一个令牌,但在我的服务器终端中也可以看到以下错误:
{ 错误:'invalid_grant', error_description: '无效的授权码' }
如果我随后尝试使用令牌从客户端发出(简单)请求:\
getSpotifyMe() {
fetch('/me?token=' + this.state.token)
.then((res) => res.json())
.then(data => {
console.log(data);
});
}
以及对应的服务器调用:
app.get("/me", (req, res) => {
let token = req.query.token;
console.log("Token: " + token);
let options = {
url: 'https://api.spotify.com/v1/me',
headers: { 'Authorization': 'Bearer ' + token },
json: true
}
request.get(options, function(error, response, body) {
console.log("/me request body");
console.log(body);
if (!error && response.statusCode === 200) {
res.json(body);
} else {
}
})
})
这给了我一个 401 错误:
{ 错误:{状态:401,消息:'无效的访问令牌'} }
我已经尝试了一些东西。从客户那里打来电话,没有成功。刷新令牌,删除 cookie,从帐户授权,但没有成功。奇怪的是我可以使用在Spotify Web Console 中无效的令牌,执行与我在应用程序中尝试执行的完全相同的调用。
您知道我在哪里导致我的应用程序出现这些错误(invalid_grant 和 401)吗?我该如何解决?
【问题讨论】:
标签: node.js express oauth-2.0 create-react-app spotify