【问题标题】:Adding custom page without authentication in react-admin在 react-admin 中添加无需身份验证的自定义页面
【发布时间】:2019-04-27 11:11:03
【问题描述】:

我想向我的react-admin 门户网站添加一个注册页面。由于react-admin 没有提供注册页面,所以我创建了一个自定义页面并将其添加到自定义路由中:

customRoutes.js

import React from 'react';
import { Route } from 'react-router-dom';
import SignupForm from './signupForm';

export default [
    <Route path="/signup" component={SignupForm} noLayout/>,
];

问题是我只能在用户已经登录时打开/signup 的页面。否则我会自动重定向到/login 路由。

如何禁用自定义路由的身份验证?是否有&lt;Route&gt; 接受的某些属性或与dataProvider.js 有关的属性?

编辑

为我的signupForm.js添加代表代码:

import React from 'react';
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import Dialog from '@material-ui/core/Dialog';
import { fetchUtils } from 'react-admin';
import { ApiUrl } from './config';

class SignupForm extends React.Component {
    constructor() {
        super();
        this.state = {
            fields: {
                username: '',
                password: ''
            }
    }


    handleChange = name => event => {
        let fields = this.state.fields;
        fields[name] = event.target.value;

        this.setState({
            fields: fields,
        });
    };

    handleSubmit = (event) => {
        // Prevent default
        event.preventDefault();

        if (this.handleValidation()) {
            let body = JSON.parse(JSON.stringify(this.state.fields));

            let url = ApiUrl + '/api/user/create';
            let options = {}
            options.headers = new Headers({ Accept: 'application/json' });
            options.method = 'POST'
            options.body = JSON.stringify(body);
            fetchUtils.fetchJson(url, options)
                .then(data => {
                    alert(data.json.message);
                    this.props.history.push('/login')
                })
                .catch((err, ...rest) => {
                    console.log(err.status, err.message);
                    alert(err.message);
                });
        }
    }

    render() {
        const { classes } = this.props;

        const actions = [
            <Button
                type="submit"
                label="Submit"
                color='primary'
                variant="flat"
            >Submit</Button>,
        ];

        return (
            <Dialog
                open={true}
                style={{
                    textAlign: "center",
                }}
                onClose={this.handleClose}
                classes={{ paper: classes.dialogPaper }}
            >
                <DialogTitle>Create an Account</DialogTitle>
                <form className={classes.container} noValidate autoComplete="off" onSubmit={this.handleSubmit}>
                    <TextField
                        required
                        id="username"
                        label="Username"
                        value={this.state.fields["username"]}
                        onChange={this.handleChange('username')}
                    />
                    <br />
                    <TextField
                        required
                        id="password"
                        label="Password"
                        value={this.state.fields["password"]}
                        onChange={this.handleChange('password')}
                        type="password"
                    />

                    <div style={{ textAlign: 'right', padding: 40 }}>
                        {actions}
                    </div>
                </form>
            </Dialog>
        );
    }
}

export default withStyles(styles)(SignupForm);

【问题讨论】:

  • 您的 SignupForm 代码是什么样的?
  • @Kosch 为我的 signup.js 添加了缩短的代表代码
  • 我是 react-admin 的新手,所以我不知道答案。但我想知道你是否可以使用授权钩子。因此,任何未经授权的人都可以获得“访客”权限,也许您可​​以使用它来显示/隐藏应用程序的某些部分。 marmelab.com/react-admin/Authorization.html
  • @geoaxis 是的,它在类似的线路上工作,我已经在我的回答中详细描述了。

标签: react-router-dom react-admin


【解决方案1】:

问题在于,应/signup 的请求,react-admin 正在调用类型为AUTH_GET_PERMISSIONSauthProvider,其代码为:

if (type === AUTH_GET_PERMISSIONS) {
    const role = localStorage.getItem('role');
    return role ? Promise.resolve(role) : Promise.reject();
}

由于用户没有登录,所以 localStorage.role 从未初始化。

改成:

if (type === AUTH_GET_PERMISSIONS) {
    const role = localStorage.getItem('role');
    return role ? Promise.resolve(role) : Promise.resolve('guest');
}

【讨论】:

  • 您能详细说明一下吗?我正在尝试实现相同的功能,但您的回答没有提供足够的信息来说明如何做到这一点
【解决方案2】:

React-admin V3 版本,修改 authProvider 默认返回 'guest' 角色:

authProvider.js

  ...,
  getPermissions: () => {
    const role = localStorage.getItem('permissions')
    return role ? Promise.resolve(role) : Promise.resolve('guest') // default 'guest'
  },
  ...

现在您的customRoutes 页面将不再重定向到/login,您可以使用usePermissions 挂钩来检查您的自定义页面中的角色。

【讨论】:

    【解决方案3】:

    您可以像这样在 customRoutes.js 文件中创建一个类似枚举的对象 PublicRoutes,其中包含所有未经身份验证的路由:

    customRoutes.js
    
    
    export const PublicRoutes = {
        SIGNUP: "/signup",
    }
    
    export const customRoutes = [
         <Route path={PublicRoutes.SIGNUP} component={SignupForm} noLayout/>
    ]
    

    然后在您的authProvider 中导入historyrouter 对象(在您的Admin 组件中创建),以访问当前位置pathname

    接下来,创建一个函数表达式isPublicRoute,它将检查当前路由是否可以在没有身份验证的情况下提供服务。 将此检查添加到 AUTH_GET_PERMISSIONS 和可选的 AUTH_CHECK 之上(如果您在此处有 JWT 解析器)。

    对于AUTH_GET_PERMISSIONS,返回Promise.resolve(),因为我们拥有公共路线的权限。对于AUTH_CHECK,请返回Promise.reject(),因为我们在这里不需要授权(例如获取或解析 JWT)。

    authProvider.js
    
    
    import {PublicRoutes} from "./customRoutes";
    
    ...
    
    const isPublicRoute = (pathname) => Object.values(PublicRoutes).some(route => route === pathname);
    
    ...
    
    const {pathname} = router.location;
    
    if (type === AUTH_GET_PERMISSIONS) {
         // has to be on top 
         if(isPublicRoute(pathname)) return Promise.resolve();
         ...
    }
    
    if (type === AUTH_CHECK) {
         // has to be on top        
         if(isPublicRoute(pathname)) return Promise.reject()
         ...
    }
    

    【讨论】:

      猜你喜欢
      • 2011-09-03
      • 2023-01-26
      • 1970-01-01
      • 2019-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-13
      • 1970-01-01
      相关资源
      最近更新 更多