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

如何在Expo+React Navigation v6应用内打开登录URL并向React Native传值

实现浏览器登录并存储登录状态到AsyncStorage(Expo + React Navigation v6)

一、核心逻辑说明

你提到的AWS Console式登录属于OAuth2/OpenID Connect授权码流程,核心步骤是:打开外部浏览器加载登录页→登录成功后通过深度链接唤起App→解析返回的令牌并存入AsyncStorage→用React Navigation管理登录态路由跳转。

二、具体实现步骤

1. 配置Expo深度链接

在app.json中添加自定义scheme,让App能被外部链接唤起:

{
  "expo": {
    "scheme": "yourappscheme", // 自定义协议名,比如myawsdemo
    // 其他原有配置
  }
}

2. 用Expo AuthSession处理登录跳转

Expo官方提供的expo-auth-session专门处理这类网页登录场景,先安装依赖:

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

基础实现代码示例:

import * as AuthSession from 'expo-auth-session';
import * as WebBrowser from 'expo-web-browser';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useEffect } from 'react';
import { Button } from 'react-native';

// 配置AWS登录相关端点(根据你的实际需求调整)
const discovery = {
  authorizationEndpoint: 'https://signin.aws.amazon.com/oauth',
  tokenEndpoint: 'https://aws.amazon.com/oauth2/token',
};

const LoginScreen = ({ navigation }) => {
  const [request, response, promptAsync] = AuthSession.useAuthRequest(
    {
      clientId: 'YOUR_AWS_CLIENT_ID', // 替换为你的AWS客户端ID
      scopes: ['openid', 'profile'],
      redirectUri: AuthSession.makeRedirectUri({ scheme: 'yourappscheme' }),
    },
    discovery
  );

  // 触发登录跳转
  const handleLogin = () => {
    promptAsync();
  };

  // 处理登录回调,存储令牌
  useEffect(() => {
    if (response?.type === 'success') {
      const { accessToken } = response.params;
      AsyncStorage.setItem('userToken', accessToken)
        .then(() => navigation.navigate('Home'))
        .catch(err => console.error('存储令牌失败:', err));
    }
  }, [response, navigation]);

  return <Button title="跳转到AWS登录" onPress={handleLogin} />;
};

export default LoginScreen;

3. AsyncStorage封装工具类

把存储逻辑封装成可复用的工具,方便多处调用:

import AsyncStorage from '@react-native-async-storage/async-storage';

export const storeUserToken = async (token) => {
  try {
    await AsyncStorage.setItem('userToken', token);
  } catch (error) {
    console.error('存储令牌出错:', error);
  }
};

export const getUserToken = async () => {
  try {
    return await AsyncStorage.getItem('userToken');
  } catch (error) {
    console.error('获取令牌出错:', error);
    return null;
  }
};

4. React Navigation v6 登录态路由守卫

在导航容器中根据令牌状态自动跳转登录页或首页:

import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import LoginScreen from './screens/LoginScreen';
import HomeScreen from './screens/HomeScreen';
import { getUserToken } from './utils/storage';
import { useState, useEffect } from 'react';
import { ActivityIndicator } from 'react-native';

const Stack = createNativeStackNavigator();

export default function App() {
  const [isLoading, setIsLoading] = useState(true);
  const [userToken, setUserToken] = useState(null);

  useEffect(() => {
    const checkLoginStatus = async () => {
      const token = await getUserToken();
      setUserToken(token);
      setIsLoading(false);
    };
    checkLoginStatus();
  }, []);

  if (isLoading) {
    return <ActivityIndicator size="large" />;
  }

  return (
    <NavigationContainer>
      <Stack.Navigator screenOptions={{ headerShown: false }}>
        {userToken ? (
          <Stack.Screen name="Home" component={HomeScreen} />
        ) : (
          <Stack.Screen name="Login" component={LoginScreen} />
        )}
      </Stack.Navigator>
    </NavigationContainer>
  );
}

三、学习资源推荐

GitHub仓库

  • 官方expo/expo仓库:expo-auth-session目录下有完整的OAuth登录示例,覆盖多种场景
  • react-native-async-storage/async-storage仓库:官方文档和示例,包含存储最佳实践
  • 搜索关键词:expo oauth login example,能找到社区分享的完整项目(比如基于AWS Cognito的实战示例)

YouTube视频

  • 搜索关键词:Expo OAuth2 Login with React Navigation v6,可找到一步步的实战教程,比如:
    • 讲解Expo AuthSession基础用法+React Navigation登录态管理的视频
    • 实现AWS网页登录并存储令牌到AsyncStorage的实操视频

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 05:40:04