使用 apollo graphql 对 firebase 身份验证做出反应
Posted
技术标签:
【中文标题】使用 apollo graphql 对 firebase 身份验证做出反应【英文标题】:react firebase authentication with apollo graphql 【发布时间】:2018-12-03 09:47:58 【问题描述】:我发现了一篇很棒的文章,将身份验证添加到 react 中。 文章:https://www.robinwieruch.de/complete-firebase-authentication-react-tutorial/
本文使用一个 HOC 组件完成了 firebase 设置(在 redux 之前),我可以将其放入应用程序并可以通过上下文访问。
我的问题是如何将它放入应用程序组件之外的 apollo 客户端,因此即使在上下文中我也无法设置它。我对 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>
);
【问题讨论】:
以上这些你都做对了吗? @Phobos 我刚刚发布了一个关于我如何设置和工作的答案 【参考方案1】:所以这不是最好的方法,但这就是我目前的设置方式。
这是我的 apollo 客户端设置
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 助手类
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,看起来完全没有延迟。这可能不是最好的答案,因为当我刚刚学习所有内容时,我将几个文档放在一起,并且一直打算在我有时间但再次工作时返回并重新访问。
【讨论】:
以上是关于使用 apollo graphql 对 firebase 身份验证做出反应的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 apollo 服务器对 graphQl 中的数据进行排序?