将自己的属性添加到Firebase中的用户对象(反应,redux)

时间:2018-08-08 12:28:06

标签: reactjs firebase redux firebase-authentication roles

我正在尝试使用Firebase,React和Redux构建基于角色的身份验证。 从应用程序级别创建新用户时,是否可以通过任何方式在Firebase用户对象中添加自定义属性(例如“ permission”或“ role”),还是应该以其他方式进行设置?

@ 更新-问题已解决 我按照@ frank-van-puffelen的建议,使用自定义声明构建了基于角色的Firebase身份验证。有三个角色:管理员,工作人员和客户。只有管​​理员才能创建工作人员帐户,客户通过google +登录。

我使用Firebase云功能创建了工作人员帐户(因为当我尝试在本地执行此操作时,我已使用新创建的帐户自动登录),然后设置包含用户角色的自定义声明。云功能还可以解码包含自定义声明的令牌

这是我的代码段:

云功能

const functions = require('firebase-functions');
const cors = require('cors');
const corsHandler = cors({origin: true});
const admin = require('firebase-admin');
admin.initializeApp();

exports.createWorkerAccount = functions.https.onRequest((request, response) => {
  corsHandler(request, response, () => {
    response.status(200).send('Hello from Cloud Function');
  });
  admin.auth().createUser({
   email: request.body.email,
   password: request.body.password
  }).then(() => {
    admin.auth().getUserByEmail(request.body.email).then((user) => {
      admin.auth().setCustomUserClaims(user.uid, {role: 'worker'});
    });
  });
});

exports.getToken = functions.https.onRequest((request, response) => {
  const token = admin.auth().verifyIdToken(request.body.token) //decoding token that contains custom claims
.then((t) => { 
    corsHandler(request, response, () => {
      response.status(200).send(t.role); //sending role as a response
  });
   });
});

这两个函数都由简单的ajax请求调用。

用户角色作为请求响应返回,然后被推送到 redux状态,因此我可以从应用程序中的任何位置访问它。

要将登录的用户重定向到特定路径并限制它,我正在使用react-router公共和私有路径以及firebase函数onAuthStateChanged。

检测Firebase身份验证状态更改-它会根据自定义声明将用户重定向到特定路径。

firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    store.dispatch(login(user.uid));

    firebase.auth().currentUser.getIdToken() //getting current user's token
    .then((t) => {
      getTokenRequest(t) // Promise containing the reqest
      .then((role) => {
        store.dispatch(permissions(role)); //dispatching role to store
        renderApp();
        if (role == "admin") {
          console.log('admin');
          history.push('/admin/dashboard'); //redirecting to user-role-specific path
        }
        else if (role == "worker") {
          history.push('/worker/dashboard');
        } 
        else {
          history.push('/customer/dashboard');
        }
      });
    });

  } else {
    store.dispatch(logout());
    renderApp();
    history.push('/');
  }
});

反应路由器公共路由组件,它不允许用户访问错误的路径。

export const PublicRoute = ({
  isAuthenticated,
  role,
  component: Component,
  ...rest 
}) => (
    <Route {...rest} component={(props) => {
      if(isAuthenticated && role == "admin") {
        return <Redirect to="/admin/dashboard" />
      } else if (isAuthenticated && role == "") {
        return <Redirect to ="/customer/dashboard" />
      }
      else {
        return <Component {...props} />
      }
    }} />
  );

const mapStateToProps = (state) => ({
  isAuthenticated: !!state.auth.uid,
  role: state.role
});

export default connect(mapStateToProps)(PublicRoute);

1 个答案:

答案 0 :(得分:1)

否,您不能将任何配置文件信息附加到用户对象。 Firebase用户对象中显然存在用于此目的的字段用于社交身份验证(例如,使用Facebook,Google + ...登录)。

如果您需要添加自己的应用程序特定字段,则需要将它们添加到其数据库解决方案之一(例如Firestore)中。

流程示例:

  1. 使用firebase SDK创建用户。
  2. 创建用户后,您可以 得到     新创建的用户的ID。推送包含用户的新JSON     配置文件,并具有到数据库的以下路由: users / $ {userId}

如果使用这种模式,您将始终能够从数据库中提取相关的用户配置文件(与用户具有相同的ID),而实际上并不需要以任何方式将其与用户帐户链接。