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

Go(Gin-Gonic/Gothic)后端对接React Native Expo登录回调跳转问题

解决React Native Expo客户端对接Go后端谷歌登录回调跳转问题

核心思路

Expo客户端无法直接接收Web端的回调请求,需要通过**深链接(Deep Linking)**将登录结果(JWT)从后端传递回客户端。调整后端回调逻辑,将原本返回JSON的方式改为重定向到客户端深链接并携带JWT;客户端使用Expo Auth Session或Linking API监听深链接,完成登录状态同步。


一、后端Go代码调整

1. 修改回调函数CompleteAuth

将原本返回JSON的逻辑改为重定向到客户端深链接,把JWT作为查询参数传递(生产环境建议用临时存储+短码替代直接传token,避免暴露风险,以下为演示示例):

func (auth *AuthAPI) CompleteAuth(c *gin.Context) {
	q := c.Request.URL.Query()
	provider := c.Param("provider")
	q.Add("provider", provider)
	c.Request.URL.RawQuery = q.Encode()

	user, err := gothic.CompleteUserAuth(c.Writer, c.Request)
	if err != nil {
		c.AbortWithError(http.StatusInternalServerError, err)
		return
	}

	// 原有用户注册/查询逻辑保持不变
	var user_id = user.UserID
	var user_provider = user.Provider
	count := auth.database_connection.QueryRow("SELECT COUNT(*) FROM auth WHERE id = $1 AND method = $2", user_id, user_provider)

	var user_count int
	err = count.Scan(&user_count)
	if err != nil {
		c.AbortWithStatus(http.StatusNotFound)
		slog.Warn("User not found", "user", user_id, "err", err)
		return
	}

	if user_count == 0 {
		var new_user_id int
		err := auth.database_connection.QueryRow("INSERT INTO users (username, email) VALUES ($1, $2) RETURNING id", user.Name, user.Email).Scan(&new_user_id)
		if err != nil {
			c.AbortWithError(http.StatusInternalServerError, err)
			return
		}

		_, err = auth.database_connection.Exec("INSERT INTO auth (id, method, user_id) VALUES ($1, $2, $3)", user_id, user_provider, new_user_id)
		if err != nil {
			c.AbortWithError(http.StatusInternalServerError, err)
			return
		}
	}

	// 生成JWT
	token, err := generateJWT(user.UserID)
	if err != nil {
		c.AbortWithError(http.StatusInternalServerError, err)
		return
	}

	// 定义客户端深链接(需提前配置Expo的scheme)
	// 示例scheme:myapp://auth/callback
	clientRedirectUrl := fmt.Sprintf("myapp://auth/callback?token=%s", token)
	// 重定向到客户端深链接
	c.Redirect(http.StatusFound, clientRedirectUrl)
}

2. 确认Gothic回调配置

确保Gothic初始化时,谷歌OAuth的回调地址已设置为后端的/login/google/callback(原有配置正常则无需修改)。


二、React Native Expo客户端实现

1. 配置深链接Scheme

在app.json中添加自定义scheme:

{
  "expo": {
    "scheme": "myapp",
    // 其他项目配置...
  }
}

2. 实现登录流程与回调监听

先安装依赖:

npx expo install expo-auth-session expo-web-browser

编写登录页面代码:

import React, { useEffect, useState } from 'react';
import { Button, View, Text } from 'react-native';
import * as WebBrowser from 'expo-web-browser';
import * as Linking from 'expo-linking';

// 替换为你的后端实际地址
const BACKEND_BASE_URL = 'http://your-backend-domain.com';

export default function LoginScreen() {
  const [token, setToken] = useState(null);

  // 从后端获取谷歌登录跳转URL
  const getAuthUrl = async () => {
    const response = await fetch(`${BACKEND_BASE_URL}/login/google`);
    const data = await response.json();
    return data.redirectUrl;
  };

  // 监听深链接回调,解析token
  useEffect(() => {
    const handleDeepLink = async (event) => {
      const urlParams = new URLSearchParams(event.url.split('?')[1]);
      const loginToken = urlParams.get('token');
      if (loginToken) {
        setToken(loginToken);
        // 这里可将token存入AsyncStorage,再跳转到首页
        console.log('登录成功,token:', loginToken);
      }
    };

    // 监听实时深链接
    Linking.addEventListener('url', handleDeepLink);
    // 检查App启动时的初始深链接(比如从浏览器跳转回来的场景)
    Linking.getInitialURL().then(url => url && handleDeepLink({ url }));

    return () => Linking.removeEventListener('url', handleDeepLink);
  }, []);

  // 触发登录流程
  const handleGoogleLogin = async () => {
    const authUrl = await getAuthUrl();
    await WebBrowser.openAuthSessionAsync(authUrl);
  };

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      {token ? (
        <Text>登录成功!</Text>
      ) : (
        <Button title="使用谷歌登录" onPress={handleGoogleLogin} />
      )}
    </View>
  );
}

关键注意事项

  • 生产环境安全:不要直接在URL中传递JWT,建议后端生成临时短码,客户端拿到短码后再请求后端换取JWT,降低泄露风险。
  • 谷歌OAuth配置:确保谷歌开发者控制台中,已将后端/login/google/callback添加到授权回调地址列表。
  • 深链接测试:Expo开发环境可使用npx expo start --dev-client测试,真机需用Expo Go扫码或打包测试。

内容的提问来源于stack exchange,提问作者Margin Petrisor-Victor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 13:23:20