Expo React Native集成Passport.js Google OAuth2.0遇网络错误及需求实现
Expo React Native 集成Google OAuth2.0 网络错误排查与解决
核心问题分析
你遇到的AxiosError: Network Error本质是OAuth2.0流程适配错误+跨域/网络地址配置问题:Axios是异步HTTP请求工具,无法处理Google OAuth需要的页面跳转逻辑;同时后端跨域、真机调试地址错误也会直接导致网络请求失败。
分步修复方案
1. 修正后端跨域配置
安装并配置cors中间件,允许Expo应用的请求来源:
const cors = require('cors'); const express = require('express'); const app = express(); // 替换为你的Expo应用地址(真机调试用电脑局域网IP) const allowedOrigins = ['http://localhost:8081', 'exp://192.168.x.x:8081']; app.use(cors({ origin: allowedOrigins, credentials: true, // 允许携带Session Cookie methods: ['GET', 'POST', 'OPTIONS'] }));
2. 调整API请求地址(真机调试必备)
Expo真机无法访问localhost,必须替换为电脑的局域网IP:
- 后端服务地址示例:
http://192.168.x.x:3000/auth/google - 确保手机和电脑在同一WiFi网络下
3. 重构前端登录逻辑(放弃Axios,改用深层链接)
Google OAuth需要跳转至Google登录页,不能用Axios异步请求,直接用expo-linking打开后端授权路由:
import * as Linking from 'expo-linking'; import { Button } from 'react-native'; const handleLogin = () => { // 直接打开后端Google授权地址,触发跳转 Linking.openURL('http://192.168.x.x:3000/auth/google'); }; // 谷歌登录按钮 <Button title="登录Google" onPress={handleLogin} />
4. 配置深层链接回调(完成登录闭环)
步骤1:Expo项目配置自定义Scheme
在app.json中添加自定义协议,用于Google登录完成后跳转回App:
{ "expo": { "scheme": "yourapp", // 自定义协议,如yourapp:// "ios": { "bundleIdentifier": "com.yourapp.id" }, "android": { "package": "com.yourapp.id" } } }
步骤2:Google Cloud Console配置回调地址
在Google云平台的OAuth2.0客户端设置中,添加授权重定向URI:
yourapp://auth/google/callback
步骤3:后端处理回调并返回Token
调整Passport的回调路由,生成用户Token并跳回App:
app.get('/auth/google/callback', passport.authenticate('google', { failureRedirect: '/' }), (req, res) => { // 生成JWT或Session Token const token = generateToken(req.user); // 跳转回Expo应用,携带Token res.redirect(`yourapp://auth/google/callback?token=${token}`); } );
步骤4:前端监听回调并跳转首页
在App入口监听深层链接,处理登录回调:
import * as Linking from 'expo-linking'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { useNavigation } from '@react-navigation/native'; const App = () => { const navigation = useNavigation(); useEffect(() => { const handleDeepLink = async (url) => { const { path, queryParams } = Linking.parse(url); if (path === '/auth/google/callback' && queryParams.token) { // 保存Token到本地 await AsyncStorage.setItem('userToken', queryParams.token); // 跳转首页 navigation.replace('Home'); } }; // 监听深层链接 Linking.addEventListener('url', handleDeepLink); // 检查初始链接(App从后台唤起场景) Linking.getInitialURL().then(handleDeepLink); return () => Linking.removeEventListener('url', handleDeepLink); }, [navigation]); // ...其他组件逻辑 };
5. 验证后端Session配置(可选)
如果使用Passport Session,确保Session中间件配置正确:
const session = require('express-session'); app.use(session({ secret: 'your-strong-secret-key', resave: false, saveUninitialized: false, cookie: { secure: false, // 开发环境禁用HTTPS,生产环境开启 sameSite: 'lax', maxAge: 24 * 60 * 60 * 1000 // Session有效期1天 } })); app.use(passport.initialize()); app.use(passport.session());
内容的提问来源于stack exchange,提问作者Harry 408
相关产品推荐
相关产品推荐

