我一直试图将state和code_challenge添加到我们的流中,但出于某种原因,我继续从亚马逊获得invalid_request响应。
我跟着这个Auth0教程到了一个发球台。
/**
* Converts buffer to Base64 URL encoded string
*
* @param {Buffer} buf The buffer to convert
* @returns {string}
*/
private base64URLEncode(str: any): string {
return str.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}
/**
* Generates a new code challenge
*
* @returns {string} The code challange string
*/
private generateCodeChallenge(): string {
if (!this._verifier) this._verifier = this.base64URLEncode(crypto.randomBytes(32));
return this.base64URLEncode(crypto.createHash('sha256').update(this._verifier).digest());
}
/**
* Generates the Authorization URL
*/
public generateAuthUrl(): string {
if (!this.config.clientId) throw new Error('Client ID is missing from configuration.');
if (!this.config.redirectUrl) throw new Error('Redirect URI is missing from configuration.');
if (!this._state) this._state = this.base64URLEncode(crypto.randomBytes(28));
return `${this.config.protocol}://signin.${
this.config.host
}/login?response_type=code&client_id=${this.config.clientId}&redirect_uri=${
this.config.redirectUrl
}&scope=${this._scope.join('%20')}&state=${
this._state
}&code_challenge_method=S256&code_challenge=${this.generateCodeChallenge()}`;
}
/**
* Verifies that the state matches
*
* @returns {boolean}
*/
public verifyState(state: string): boolean {
return this._state === state;
}
/**
* Retrieves a new OAuth Authorization Grant token
*/
public async getToken(code: string): Promise<UserAccessToken> {
if (!this.config.clientId) throw new Error('Client ID is missing from configuration.');
if (!this.config.redirectUrl) throw new Error('Redirect URI is missing from configuration.');
try {
const token = (await this.req.postform(
`/oauth2/token`,
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Cache-Control': 'no-store',
},
},
{
grant_type: 'authorization_code',
code,
client_id: this.config.clientId,
code_verifier: this._verifier,
redirect_uri: this.config.redirectUrl,
}
)) as UserAccessToken;
this._userAccessToken = token;
return token;
} catch (err) {
throw err;
}
}一切都进行得很顺利,直到用代码交换令牌为止。我们重定向到托管的UI,并成功地获得了一个代码。当我们用它交换一个令牌时,不管我尝试了什么,我们都会得到一个invalid_request响应。如果我删除了代码挑战,所有事情都会像预期的那样工作,所以我很有信心这就是导致问题的原因。



更新1
这个函数在useEffect钩子内部的function应用程序中调用,如下所示:
useEffect(() => {
const authUrl = sdk.auth.generateAuthUrl();
console.log(authUrl);
if (!code) window.location.assign(authUrl);
console.log(`New Auth URL: ${authUrl}`);
sdk.auth
.getToken(code as string)
.then((token) => {
localStorage.setItem('sdk_access_token', JSON.stringify(token));
sdk.organizations.getUser().then((user) => {
setUser({ ...user });
history.push('/');
});
})
.catch((err) => console.log(err));
}, []);两个console.log语句都显示相同的URL:

但是在“网络调试”选项卡上,请求URL是不同的:

那件事怎么可能?window.location.href是否以某种方式对URL进行编码?
发布于 2021-04-18 19:46:04
据我所知,您的代码和消息看起来很好。如果你有一个应用程序客户端的秘密配置在科尼图,这将解释问题(认知错误反应不是最好的)。
也许可以尝试使用我的认知样本中的硬编码值-或者运行您正在通过这个工具计算的值。这将使您能够知道问题是否与PKCE值有关:
有很多带有工作PKCE代码的库,尽管我希望Auth0代码很好.
https://stackoverflow.com/questions/67140624
复制相似问题