首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Spotify PKCE code_verifier不正确

Spotify PKCE code_verifier不正确
EN

Stack Overflow用户
提问于 2020-07-26 02:43:38
回答 2查看 1.3K关注 0票数 4

我很高兴听到我现在可以使用Spotify web API,而不必通过PKCE拥有后端应用程序。不幸的是,我似乎有某种误解,一直无法使它发挥作用。

我很可能在路上犯了一些小错误,但是我做了一次,但没有结果,我把板子擦干净了,又试了一次,但还是没有运气。由此,我想我一定是误解了文档

我会解释我在做什么,希望这里的人能指出我错过了什么或者做错了什么。我假设我有一个基本的概念误解。

我首先使用一个名为密码随机字符串的npm包生成一个密码随机字符串。在使用js-sha256对其进行散列之前,我将其存储在浏览器的本地存储中,然后使用另一个名为base64url的npm包对其进行编码。

代码语言:javascript
运行
复制
    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参数中获取给定的代码。

此时,我尝试使用client_id、grant_type、从url参数获取的代码、我的redirect_uri和本地存储的code_verifier来获取/api/token端点。

代码语言:javascript
运行
复制
    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)

此时,在两次尝试之后,我都收到了错误:

代码语言:javascript
运行
复制
{ error: "invalid_grant", error_description: "code_verifier was incorrect" }

很明显我做错了什么吗?这个错误让我相信我在做一些错误的事情,直到code_verifier的实际产生,但我不知道这个问题可能是什么。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-07-30 14:05:21

Spotify论坛上有人告诉我的答案。不确定确切原因,但按以下方式进行编码确实有效:

代码语言:javascript
运行
复制
    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)
票数 5
EN

Stack Overflow用户

发布于 2021-06-01 13:48:52

以前的答复和评论,除了OP之外,已经记录了所需的大部分信息,所以我只会补充一些帮助我的信息:

验证器本身的大部分被编码为Base64-URL。

Pseduo代码(正如我自己在C#中的代码):

代码语言:javascript
运行
复制
verifier = Base64UrlEncode(GetRandomString(length: 50))
challenge = Base64UrlEncode(HashWithSha256(verifier))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63095557

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档