使用 apollo graphql 响应 firebase 身份验证 [英] react firebase authentication with apollo graphql

查看:34
本文介绍了使用 apollo graphql 响应 firebase 身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have found a great article adding authentication into react. Article: https://www.robinwieruch.de/complete-firebase-authentication-react-tutorial/

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

This article finishes the firebase setup (before redux) with a HOC component that I can put into the app and can access with context.

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

My issue is how do i put this into the apollo client which is outside of the app component so even with the context I cant set it. I have this same problem with redux. Only one I have found is use local storage but I would like to avoid that.

这是我在主应用组件中的 apollo 客户端.

This is my apollo client in the main app component.

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>
);

推荐答案

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

So this my not be the best way but this is how I have it setup at the moment.

这是我的 apollo 客户端设置

this is my apollo client setup

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 助手类

This is my firebase helper class I import

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设置相关信息

And lastly on the server here is my graphql setup relevent information I use

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,看起来根本没有延迟.这可能不是最好的答案,因为当我刚刚学习所有东西时,我将它从几个文档中汇总在一起,并且一直打算在我有时间但再次工作时回去重温.

This answer works and gets me the UID of the user authorized through firebase and looks like there is no delay at all. This might not be the best answer because I Put this together from several documents when I was just learning everything and have been meaning to go back and revisit when I have time but again, working.

这篇关于使用 apollo graphql 响应 firebase 身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆