【问题标题】:Oauth2 and PKCE: Code verifier is invalidOauth2 和 PKCE:代码验证程序无效
【发布时间】:2022-11-22 12:56:12
【问题描述】:

我正在让客户端通过 OAuth2 进行授权,但我一直收到“代码验证程序无效”错误。

async function encode(input: string): Promise<string> {
  return btoa(string).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')
}

async function digestMessage(message) {
  const msgUint8 = new TextEncoder().encode(message);                           // encode as (utf-8) Uint8Array
  const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8);           // hash the message
  const hashArray = Array.from(new Uint8Array(hashBuffer));                     // convert buffer to byte array
  const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join(''); // convert bytes to hex string
  return hashHex;
}

function generateRandomString (len?: number) {
  var arr = new Uint8Array((len || 40) / 2)
  window.crypto.getRandomValues(arr)
  return Array.from(arr, dec2hex).join('')
}

async function pkceChallengeFromVerifier(v: string) {
  let hash = await digestMessage(v)
  let challenge = await encode(hash)
  return challenge
}

无论我输入什么验证器,它都会不断给我错误。

【问题讨论】:

    标签: typescript oauth-2.0 pkce


    【解决方案1】:

    不要将其转换为字符串!这完全改变了 base64 输出值!相反,base64 编码来自crypto.subtle.digest 的原始哈希缓冲区。

    使用 this solution 获取数组缓冲区的 base64:

    async function hashSHA256(str: string): Promise<ArrayBuffer> {
      const utf8 = new TextEncoder().encode(str);
      const hashBuffer = await crypto.subtle.digest('SHA-256', utf8);
      return hashBuffer;
    }
    
    async function base64_arraybuffer(data: ArrayBuffer): Promise<string> {
      // Use a FileReader to generate a base64 data URI
      const base64url: string = await new Promise((r) => {
          const reader = new FileReader()
          reader.onload = () => r(reader.result as string)
          reader.readAsDataURL(new Blob([data]))
      })
    
      /*
      The result looks like
      "data:application/octet-stream;base64,<your base64 data>",
      so we split off the beginning:
      */
      return base64url.split(",", 2)[1]
    }
    
    
    async function encode(input: ArrayBuffer): Promise<string> {
      return (await base64_arraybuffer(input)).replace(/+/g, '-').replace(///g, '_').replace(/=/g, '')
    }
    
    async function pkceChallengeFromVerifier(v: string) {
      let hash = await hashSHA256(v)
      let challenge = encode(hash)
      return challenge
    }
    

    还要确保输入的验证器字符串在 43 到 128 个字符的长度范围内。

    【讨论】:

      猜你喜欢
      • 2021-12-15
      • 2022-01-13
      • 2018-09-01
      • 1970-01-01
      • 2021-01-29
      • 2020-07-17
      • 2020-06-15
      • 2020-08-20
      • 1970-01-01
      相关资源
      最近更新 更多