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

Expo安卓应用Google OAuth遇400错误及redirect_uri配置困惑

Expo安卓应用Google OAuth认证问题解决

问题描述

首次在Expo中实现安卓应用的Google OAuth认证时,出现错误:

You can't sign in to this app because it doesn't comply with Google's OAuth 2.0 policy for keeping apps secure.
同时不清楚redirect_uri的配置方式,相关代码如下:

const redirectUri = AuthSession.makeRedirectUri();
const login = () => {
    const [userInfo, setUserinfo] = useState();
    const [request, response, promptAsync] = Google.useAuthRequest({
        androidClientId: process.env.EXPO_PUBLIC_ANDROID_GOOGLE_CLIENT_ID || "",
        redirectUri: redirectUri,
        usePKCE: false
    });
    console.log(request)

    useEffect(() => {
        console.log(process.env.EXPO_PUBLIC_ANDROID_GOOGLE_CLIENT_ID)
        if(response?.type == "success"){
            const {authentication} = response;
            getUserInfo(authentication?.accessToken)
        }
    }, [response])

    async function getUserInfo(token: string | undefined){
        try{
            const response = await fetch('https://www.googleapis.com/userinfo/v2/me', {
                headers: {Authorization: `Bearer ${token}`}
            })
            const user = await response.json()
            setUserinfo(user)
        } catch(exc){
            console.error("Error getting user info with access token", exc)
        }
    }
}

解决方案

1. 修复PKCE配置(核心错误)

Google OAuth 2.0政策强制要求移动端应用使用PKCE(Proof Key for Code Exchange)保障安全,你代码中usePKCE: false直接违反了该规则,这是报错的主要原因。

  • 将usePKCE改为true。

2. 正确配置Redirect URI

Expo中AuthSession.makeRedirectUri()会自动生成对应环境的重定向URI,但需要在Google Cloud控制台中将这些URI添加到授权列表:

  • Expo Go预览环境:
    运行应用后,通过console.log(redirectUri)拿到实际生成的URI(格式类似exp://192.168.xxx.xxx:8081--auth或exp://your-project-slug.exp.direct--auth),把这个值添加到Google Cloud的OAuth客户端「已授权的重定向URI」中。
  • 自定义开发构建/生产构建:
    重定向URI格式为com.your.app.package://expo-auth-session,替换com.your.app.package为你的安卓应用包名(在app.json的android.package字段中设置),同样添加到Google Cloud的授权列表。

3. 修正代码中的Hook位置错误

React Hooks(如useState、useEffect)不能定义在普通函数内部(你的login函数里),必须移到组件顶层。修正后的代码示例:

import { useState, useEffect } from 'react';
import { Google, AuthSession } from 'expo';

export default function LoginScreen() {
    const [userInfo, setUserinfo] = useState<any>(null);
    const redirectUri = AuthSession.makeRedirectUri();
    
    const [request, response, promptAsync] = Google.useAuthRequest({
        androidClientId: process.env.EXPO_PUBLIC_ANDROID_GOOGLE_CLIENT_ID || "",
        redirectUri: redirectUri,
        usePKCE: true // 必须开启PKCE
    });

    useEffect(() => {
        console.log(process.env.EXPO_PUBLIC_ANDROID_GOOGLE_CLIENT_ID);
        if(response?.type === "success"){
            const {authentication} = response;
            getUserInfo(authentication?.accessToken);
        }
    }, [response])

    async function getUserInfo(token: string | undefined){
        if(!token) return;
        try{
            const response = await fetch('https://www.googleapis.com/userinfo/v2/me', {
                headers: {Authorization: `Bearer ${token}`}
            })
            const user = await response.json();
            setUserinfo(user);
        } catch(exc){
            console.error("获取用户信息失败", exc);
        }
    }

    return (
        // 你的页面JSX
        <button onClick={() => promptAsync()}>登录Google</button>
    )
}

4. 其他必要检查

  • 确保androidClientId是Google Cloud中创建的安卓类型OAuth客户端ID,不要混用网页或iOS的客户端ID。
  • 检查Google Cloud安卓客户端配置中的SHA-1指纹:
    • 使用Expo Go时,固定SHA-1为BB:0D:AC:74:D3:21:E1:43:67:71:9B:62:91:AF:A1:66:6E:44:5D:75。
    • 自定义构建时,需要生成你应用签名证书的SHA-1指纹并添加到配置中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 12:47:15