【问题标题】:Add own properties to user object in firebase (react, redux) [duplicate]在firebase(react,redux)中向用户对象添加自己的属性[重复]
【发布时间】:2018-08-08 12:28:05
【问题描述】:

我正在尝试使用 firebase、react 和 redux 构建基于角色的身份验证。 在从应用程序级别创建新用户时,是否可以将自定义属性(例如“权限”或“角色”)添加到 Firebase 用户对象,或者我应该以其他方式完成?

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

我使用 firebase 云功能创建工作帐户,(因为当我尝试在本地执行此操作时,我使用新创建的帐户自动登录),然后设置包含用户角色的自定义声明. Cloud 函数还在解码一个 token,其中包含自定义声明。

这是我的代码 sn-ps:

云功能

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('/');
  }
});

React-router 公共路由组件,它不允许用户访问错误的路径。

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

【问题讨论】:

    标签: reactjs firebase redux firebase-authentication roles


    【解决方案1】:

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

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

    流程的一个例子是:

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

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

    【讨论】:

    • 很好的答案!虽然为了存储用户角色,我现在推荐using custom claims
    • Vlatko,逻辑上这是可以理解的方法,但我在技术上被困住了。我不需要任何安全规则(还),只需要有关用户角色的简单信息来创建路由。我的应用程序中有 3 条其他路线,每个角色一条。如果登录用户是管理员,让他进入管理页面,如果是简单用户 - 进入简单用户页面等。如何使其成为最简单的方法?
    • 最简单的方法是使用@frank-van-puffelen 建议的自定义声明。当您注册用户时,向他的帐户添加自定义声明,并将该信息保存到 Redux reducer,以便您可以在应用程序范围内使用它。如果您要持久登录(登录屏幕上的记住我选项),则将角色保存在 cookie 或本地存储中,具体取决于您使用的内容。下次您的用户打开网站时,您可以检查他们的 cookie 或本地存储以自动补充身份验证状态。如果您没有持久登录,您可以在用户下次登录网站时检查 firebase 上的声明。
    • 我只是尝试使用自定义声明,但是当我尝试将管理 SDK 导入我的项目时,我遇到了一堆编译错误,例如“找不到模块:错误:无法解析 'fs'” .
    • 您可能会尝试在客户端代码中使用 Admin SDK。那是行不通的(如果你让它工作,那将是一个很大的安全风险)。由于此代码设置了用户的角​​色,因此您不能让任何用户运行它。它需要在受信任的环境中运行,只有您和您的合作者可以访问。这可能是您的开发机器、您控制的服务器或 Cloud Functions for Firebase。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 2017-02-10
    • 2013-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多