Axios(不工作)与Postman(工作)的差异- Google OAuth2调用刷新访问令牌

dgjrabp2  于 2022-12-12  发布在  iOS
关注(0)|答案(2)|浏览(215)

我正在使用Google OAuth2流程,编写一个函数,该函数获取我保存到数据库中的refresh_token,并调用该函数以获得刷新的access_token。问题是,当我通过Postman调用时,它成功了,但当我试图通过axios在代码中调用时,它失败了。
呼叫的Postman配置如下所示:

我的代码片段如下所示:

export const getNewAccessToken = async (refreshToken: string): Promise<string> => {
    const url = 'https://oauth2.googleapis.com/token';
    const data = {
        refresh_token: refreshToken,
        grant_type: "refresh_token",
        client_id: process.env.GOOGLE_CLIENT_ID,
        client_secret: process.env.GOOGLE_CLIENT_SECRET,
    };

    try {
        let res = await axios.post(url, data, {
            headers: {
                'content-type': 'application/x-www-form-urlencoded'
            },
        }).then(response => {
            debugger;
        }).catch(e => {
            // It always enters the 'catch' here
            debugger;
        });
    } catch (e) {
        debugger;
    }
}

我已经检查过了,我用来测试的refresh_token,client_id和client_secret在两种情况下都是相同的。
当我进行这个调用时,catch中的错误显示400错误请求,并且response.data是{错误:'不支持的授权类型',错误描述:'无效的授权类型:'}
我错过了什么明显的东西吗?我可以尝试做什么来调试?
我尝试过的一件事是查看错误e,以查看发出了什么请求,但我似乎找不到原始请求在ClientRequest对象中的位置。

编辑1:

下面是来自Postman的curl命令:

curl --location --request POST 'https://oauth2.googleapis.com/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'refresh_token=[confirmed same refresh_token as the code]' \
--data-urlencode 'client_id=[ditto]' \
--data-urlencode 'client_secret=[ditto]' \
--data-urlencode 'grant_type=refresh_token'
vu8f3i0k

vu8f3i0k1#

如果你给予Axios一个JavaScript对象作为请求主体发送,Axios会将其序列化为JSON。但在这种情况下,你将Content-Type头设置为application/x-www-form-urlencoded,这意味着提供URL编码的主体,而不是JSON。URL编码的主体如下所示:

refresh_token=abc&grant_type=abc&client_id=abc&client_secret=abc

有很多不同的方法可以创建这样一个字符串作为主体发送,其中一些方法在Axios documentation中有详细说明。

const data = new URLSearchParams({
  refresh_token: refreshToken,
  grant_type: 'refresh_token',
  client_id: process.env.GOOGLE_CLIENT_ID,
  client_secret: process.env.GOOGLE_CLIENT_SECRET,
});

或者,如果您只是将Content-Type头设置为application/json,它 * 可能 * 也会工作,但这取决于API以及它是否能够接受JSON。

8nuwlpux

8nuwlpux2#

尝试此代码

export const getNewAccessToken = async (refreshToken: string): Promise<string> => {
    const url = 'https://oauth2.googleapis.com/token';
    const data = new URLSearchParams({
        refresh_token: refreshToken,
        grant_type: 'refresh_token',
        client_id: process.env.GOOGLE_CLIENT_ID,
        client_secret: process.env.GOOGLE_CLIENT_SECRET,
    });

    try {
        let res = await axios.post(url, data, {
            headers: {
                'content-type': 'application/x-www-form-urlencoded',
                'Accept-Charset': 'UTF-8'
            },
        }).then(response => {
            debugger;
        }).catch(e => {
            // It always enters the 'catch' here
            debugger;
        });
    } catch (e) {
        debugger;
    }
}

相关问题