如何使用React Native与GraphQL开发含注册登录登出认证功能的应用
基于React Native + GraphQL实现用户认证全流程方案
1. 前置准备
首先确认你已经配置好React Native开发环境,后端GraphQL服务已完成以下基础能力:
- 提供注册、登录的Mutation接口
- 支持JWT(或其他类型token)鉴权,请求头携带
Authorization: Bearer <token>即可识别用户身份 - 提供获取当前登录用户信息的Query接口,用于启动时校验登录状态
需要提前安装的核心依赖:
@apollo/client:主流GraphQL客户端,也可以用Relay替换graphql:GraphQL基础依赖@react-native-async-storage/async-storage:用于本地持久化存储用户token- 路由库(React Navigation或其他你常用的路由方案)
2. 后端GraphQL接口约定
前后端对接前先确认接口结构,参考示例如下:
# 注册接口 mutation Signup($email: String!, $password: String!, $username: String!) { signup(email: $email, password: $password, username: $username) { token user { id email username } } } # 登录接口 mutation Login($email: String!, $password: String!) { login(email: $email, password: $password) { token user { id email username } } } # 获取当前登录用户信息,用于校验登录状态 query Me { me { id email username } }
3. Apollo客户端初始化
配置Apollo客户端实现自动携带鉴权token,简化后续请求逻辑:
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client'; import { setContext } from '@apollo/client/link/context'; import AsyncStorage from '@react-native-async-storage/async-storage'; const httpLink = createHttpLink({ uri: '你的GraphQL服务端接口地址', }); // 拦截所有请求,自动注入存储的token到请求头 const authLink = setContext(async (_, { headers }) => { const token = await AsyncStorage.getItem('userToken'); return { headers: { ...headers, authorization: token ? `Bearer ${token}` : '', } }; }); export const client = new ApolloClient({ link: authLink.concat(httpLink), cache: new InMemoryCache(), });
在App根组件包裹ApolloProvider使全局可调用GraphQL接口:
import { ApolloProvider } from '@apollo/client'; import { client } from './apollo'; export default function App() { return ( <ApolloProvider client={client}> {/* 你的根路由组件 */} </ApolloProvider> ); }
4. 核心功能实现
4.1 注册功能
import { useState } from 'react'; import { useMutation, gql } from '@apollo/client'; import AsyncStorage from '@react-native-async-storage/async-storage'; const SIGNUP_MUTATION = gql` mutation Signup($email: String!, $password: String!, $username: String!) { signup(email: $email, password: $password, username: $username) { token user { id email username } } } `; const SignupScreen = ({ navigation }) => { const [formData, setFormData] = useState({ email: '', password: '', username: '' }); const [signup, { loading, error }] = useMutation(SIGNUP_MUTATION, { onCompleted: async (data) => { // 存储token到本地 await AsyncStorage.setItem('userToken', data.signup.token); // 注册成功直接跳转到登录后的首页 navigation.replace('Home'); }, onError: (err) => { // 处理后端返回的错误,比如邮箱已占用、密码长度不够 alert(err.message); } }); const handleSubmit = () => { // 先做前端表单校验 if (!formData.email || !formData.password || !formData.username) { return alert('请填写完整注册信息'); } signup({ variables: formData }); }; // UI渲染部分省略 }
4.2 登录功能
逻辑和注册几乎一致,仅调用的Mutation不同:
const LOGIN_MUTATION = gql` mutation Login($email: String!, $password: String!) { login(email: $email, password: $password) { token user { id email username } } } `; // 提交逻辑和注册完全相同,调用login Mutation,成功后存储token跳转首页即可
额外补充App冷启动登录状态判断逻辑,避免用户每次打开App都要重新登录:
const ME_QUERY = gql` query Me { me { id email username } } `; const RootNavigator = () => { const { data, loading } = useQuery(ME_QUERY, { // 首次加载优先走网络请求校验token有效性 fetchPolicy: 'network-only' }); if (loading) return <Loading组件 />; return ( <NavigationContainer> {/* 能拿到用户信息就渲染登录后的路由栈,否则渲染注册登录路由栈 */} {data?.me ? <AuthenticatedStack /> : <UnauthenticatedStack />} </NavigationContainer> ); };
4.3 登出功能
import { useApolloClient } from '@apollo/client'; import AsyncStorage from '@react-native-async-storage/async-storage'; const LogoutButton = ({ navigation }) => { const client = useApolloClient(); const handleLogout = async () => { // 如果后端有登出接口可以先调用,清除服务端的session/refresh token // 清除本地存储的token await AsyncStorage.removeItem('userToken'); // 清空Apollo缓存,避免残留之前用户的隐私数据 await client.resetStore(); // 跳转回登录页 navigation.replace('Login'); }; return <Button title="退出登录" onPress={handleLogout} />; };
5. 注意事项
- 生产环境必须使用HTTPS,避免token、密码等敏感信息明文传输
- 可以在Apollo的错误链路里加全局拦截,检测到401鉴权失败时自动清token跳登录页
- 不要在AsyncStorage里存储密码、身份证号等极度敏感信息,仅存token即可
- 前端表单校验和后端校验都要做,不能仅依赖前端校验
- 想要优化体验可以加refresh token机制,避免token过期后用户频繁重新登录
内容的提问来源于stack exchange,提问作者questgecko
相关产品推荐
相关产品推荐

