javascript 在ReactJS中为Spotify API上的PKCE认证创建代码验证器和挑战

unguejic  于 2023-03-28  发布在  Java
关注(0)|答案(3)|浏览(159)

我正试图添加Spotify认证到我的单页React应用程序后,从他们的API文档。
到目前为止,这是我如何根据我在网上找到的解决方案生成代码的:

const generateVerifier = () => {
    return crypto.randomBytes(64).toString('hex');
}

const getChallenge = verifier => {
    return crypto.createHash('sha256')
        .update(verifier)
        .digest('base64')
        .replace(/\+/g, '-')
        .replace(/\//g, '_')
        .replace(/=/g, '')
}

下面是我使用该技术创建的一对代码的示例:

  • 验证人:e8c3745e93a9c25ce5c2653ee36f5b4fa010b4f4df8dfbad7055f4d88551dd960fb5b7602cdfa61088951eac36429862946e86d20b15250a8f0159f1ad001605
  • 挑战:CxF5ZvoXa6Cz6IcX3VyRHxMPRXYbv4PADxko3dwPF-I

我创建的一对旧代码的例子:

  • 验证人:1jp6ku6-16xxjfi-1uteidc-9gjfso-1mcc0wn-tju0lh-tr2d8k-1auq4zk
  • 挑战:SRvuz5GW2HhXzHs6b3O_wzJq4sWN0W2ma96QBx_Z77s

然后,我从API得到一个响应,说“code_verifier was incorrect.”我在这里做错了什么?

yzuktlbb

yzuktlbb1#

请尝试按照此指南生成代码以生成代码质询和验证器
以下是重要的部分:

生成验证码

// GENERATING CODE VERIFIER
function dec2hex(dec) {
  return ("0" + dec.toString(16)).substr(-2);
}

function generateCodeVerifier() {
  var array = new Uint32Array(56 / 2);
  window.crypto.getRandomValues(array);
  return Array.from(array, dec2hex).join("");
}

验证器生成代码质询

function sha256(plain) {
  // returns promise ArrayBuffer
  const encoder = new TextEncoder();
  const data = encoder.encode(plain);
  return window.crypto.subtle.digest("SHA-256", data);
}

function base64urlencode(a) {
  var str = "";
  var bytes = new Uint8Array(a);
  var len = bytes.byteLength;
  for (var i = 0; i < len; i++) {
    str += String.fromCharCode(bytes[i]);
  }
  return btoa(str)
    .replace(/\+/g, "-")
    .replace(/\//g, "_")
    .replace(/=+$/, "");
}

async function generateCodeChallengeFromVerifier(v) {
  var hashed = await sha256(v);
  var base64encoded = base64urlencode(hashed);
  return base64encoded;
}

这是一个working example
您还可以检查代码here的有效性

bwleehnv

bwleehnv2#

我从passport oauth2库中提取了这个代码片段来生成代码验证器和代码质询。

const code_verifier = base64url(crypto.pseudoRandomBytes(32));

const code_challenge = crypto
     .createHash("sha256")
     .update(code_verifier)
     .digest();
fsi0uk1n

fsi0uk1n3#

完全工作和验证的示例:

const {randomBytes, createHash} = require("node:crypto");
// OR: import {randomBytes, createHash} from "crypto";

function generatePKCEPair() {
    const NUM_OF_BYTES = 22; // Total of 44 characters (1 Bytes = 2 char) (standard states that: 43 chars <= verifier <= 128 chars)
    const HASH_ALG = "sha256";
    const randomVerifier = randomBytes(NUM_OF_BYTES).toString('hex')
    const hash = createHash(HASH_ALG).update(randomVerifier).digest('base64');
    const challenge = hash.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); // Clean base64 to make it URL safe
    return {verifier: randomVerifier, challenge}
}

运行示例:

generatePKCEPair();
// Result:
{
  verifier: '3e2727957a1bd9f47b11ff347fca362b6060941decb4',
  challenge: '1SF5UEwYplIjmAwHUwcitzp9qz8zv98uYflt-tBmwLc'
}

相关问题