代码之家  ›  专栏  ›  技术社区  ›  Mel

与Firebase反应-CRUD操作之间的拆分授权

  •  0
  • Mel  · 技术社区  · 5 年前

    我正在尝试使用react和firebase制作一个应用程序,允许所有用户读取所有内容,一些用户写入一些函数。

    目前,我已经设置了firestore安全规则,允许所有用户读写所有内容,然后我有了一个带授权的包装器,我想把它放在一个组件上,该组件包含一个链接,用于编写新文档。我知道这是不安全的,但我只是想知道如何分离代码,以便我可以建立视图层,使内容呈现符合我写的权限。

    现在我有一个引用列表,它是所有创建的引用的索引。在这个列表的底部,我有一个名为“AddReference”的组件,它是一个指向表单的链接,用于创建新的引用。

    列表没有用我的授权包装纸包装。AddReference组件被包装。

    相反,整个列表在身份验证重定向后被阻止。

    import React, { Component } from 'react';
    import { Link, withRouter } from 'react-router-dom';
    import { compose } from 'recompose';
    import { withFirebase } from '../../Firebase/Index';
    import * as ROUTES from '../../../constants/Routes';
    import { ReferencesList } from './ReferencesList';
    import {  Layout, Typography, Card, List, Button, Divider } from 'antd';
    import {ReferencesForm} from './Form';
    import AddReference from './AddReference';
    
    const { Content } = Layout 
    const { Title, Paragraph, Text } = Typography;
    
    
    class ReferencesPage extends Component {
    
      render() {
        return (
          <div>
              <Content
                style={{
                  background: '#fff',
                  padding: 24,
                  margin: "auto",
                  minHeight: 280,
                  width: '90%'
                }}
              >
                <ReferencesList/>
                <br/>
                <AddReference />
              </Content>
    
          </div>
        );
      }
    }
    
    export default ReferencesPage;
    

    我的AddReference组件具有:

    import React, { Component } from 'react';
    import { Link, withRouter } from 'react-router-dom';
    import { compose } from 'recompose';
    import { withFirebase } from '../../Firebase/Index';
    import * as ROUTES from '../../../constants/Routes';
    import { ReferencesList } from './ReferencesList';
    import {  Layout, Typography, Card, List, Button, Divider } from 'antd';
    import {ReferencesForm} from './Form';
    import { AuthUserContext, withAuthorization, withEmailVerification } from '../../Session/Index';
    
    
    const { Content } = Layout 
    const { Title, Paragraph, Text } = Typography;
    
    
    const AddReference = () => (
    
    <AuthUserContext.Consumer>
        {authUser => (
    
    
            <div>
    
                    <Divider></Divider>
                    <div style={{
                    display: "flex",
                    justifyContent: "center"
                    }}>
                    <Link to={ROUTES.REFERENCESFORM}>Add a Reference</Link>
                    </div>
    
    
    
            </div>
    
    )}
    </AuthUserContext.Consumer>
    );
    
    
    const condition = authUser => !!authUser;
    export default compose(
    // withEmailVerification,
    withAuthorization(condition),
    )(AddReference);
    

    我的授权包装有:

    import React from 'react';
    import { withRouter } from 'react-router-dom';
    import { compose } from 'recompose';
    import { withFirebase } from '../Firebase/Index';
    import AuthUserContext from './Context';
    import * as ROUTES from '../../constants/Routes';
    
    
    const withAuthorization = condition => Component => {
      class WithAuthorization extends React.Component {
        // componentDidMount() {
        //   this.listener = 
    this.props.firebase.auth.onAuthStateChanged(authUser => {
        //     if (!condition(authUser)) {
        //       this.props.history.push(ROUTES.SIGN_IN);
        //     }
        //   });
        // }
        componentDidMount() {
          this.listener = this.props.firebase.onAuthUserListener(
            authUser => {
              if (!condition(authUser)) {
                this.props.history.push(ROUTES.SIGN_IN);
              }
            },
            () => this.props.history.push(ROUTES.SIGN_IN),
          );
        }
        componentWillUnmount() {
          this.listener();
        }
        render() {
          return (
            <AuthUserContext.Consumer>
              {authUser =>
                condition(authUser) ? <Component {...this.props} /> : null
              }
            </AuthUserContext.Consumer>
          );
        }
      }
      return compose(
        withRouter,
        withFirebase,
      )(WithAuthorization);
    };
    export default withAuthorization;
    

    是否可以将组件包装在未包装的页面上呈现的授权要求中?我仍然想为不满足授权条件的用户显示列表的内容(AddReference组件除外)。

    0 回复  |  直到 5 年前
        1
  •  3
  •   Aabir Hussain    5 年前

    1>如何以优化的方式实现权限?

    回答:

    Best practice for React Router user roles (Firebase)

    Role-Based Access Control (RBAC) and React Apps

    是否可以将组件包装在未包装的页面上呈现的授权要求中?我仍然想为不满足授权条件的用户显示列表的内容(AddReference组件除外)。

    是的,让所有用户都可以访问该页,并隐藏不应公开的页内容。

    回答: 红色 , 本地存储 ,等等),在初始化时,我们将在其中存储用户角色(来宾、登录等)。当我们需要从组件中隐藏一个元素时,我们只需要检查下面的值

    //set state.userRole from globalState in init function.
    (this.state.userRole == 'login') ?
    <Icon name='md-log-out' style={styles.logoutIcon} button onPress={() =>
                Alert.alert(
                    'Log out',
                    'Do you want to logout?',
                    [
                        { text: 'Cancel', onPress: () => { return null } },
                        {
                            text: 'Confirm', onPress: () => {this.logout()}
                        },
                    ],
                    { cancelable: false }
                )
            }/>
            :
            <View />;