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

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 05:42:04