You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spotify Auth API返回400错误:code_verifier不正确的排查求助

解决Spotify PKCE授权中code_verifier不正确的问题

你的核心问题出在code_challenge的生成逻辑不符合PKCE规范:PKCE的S256方法要求对code_verifier字符串的ASCII字节做SHA-256哈希,而不是对生成code_verifier的原始随机字节做哈希,这直接导致服务器验证时哈希不匹配,返回错误。

错误原因分析

你的代码中,code_challenge是基于生成code_verifier的原始随机字节计算的:

_codeChallenge = base64UrlEncodeNoPadding((sha256.convert(codeVerifier).bytes));

但根据PKCE规范,正确逻辑应该是对编码后的code_verifier字符串的字节做哈希,而非原始随机字节。这就造成了你提交的code_challenge和服务器用code_verifier计算出的哈希完全不一致。

修正后的代码

1. 修正code_verifier和code_challenge生成逻辑

import 'dart:convert';
import 'dart:math';
import 'package:crypto/crypto.dart';

static void _createCodeVerifierAndChallenge() {
  final random = Random.secure();
  // 生成32字节随机数据,转成URL安全的base64字符串(无填充)作为code_verifier
  final codeVerifierBytes = List<int>.generate(32, (_) => random.nextInt(256));
  _codeVerifier = base64UrlEncodeNoPadding(codeVerifierBytes);
  
  // 关键修正:对code_verifier字符串的UTF-8字节做SHA-256哈希
  final challengeBytes = utf8.encode(_codeVerifier);
  final challengeHash = sha256.convert(challengeBytes);
  _codeChallenge = base64UrlEncodeNoPadding(challengeHash.bytes);

  print('Code Verifier: $_codeVerifier');
  print('Code Challenge: $_codeChallenge');
}

static String base64UrlEncodeNoPadding(List<int> input) =>
    base64Url.encode(input).replaceAll('=', '');

2. 额外检查点

  • 确保_codeVerifier和_codeChallenge在整个授权流程中未被重新生成:比如Flutter页面重建导致静态变量重置,或获取授权码后意外调用生成方法。建议将这两个值存入持久化存储(如SharedPreferences)避免状态丢失。
  • 确认POST请求的redirect_uri和GET授权请求中的完全一致,包括大小写、路径参数等,任何细微差异都会导致验证失败。
  • 检查POST请求body的编码:Dart的http库传入Map作为body时,会自动处理application/x-www-form-urlencoded编码,无需手动编码code_verifier。

内容的提问来源于stack exchange,提问作者tug89508

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 10:44:55