Google Oauth Error: redirect_uri_mismatch

Google Oauth Error: redirect_uri_mismatch

我正在尝试使用 google Oauth 2 通过 google 日历 API 对 AWS EC2 上的 Web 服务器 运行 进行身份验证。

当我生成凭据时,我选择了 'OAuth Client ID',然后是 'Web Application'。对于我输入的授权重定向 URI:

http://ec2-XX-XX-XX-XXX.eu-west-1.compute.amazonaws.com (我已经删除了我的 EC2 实例的 IP)。我已经检查过这是我希望回调转到的正确 URL。

服务器日志中生成的 link 格式为:

https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=XXXXXXXXXXXX-XXXXXXXXXXXXXX.apps.googleusercontent.com&redirect_uri=http://localhost:47258/Callback&response_type=code&scope=https://www.googleapis.com/auth/calendar.readonly

当我按照 link 时,我得到了错误 'Error: redirect_uri_mismatch'.

我已阅读 this SO question 并检查我使用的是 HTTP 并且没有试用“/”

我怀疑生成的 URL 不应该包含 'localhost' 但我已经多次重置 client_secret.json 并且每次我重新启动 tomcat新的客户端密码我仍然通过本地主机获得 link,但只是通过不同的端口。

在本地,我之前选择了 'other' 的凭据类型,但没有为授权重定向 URI 提供选项。我确实为 EC2 实例尝试过此操作,但这不会给我想要的对重定向 URI 的控制并通过本地主机发送重定向。

Google 当随请求提供的 uri(包括端口)与在应用程序中注册的不匹配时抛出 redirect_uri_mismatch

确保您在 Web 控制台上正确注册了 Authorised redirect URIsAuthorised JavaScript origins

这是适合我的示例配置。

创建 Oauth 客户端 ID 时,请勿 select 网络应用程序,Select "Other"。这样,就不需要重定向 URI。

如果您在从服务器进行 API 调用以获取令牌时看到此错误。

简答 - 是什么解决了我的问题

使用字符串 postmessage 代替您在云控制台上配置的实际 redirectUri

这是我对 OAuth2 客户端的初始化,对我有用。

// import {Auth, google} from 'googleapis`;

const clientID = process.env.GOOGLE_OAUTH_CLIENT_ID;
const clientSecret = process.env.GOOGLE_OAUTH_CLIENT_SECRET;
oauthClient = new google.auth.OAuth2(clientID,clientSecret,'postmessage');

我的案例

在前端,我使用 React 提示用户使用 google 和 authentication-code 流程登录。成功时,此 returns code 中的负载需要发布到 google API 服务器以获取 token - Access Token, Refresh TokenID Token

我在我的服务器上使用 googleapis 包。以下是我如何从 google

检索用户信息
// import {Auth, google} from 'googleapis`;

const clientID = process.env.GOOGLE_OAUTH_CLIENT_ID;
const clientSecret = process.env.GOOGLE_OAUTH_CLIENT_SECRET;
oauthClient = new google.auth.OAuth2(clientID,clientSecret,'postmessage');

/*
    get tokens from google to make api calls on behalf of user.
    @param: code -> code posted to backend from the frontend after the user successfully grant access from consent screen
*/
const handleGoogleAuth = (code: string) => {
    oauthClient.getToken(code, async (err, tokens: Auth.Credentials) {
        if (err) throw new Error()

        // get user information
        const tokenInfo = await oauthClient.verifyIdToken({
          idToken: tokens.id_token
        });
    
        const {email, given_name, family_name, email} = tokenInfo.getPayload();
        // do whatever you want to do with user informaton
    }
}