Spotify PKCE code_verifier 不正确 [英] Spotify PKCE code_verifier was incorrect
问题描述
听到我现在可以使用 Spotify Web API 而无需通过 PKCE 的后端应用程序,我感到很兴奋.不幸的是,我似乎有某种误解,无法让它发挥作用.
I was excited to hear that I can now use the Spotify web API without having a backend application via PKCE. Unfortunately, I seem to have some sort of misunderstanding and have been unable to get it to work.
一路上我很可能犯了一些小错误,但我犯了一次没有用,我把石板擦干净,再试一次,但仍然没有运气.由此我认为我一定是误解了 文档.
I am likely making some minor mistake along the way, but I did it once to no avail and I wiped the slate clean and tried again but still without luck. From this I gather that I must be misunderstanding the documentation.
我会解释我在做什么,希望这里有人能指出我遗漏了什么或做错了什么.我假设我有一个基本的概念误解.
I will explain what I am doing and hopefully someone here can point out what I'm missing or doing wrong. I'm assuming I have a fundamental conceptual misunderstanding.
我首先使用名为 crypto-random-string 的 npm 包生成一个加密随机字符串.我将它存储在浏览器的本地存储中,然后使用 js-sha256 对其进行哈希处理,然后使用另一个名为 base64url 的 npm 包对其进行编码.
I first generate a cryptographically random string using an npm package called crypto-random-string. I store that in the browser's local storage before using js-sha256 to hash it and then using another npm package called base64url to encode it.
let verifier = cryptoRandomString({length: 50})
window.localStorage.setItem('verifier', verifier)
let params = {
client_id: '[MY CLIENT ID]',
response_type: 'code',
redirect_uri: 'http://localhost:3000/callback',
code_challenge_method: 'S256',
code_challenge: base64url(sha256(verifier))
}
let endpoint = new URL('https://accounts.spotify.com/authorize');
endpoint.search = new URLSearchParams(params);
window.location = endpoint.toString();
从这里,我使用正确的 url 参数重定向到/authorize 端点.我已经成功地做到了这一点,然后被相应地重定向到我提供的 redirect_uri,在那里我从 url 参数中获取给定的代码.
From here, I redirect to the /authorize endpoint with the proper url parameters. I have gotten this far successfully and then been redirected accordingly to my provided redirect_uri, where I grab the given code from the url parameters.
此时,我尝试使用 client_id、grant_type、从 url 参数中获取的代码、我的 redirect_uri 和本地存储的 code_verifier 获取/api/token 端点.
At this point, I try the fetch to the /api/token endpoint with the client_id, grant_type, the code I got from the url params, my redirect_uri, and the locally stored code_verifier.
let params = new URLSearchParams(window.location.search);
console.log(params.get('code'));
let newParams = {
client_id: '[MY CLIENT ID]',
grant_type: 'authorization_code',
code: params.get('code'),
redirect_uri: 'http://localhost:3000/callback',
code_verifier: window.localStorage.getItem('verifier')
}
let endpoint = new URL('https://accounts.spotify.com/api/token');
endpoint.search = new URLSearchParams(newParams);
fetch(endpoint.toString(), {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).then(data => data.json()).then(console.log)
此时,在我两次尝试后,我收到了错误:
At this point, after both of my attempts I received the error:
{ error: "invalid_grant", error_description: "code_verifier was incorrect" }
有什么我明显做错的地方吗?该错误使我相信就 code_verifier 的实际生成而言,我做错了什么,但我不知道该问题可能是什么.
Is there anything that I am obviously doing wrong? The error leads me to believe I'm doing something wrong as far as the actual generation of the code_verifier, but I am at a loss to what that issue may be.
推荐答案
Spotify 论坛上有人向我指出 这个 答案.不知道为什么,但按以下方式进行编码确实有效:
Someone on the Spotify forum pointed me to this answer. Not sure why exactly, but doing the encoding the following way does work:
async function sha256(plain) {
const encoder = new TextEncoder()
const data = encoder.encode(plain)
return window.crypto.subtle.digest('SHA-256', data)
}
function base64urlencode(a){
return btoa(String.fromCharCode.apply(null, new Uint8Array(a))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
}
const hashed = await sha256(verifyCode)
const codeChallenge = base64urlencode(hashed)
这篇关于Spotify PKCE code_verifier 不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!