Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to conditionally add routes in React.JS?

I have a login system with Firebase and I want to dynamically add routes if someone enters correct information, I want it to add the main route and the add route.

var userToken = 'firebase:authUser:AIzaSyDfC9LqfL1rbClhfCOD04BKC9ZIn7UAZ_g:[DEFAULT]';

ReactDOM.render(
    <Router history={hashHistory}>
        <Route path="/" component={Login} />
        <Route path="signup" component={Signup} />
         { localStorage.getItem(userToken) ? (
            <Route path="main" component={Main} />
          ) : (<Redirect from="main" to="/" />)
        }
        { localStorage.getItem(userToken) ? (
            <Route path="add" component={Add} />
          ) : null
        }  
        <Route path="main" component={Main} />
        <Route path="*" component={NotFound} />
    </Router>
    , document.getElementById('container'));

The code above is working fine, but it has a flaw when someone types the correct information, they have to reload the page and enter the information again to log in.

Is there any way around where they don't have to reload the page after successful authentication?

like image 291
Osama Xäwãñz Avatar asked Dec 19 '22 11:12

Osama Xäwãñz


2 Answers

I'd suggest creating components SecureMain and SecureAdd and updating the routes to use those instead. These would check for the existence of the user token and render either the desired content, or your NotFound component otherwise. For example (note that I banged this out as a concept and it may not be perfect):

import React from 'react';
import Main from './Main';
import NotFound from './NotFound';

export default class SecureMain extends React.Component {
  constructor(...args) {
    super(...args);
    this.state = { token: localStorage.getItem(userToken) };
  }
  render() {
    if (this.state.token) return <Main {...this.props} />;
    else return <NotFound {...this.props} />;
  }
}

This makes the state of your application much easier to predict based on its state.

Of course I also have to echo @ZekeDroid's disclaimer about client-side "security":

client-side security IRL

like image 102
Ryan Kennedy Avatar answered Dec 28 '22 08:12

Ryan Kennedy


That's an interesting approach at authentication. Very interesting. My suggestion is for you to add Redux or straight up to wrap your Router in a parent component. This way, when the user triggers what I assume is some onChange handler, it should update that parent's state rather than localStorage only. At that point, that parent will re-render its children (in your case, the Router) hence generating new Routes!

Disclaimer: it's still easy to get around this authentication since anyone can go to the source and change the line to read { true ? <Route path="add" component={Add} /> : null }, but still, kinda cool approach.

like image 32
ZekeDroid Avatar answered Dec 28 '22 08:12

ZekeDroid