1

I have 2 routes that each one is for a type of user, how do I do it differently, I already have my auth, but I don't know how to do that. If anyone knows or has seen any documentation on this just put it below, I'm finding this all day

import React, { createContext, useState, useEffect } from 'react'
import { useNavigate } from "react-router-dom";
import axios from '../services/api';

export const AuthContext = createContext()

export const AuthProvider = ({ children }) => {
  const navigate = useNavigate();
  const [user, setUser] = useState()
  const [loading, setLoading] = useState(true)
  useEffect(() => {
    const recoveredUser = localStorage.getItem('user')
    if (recoveredUser) {
      const jsonUser = JSON.parse(recoveredUser)
      axios.defaults.headers.common['Authorization'] = `Bearer ${jsonUser.token}`;
      setUser(jsonUser)
      navigate('/user')
    }
    setLoading(false)
  }, [])
  const login = (data) => {
    if (data) {
      localStorage.setItem('user', JSON.stringify(data))
      setUser(data)
      navigate('/user')
    }
  }
  const logout = () => {
    localStorage.removeItem('user')
    setUser("")
    navigate('/login')
  }
  return (
    <AuthContext.Provider value={{ authenticated: !!user, user, loading, login, logout }}>
      {children}
    </AuthContext.Provider>
  )
}
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
Gustavo Henrique
  • 498
  • 1
  • 4
  • 6
  • Where are you referencing any roles for any specific routes? Please include all relevant code in your question. https://stackoverflow.com/help/minimal-reproducible-example – Drew Reese Feb 16 '22 at 21:49

1 Answers1

2

Kent C Dodds has a really good article about this and its what I follow in my apps. https://kentcdodds.com/blog/authentication-in-react-applications

Because you have your user in your context you can just check that where your routes get rendered.

import { Routes } from 'react-router-dom'
import { useAuth } from './context/auth'

function App() {
  const { user } = useAuth();
  return user ? <AuthenticatedApp /> : <UnauthenticatedApp />
}

function AuthenticatedApp () {
 return (
  <Routes>
    // all your authenticated routes
  </Routes>
 )
}

function UnauthenticatedApp () {
 return (
  <Routes>
    // all your un authenticated routes
  </Routes>
 )
}

In my example I created a useAuth() hook which you would have to do in your file.

function useAuth() {
  const context = useContext(AuthContext);
  return context;
}

export { useAuth };
Richard Hpa
  • 2,353
  • 14
  • 23
  • This pattern doesn't lead to very **DRY** code, in fact, this is quite **WET** (*Write Everything Twice*). What if you want to render both authenticated and unauthenticated routes at the same time? I think you've misunderstood Kent's design pattern, it's meant for presenting an entire UI depending on authentication, not restricting specific routes. – Drew Reese Feb 16 '22 at 21:51
  • That is true so you would then have to include the `useAuth` constantly throughout the app, or create a `AuthenticatedRoute` component. I personally don't mind having the route for `/home` in both places as I then know all of the routes that an authenticated and unauthenticated user have access to. – Richard Hpa Feb 16 '22 at 21:59