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

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

问题描述

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

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

本文完成了Firebase的安装(在Redux之前),其中包含一个HOC组件,我可以将其放入应用程序并可以通过上下文进行访问.

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.

这是我在主要应用程序组件中的阿波罗客户端.

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.

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

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天全站免登陆