Adding custom page without authentication in react-admin












1















I want to add a signup page to my react-admin web portal. Since react-admin do not provide a signup page, I created a custom page and added it to custom routes:



customRoutes.js



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

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


The problem is that I am only able to open the page at /signup when a user is already signed in. Otherwise I am automatically redirected to /login route.



How to disable authentication for custom routes? Is there some attribute which <Route> accepts or something to do with the dataProvider.js?



EDIT:



Adding the representative code for my 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);









share|improve this question

























  • What does your code for SignupForm look like?

    – Kosch
    Nov 26 '18 at 23:51











  • @Kosch added shortened representative code for my signup.js

    – arpanmangal
    Nov 27 '18 at 15:15











  • I am new to react-admin so I don't know the answer. But I wonder if you can use the authorization hooks. So any one who is not authorized can get the "guest" permission, and perhaps you can use that to show/hide parts of your app. marmelab.com/react-admin/Authorization.html

    – geoaxis
    Dec 2 '18 at 11:09











  • @geoaxis yes it worked on similar lines, I have described in detail in my answer.

    – arpanmangal
    Dec 5 '18 at 16:48
















1















I want to add a signup page to my react-admin web portal. Since react-admin do not provide a signup page, I created a custom page and added it to custom routes:



customRoutes.js



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

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


The problem is that I am only able to open the page at /signup when a user is already signed in. Otherwise I am automatically redirected to /login route.



How to disable authentication for custom routes? Is there some attribute which <Route> accepts or something to do with the dataProvider.js?



EDIT:



Adding the representative code for my 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);









share|improve this question

























  • What does your code for SignupForm look like?

    – Kosch
    Nov 26 '18 at 23:51











  • @Kosch added shortened representative code for my signup.js

    – arpanmangal
    Nov 27 '18 at 15:15











  • I am new to react-admin so I don't know the answer. But I wonder if you can use the authorization hooks. So any one who is not authorized can get the "guest" permission, and perhaps you can use that to show/hide parts of your app. marmelab.com/react-admin/Authorization.html

    – geoaxis
    Dec 2 '18 at 11:09











  • @geoaxis yes it worked on similar lines, I have described in detail in my answer.

    – arpanmangal
    Dec 5 '18 at 16:48














1












1








1


1






I want to add a signup page to my react-admin web portal. Since react-admin do not provide a signup page, I created a custom page and added it to custom routes:



customRoutes.js



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

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


The problem is that I am only able to open the page at /signup when a user is already signed in. Otherwise I am automatically redirected to /login route.



How to disable authentication for custom routes? Is there some attribute which <Route> accepts or something to do with the dataProvider.js?



EDIT:



Adding the representative code for my 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);









share|improve this question
















I want to add a signup page to my react-admin web portal. Since react-admin do not provide a signup page, I created a custom page and added it to custom routes:



customRoutes.js



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

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


The problem is that I am only able to open the page at /signup when a user is already signed in. Otherwise I am automatically redirected to /login route.



How to disable authentication for custom routes? Is there some attribute which <Route> accepts or something to do with the dataProvider.js?



EDIT:



Adding the representative code for my 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);






react-router-dom react-admin






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 29 '18 at 7:24







arpanmangal

















asked Nov 25 '18 at 18:09









arpanmangalarpanmangal

6761722




6761722













  • What does your code for SignupForm look like?

    – Kosch
    Nov 26 '18 at 23:51











  • @Kosch added shortened representative code for my signup.js

    – arpanmangal
    Nov 27 '18 at 15:15











  • I am new to react-admin so I don't know the answer. But I wonder if you can use the authorization hooks. So any one who is not authorized can get the "guest" permission, and perhaps you can use that to show/hide parts of your app. marmelab.com/react-admin/Authorization.html

    – geoaxis
    Dec 2 '18 at 11:09











  • @geoaxis yes it worked on similar lines, I have described in detail in my answer.

    – arpanmangal
    Dec 5 '18 at 16:48



















  • What does your code for SignupForm look like?

    – Kosch
    Nov 26 '18 at 23:51











  • @Kosch added shortened representative code for my signup.js

    – arpanmangal
    Nov 27 '18 at 15:15











  • I am new to react-admin so I don't know the answer. But I wonder if you can use the authorization hooks. So any one who is not authorized can get the "guest" permission, and perhaps you can use that to show/hide parts of your app. marmelab.com/react-admin/Authorization.html

    – geoaxis
    Dec 2 '18 at 11:09











  • @geoaxis yes it worked on similar lines, I have described in detail in my answer.

    – arpanmangal
    Dec 5 '18 at 16:48

















What does your code for SignupForm look like?

– Kosch
Nov 26 '18 at 23:51





What does your code for SignupForm look like?

– Kosch
Nov 26 '18 at 23:51













@Kosch added shortened representative code for my signup.js

– arpanmangal
Nov 27 '18 at 15:15





@Kosch added shortened representative code for my signup.js

– arpanmangal
Nov 27 '18 at 15:15













I am new to react-admin so I don't know the answer. But I wonder if you can use the authorization hooks. So any one who is not authorized can get the "guest" permission, and perhaps you can use that to show/hide parts of your app. marmelab.com/react-admin/Authorization.html

– geoaxis
Dec 2 '18 at 11:09





I am new to react-admin so I don't know the answer. But I wonder if you can use the authorization hooks. So any one who is not authorized can get the "guest" permission, and perhaps you can use that to show/hide parts of your app. marmelab.com/react-admin/Authorization.html

– geoaxis
Dec 2 '18 at 11:09













@geoaxis yes it worked on similar lines, I have described in detail in my answer.

– arpanmangal
Dec 5 '18 at 16:48





@geoaxis yes it worked on similar lines, I have described in detail in my answer.

– arpanmangal
Dec 5 '18 at 16:48












1 Answer
1






active

oldest

votes


















0














The problem was that on request to /signup, react-admin was calling the authProvider with type AUTH_GET_PERMISSIONS whose code was:



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


Since the user was not logged in so localStorage.role was never initialised.



Changed it to:



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





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53470403%2fadding-custom-page-without-authentication-in-react-admin%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    The problem was that on request to /signup, react-admin was calling the authProvider with type AUTH_GET_PERMISSIONS whose code was:



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


    Since the user was not logged in so localStorage.role was never initialised.



    Changed it to:



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





    share|improve this answer




























      0














      The problem was that on request to /signup, react-admin was calling the authProvider with type AUTH_GET_PERMISSIONS whose code was:



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


      Since the user was not logged in so localStorage.role was never initialised.



      Changed it to:



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





      share|improve this answer


























        0












        0








        0







        The problem was that on request to /signup, react-admin was calling the authProvider with type AUTH_GET_PERMISSIONS whose code was:



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


        Since the user was not logged in so localStorage.role was never initialised.



        Changed it to:



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





        share|improve this answer













        The problem was that on request to /signup, react-admin was calling the authProvider with type AUTH_GET_PERMISSIONS whose code was:



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


        Since the user was not logged in so localStorage.role was never initialised.



        Changed it to:



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






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 5 '18 at 16:47









        arpanmangalarpanmangal

        6761722




        6761722






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53470403%2fadding-custom-page-without-authentication-in-react-admin%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

            Calculate evaluation metrics using cross_val_predict sklearn

            Insert data from modal to MySQL (multiple modal on website)