【发布时间】:2021-12-15 06:09:03
【问题描述】:
我正在制作一个 Java 应用程序,我正在尝试为需要 PKCE(代码交换证明密钥)的 API (Etsy.com) 实现 OAuth2 授权流程。我已经尝试了一段时间,但是在交换 OAuth 令牌的访问代码时,我一直遇到以下错误:
{"error":"invalid_grant","error_description":"code_verifier is invalid"}
下面是通过sha256编码验证器生成初始URL的方法:
@Override
public String getOAuth2AuthorizationUrl() {
String sha256hex = null;
try {
if(_currentVerifier == null)
_currentVerifier = PkceUtil.generateCodeVerifier();
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] encodedhash = digest.digest(
_currentVerifier.getBytes(StandardCharsets.UTF_8));
sha256hex = new String(encodedhash);
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
UnicodeEscaper basicEscaper = new PercentEscaper("-", false);
System.out.println("sha256="+sha256hex);
System.out.println("veri="+_currentVerifier);
String oAuth2AuthorizationUrl = super.getOAuth2AuthorizationUrl();
var authUrl = oAuth2AuthorizationUrl
+"&state=asdf&code_challenge_method=S256&code_challenge='"
+ basicEscaper.escape(sha256hex)+"'";
return authUrl;
}
然后我发送请求以交换令牌代码作为 application/x-www-form-urlencoded POST-request:
UnicodeEscaper basicEscaper = new PercentEscaper("-", false);
var params = "grant_type=authorization_code&client_id="
+token.getOwner().clientId+"&redirect_uri="
+basicEscaper.escape("https://localhost")
+"&code="+accessCode+"&code_verifier="+basicEscaper.escape(_currentVerifier)+"";
我尝试了很多变体,还尝试将值包装在 '' 等中,但没有任何效果。我误解了这个过程吗?我最初发送一个 sha256 字符串,在请求 OAuth2 令牌时,我发送的是编码的值。 有什么想法吗?
更新: 我尝试使用 Google 库生成哈希,但仍然遇到同样的错误。
Hasher hasher = Hashing.sha256().newHasher();
hasher.putString(CODE_VERIFIER, Charsets.UTF_8);
HashCode sha256 = hasher.hash();
System.out.println("veri="+AppUtils.encodeBase64(AppUtils.toHexString(sha256.asBytes())));
String oAuth2AuthorizationUrl = super.getOAuth2AuthorizationUrl();
var authUrl = oAuth2AuthorizationUrl
+"&state=asdf&code_challenge_method=S256&code_challenge="+AppUtils.encodeBase64(AppUtils.toHexString(sha256.asBytes()));
return authUrl;
code_challenge 参数的格式在示例中看起来也不同。
【问题讨论】: