使用 apollo graphql 反应 firebase 身份验证

2024-02-23

我发现一篇很棒的文章将身份验证添加到反应中。 文章:https://www.robinwieruch.de/complete-firebase-authentication-react-tutorial/ https://www.robinwieruch.de/complete-firebase-authentication-react-tutorial/

本文使用 HOC 组件完成了 firebase 设置(在 redux 之前),我可以将其放入应用程序中并可以通过上下文进行访问。

我的问题是如何将其放入应用程序组件之外的阿波罗客户端中,因此即使有上下文我也无法设置它。我对 redux 也有同样的问题。我发现的唯一一个是使用本地存储,但我想避免这种情况。

这是我的主应用程序组件中的 apollo 客户端。

const client = new ApolloClient({   
    uri: clientUrl,
  request: async operation => {
        const token = How_do_i_set_this <-- ???
        console.log('token in request', token)
    operation.setContext({
      headers: {
        authorization: token ? `Bearer ${token}` : ''
      }
    });
    }
});

const App = () => (
    <DashAppHolder>
        <ApolloProvider client={client}>
            <Provider store={store}>
                <PublicRoutes history={history} />
            </Provider>
        </ApolloProvider>
    </DashAppHolder>
);

所以这不是最好的方法,但这就是我目前的设置方式。

这是我的阿波罗客户端设置

import Firebase from './helpers/firebase';
import ApolloClient from "apollo-boost";

const client = new ApolloClient({   
    uri: clientUrl,
  request: async operation => {
    const fireToken = await Firebase.token();
    console.log('fire token', fireToken);
    operation.setContext({
      headers: {
        authorization: fireToken ? `Bearer ${fireToken}` : 'token bad'
      }
    });
    }
});

这是我导入的 firebase helper 类

import firebase from 'firebase';
import 'firebase/firestore';
import { firebaseConfig } from '../../settings';

const valid = firebaseConfig && firebaseConfig.apiKey && firebaseConfig.projectId;

const firebaseApp = firebase.initializeApp(firebaseConfig);
const firebaseAuth = firebase.auth;

class FirebaseHelper {
    isValid = valid;
    EMAIL = 'email';
    FACEBOOK = 'facebook';
    GOOGLE = 'google';
    GITHUB = 'github';
    TWITTER = 'twitter';
    constructor() {
        this.login = this.login.bind(this);
        this.logout = this.logout.bind(this);
        this.signup = this.signup.bind(this);
        this.resetPassword = this.resetPassword.bind(this);
        this.doPasswordUpdate = this.doPasswordUpdate.bind(this);
        this.auth = this.auth.bind(this);
        this.database = firebase.firestore();
    }
    token = async() => {
        const user = this.user()
        if (user) {
            return await user.getIdToken().then(token => { return token });
        } else {
            return null;
        }
    }

    user() {
        return firebaseAuth().currentUser;
    }

    login(provider, info) {
        switch (provider) {
            case this.EMAIL:
                return firebaseAuth().signInWithEmailAndPassword(
                    info.email,
                    info.password
                );
            case this.GOOGLE:
                var googleProvider = new firebase.auth.GoogleAuthProvider();
                return firebaseAuth().signInWithPopup(googleProvider);
            default:
        }
    }

    signup(provider, info) {
        switch (provider) {
            case this.EMAIL:
                return firebaseAuth().createUserWithEmailAndPassword(
                    info.email,
                    info.password
                );
            case this.FACEBOOK:
                return firebaseAuth().FacebookAuthProvider();
            case this.GOOGLE:
                return firebaseAuth().GoogleAuthProvider();
            case this.GITHUB:
                return firebaseAuth().GithubAuthProvider();
            case this.TWITTER:
                return firebaseAuth().TwitterAuthProvider();
            default:
                alert('defaulted');
        }
    }

    logout() {
        return firebaseAuth().signOut();
    }

    auth = () => {
        return firebaseAuth()
    }
    resetPassword(email) {
        return firebaseAuth().sendPasswordResetEmail(email);
    }

    doPasswordUpdate(password) {
        firebaseAuth().currentUser.updatePassword(password);
    }

    createNewRef() {
        return firebase
            .database()
            .ref()
            .push().key;
    }
}

最后在服务器上这是我使用的 graphql 设置相关信息

const admin = require('firebase-admin');

const getUid = async (request) => {
    let idToken = (request.headers && request.headers.authorization) ? request.headers.authorization : null;
    if (!idToken) {
        console.log('no token found');
        return null;
   }
    console.log('raw token', idToken);
    var newToken = idToken.replace("Bearer ", "");
    console.log('pure token', newToken)
    let uid = await admin.auth().verifyIdToken(newToken)
        .then(decodedToken => {
            var uid = decodedToken.uid;
            return uid;
        }).catch((error) => {
            // Handle error
            console.log('uid failed', error);
            return null;
        });
    console.log('uid found', uid);
    return uid;
}

app.use(
    '/graphql',
    cors(),
    express.json(),
    graphqlExpress(async (request) => ({
        schema: schema,
        context: {
            request: request,
            uid: await getUid(request),
            accountLoader: new Dataloader(keys => batchAccounts(keys, db)),
            dealLoader: new Dataloader(keys => batchDeals(keys, db)),
        }
    })),
);

这个答案有效,让我获得了通过 firebase 授权的用户的 UID,看起来根本没有延迟。这可能不是最好的答案,因为当我刚刚学习所有内容时,我将这些文件放在一起,并且一直打算在有时间但再次工作时回去重新访问。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 apollo graphql 反应 firebase 身份验证 的相关文章

  • Firebase queryOrderedbyChild 不返回 Null 值

    我有一个根据年龄搜索用户的查询 self ref child users queryOrdered byChild age queryStarting atValue 18 queryEnding atValue 25 observeSin
  • React - 按下按钮,继续调用函数

    我正在尝试实现缩放功能 onClick 工作正常 但我希望当我按住缩放按钮时它会连续缩放 我如何用 ReactJS 来实现这个 Jquery mousedown效果 按住左键时 https stackoverflow com questio
  • 在复选框内映射复选框 ReactJS

    我有一个函数 一旦主复选框被选中 就会触发子复选框 并且所有这些复选框都是从 JSON 映射的 主复选框 最高级别 及其下面的所有子复选框 第二级别 都会在单击时显示 并且效果很好 我想要显示的是单击时主复选框 第三级别 的子复选框2 级项
  • Typescript 和 React 使用空类型数组设置初始状态

    假设我有以下片段 interface State alarms Alarm export default class Alarms extends React Component lt State gt state alarms 因为我想设
  • 嵌套对象的 setState

    我有一个嵌套对象作为状态 并且在组件中有一个表单 我正在考虑每次用户在表单中输入某些内容时更新状态 并且为了避免为每个输入创建许多函数 我正在考虑使用 switch 创建单个函数 使用 switch 创建单一函数是个好主意吗 如何更新对象的
  • 添加 Google Play Services 9.0.0 后 Dex 文件超过 64k

    我按照 Firebase 指南添加 FCM 因此我将以下依赖项添加到我的应用程序 gradle 中 compile com google android gms play services 9 0 0 apply plugin com go
  • 如何使用 Jest 测试 React 渲染的异步数据?

    我使用 React 进行渲染 使用 Jest Jasmine 进行测试 我用旧的 Jest Jasmine 编写了测试waitsFor and runs但这些现在在 Jasmine 2 中已经消失了 我不知道如何用新的替换done asyn
  • 12501 错误:Ionic 构建应用程序时使用什么密钥库

    我在用Ionic 2 with GooglePlus 身份验证 https ionicframework com docs v2 native google plus 一切都很完美iOS For Android我按如下方式构建我的应用程序
  • React router.push 和 router.replace 之间的区别?

    有什么区别React 路由器推送 and 路由器 替换 路由器历史记录就像一个stack of routes 当您使用router replace 您将覆盖堆栈的顶部 当使用router push 它在顶部添加了一条新路线stack 路由器
  • Apollo 客户端延迟刷新

    In Apollo Client v3React 实现 我使用钩子来使用订阅 当我从订阅接收数据时 我想重新获取查询 但前提是查询之前已执行过并且位于缓存中 有办法实现这一点吗 我首先进行惰性查询 然后在收到订阅数据时手动检查缓存 然后尝试
  • React 文件预览 (FIREBASE)

    我目前将文件存储在 Firebase 存储中 我希望能够实时生成每个文件的文件预览 映射 例如 PDF 文件会将第一页显示为图像 docx 将是文档的第一页 pptx 将是第一张幻灯片 未知文档将是默认文档符号 有人知道有什么好的服务可以轻
  • React Material UI CardMedia 视频组件未播放

    我看到缩略图 但无法启动或停止视频 还有什么方法可以让它自动播放和重复吗 https material ui com api card media https material ui com api card media
  • AngularFire 访问子元素方法

    我正在寻找一种方法来获取子元素的方法 而不是单独加载该元素 假设我有一个帖子模型 每个帖子都有评论 这就是我获取帖子模型的方式 var post firebase new Firebase FIREBASE URL posts post n
  • npm 命令 create-react-app 失败

    我正在尝试在运行 Os X sierra 10 12 6 的计算机 mac pro 2017 上测试reactjs 我已经遵循了 Facebook 教程 确保您安装了最新版本的 Node js done 按照安装说明进行操作创建一个新项目
  • React - 无法读取未定义的属性[重复]

    这个问题在这里已经有答案了 通常 当我单击子组件中的菜单项时 它会调用 this handlesort 这是一个本地函数 处理排序从我的父组件中获取 onReorder 属性 onReorder 调用名为 reOrder 的本地函数 它设置
  • 在 webpack 2.x 中使用 autoprefixer 和 postcss

    如何使用autoprefixer使用 webpack 2 x 以前 它曾经是这样的 module loaders test scss loader style css sass postcss postcss gt return autop
  • firebase :: 无法读取 null 的属性“props”

    你好 我正在尝试将react router与firebase一起使用 但它给了我这个错误 无法读取 null 的属性 props 这正是代码 我正在其中使用我的反应路由器 向下代码位于作为登录面板组件的组件上 else if this em
  • 在 React 中实现 Google 登录错误 -

    我正在尝试在 React 中实现 google 登录 这是我的组件 import Fragment useEffect from react import GOOGLE CLIENT ID from some file const Goog
  • 没有用于警告的设置器/字段 Firebase 数据库检索数据填充列表视图

    我只是想将 Firebase 数据库中的数据填充到我的列表视图中 日志显示正在检索数据 但适配器不会将值设置为列表中单个列表项中的文本 它只说 没有二传手 场地插入值 这让我觉得我的设置器没有正确制作 但 Android Studio 自动
  • 在 React.js 中编辑丰富的数据结构

    我正在尝试为数据结构创建一个简单的基于网格的编辑器 但我在使用 React js 时遇到了一些概念问题 他们的文档对此没有太大帮助 所以我希望这里有人可以提供帮助 首先 将状态从外部组件传输到内部组件的正确方法是什么 是否有可能将内部组件中

随机推荐