Router: Documentation request: route authorization & redirects

Created on 11 Oct 2019  路  5Comments  路  Source: reach/router

Documentation Request

Can we get an example of the suggest way to implement authorization/redirecting on routes? I'm used to React Router, where you can create custom Route components to do this, but since Reach Router uses the component itself (instead of a Route component), I'm not sure what the right/suggested way is to accomplish this.

Would you create your own <AuthorizedRoute /> component like you would with React Router? Then pass your component in as a property? Then in your router you'd end up with something like this (that basically mimic's what you'd do with React Router)?

import { Home } from './home';
import { Profile } from './profile';
...
<Router>
  <Home path="/" />
  <AuthorizedRoute path="/profile" component="Profile" />
</Router>

For the record, I haven't tried this, but I'm using hooks with nested routers and it looks like that method might be problematic for those anyway.

Most helpful comment

If any of you like this syntax, I made a PR here.

const Routes = () => {
  const { user } = useAuth()
  const handlePrivateRoute = navigate => {
    if (!user) navigate('/login')
  }
  return (
    <Router onPrivateRoute={handlePrivateRoute}>
      <SettingsPage path="/settings" private />
      <LoginPage path="/login" default />
    </Router>
  );
}

All 5 comments

+1

In my projects, i use this custom Route component to provide additional context, like current_role, or meta data for SEO purpose:

import React, { FunctionComponent } from "react";
import { RouteComponentProps } from "@reach/router";
import withPageContext from "utils/hocs/withPageContext";
import withLayout from "utils/hocs/withLayout";
import withMeta from 'utils/hocs/withMeta'
import { Skeleton } from "antd";
type Props = {
  component: any;
  tags?: string[];
  page?: string;
  role?: string;
  title?: string;
  meta?: any;
} & RouteComponentProps;

const Route: FunctionComponent<Props> = ({ component, path, ...rest }) => {
  const { title = '', meta = [], role = 'anonymous' } = rest
  const Component = withMeta({ title, tags: meta })(withPageContext(withLayout(component)));
  return <Component fallback={<Skeleton />} path={path} {...rest} />;
};

export default Route;

For example usage, this is how to render the Login route component:

<Router>
<Route 
  component={Login}
   path={"/login"} 
  page="login" 
  title="Login page" 
  meta={[{ name: "description", content: "My system" }]} 
/>
</Router>

@revskill10 i see no auth checks or anything in above code. where do you apply context checks and redirect to other page , if those checks aren't successful.?

@vamshi9666 In my case, if role is anonymous it'll be treated as unauthenticated. I don't separete authenticated vs unauthenticated routes. I just provide role to routes, the rest is each route's job to render based on current provided role.

If any of you like this syntax, I made a PR here.

const Routes = () => {
  const { user } = useAuth()
  const handlePrivateRoute = navigate => {
    if (!user) navigate('/login')
  }
  return (
    <Router onPrivateRoute={handlePrivateRoute}>
      <SettingsPage path="/settings" private />
      <LoginPage path="/login" default />
    </Router>
  );
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

sseppola picture sseppola  路  4Comments

hardfist picture hardfist  路  3Comments

artoodeeto picture artoodeeto  路  4Comments

jsonmaur picture jsonmaur  路  4Comments

MarioKrstevski picture MarioKrstevski  路  3Comments