expo中使用google Oauth

之前做的一个 expo 项目里有用到 google 登陆功能,特此记录一下:

1.申请 google credentials

首先需要登陆google cloud申请 Web ClientID、iOS ClientID、android ClientID。

Web ClientID

填入对应的后台地址,如果使用 expo Go 调试还需要加入auth.expo.io相关 url。

Image

[!CAUTION]
经我测试 expo 相关 url 并没有用,可能是我配置错了,这部分可以使用 expo development build 进行调试。

iOS ClientID

填入 iOS Bundle ID

Image

android ClientID

需要安装 Java JDK,终端运行cd ~/.android && keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android,将生成 SHA-1 fingerprint。

Image

[!WARNING]
android ClientID 我并没有使用,不确定是否正确。

2.使用

根据文档安装相关组件

npx expo install expo-auth-session expo-crypto

在组建中使用:

// 导入Google认证相关模块
import * as Google from "expo-auth-session/providers/google";
// 导入WebBrowser模块用于处理认证会话
import * as WebBrowser from "expo-web-browser";

// 处理可能存在的认证会话
WebBrowser.maybeCompleteAuthSession();

export default function LoginScreen() {
  // 使用Google认证hook,返回请求对象、响应对象和触发认证的函数
  const [request, response, promptAsync] = Google.useAuthRequest({
    webClientId: GOOGLE_CLIENT_ID,
    androidClientId: GOOGLE_ANDROID_CLIENT_ID,
    iosClientId: GOOGLE_IOS_CLIENT_ID,
  });

  // 监听认证响应
  useEffect(() => {
    // 当认证成功时处理返回的accessToken
    if (response?.type === "success") {
      handleGoogleSignIn(response.authentication.accessToken);
    }
  }, [response]);

  // 处理Google登录的函数
  const handleGoogleSignIn = async (token) => {
    if (!token) return;

    try {
      // 调用后端API进行认证
      const { data, error } = await googleAuth({
        access_token: token,
      }).unwrap();

      // 处理错误情况
      if (error) {
        Toast.show({
          type: "error",
          text2: error.message,
        });
      }

      // 认证成功,保存token并返回
      if (data) {
        dispatch(setToken(data.token));
        Toast.show({
          type: "success",
          text2: "登录成功",
        });
        router.back();
      }
    } catch (error) {
      // 处理异常情况
      Toast.show({
        type: "error",
        text2: "登录失败,请重试",
      });
    }
  };

  // 渲染Google登录按钮
  return (
    <TouchableOpacity
      className="items-center justify-center w-12 h-12 rounded-full bg-gray-100"
      onPress={async () => {
        await promptAsync(); // 执行google Oauth
      }}
      disabled={loading}
    >
      <Icons.AntDesign name="google" size={24} color="#4285F4" />
    </TouchableOpacity>
  );
}
posted @ 2025-11-17 18:45  jinzhepro  阅读(2)  评论(0)    收藏  举报