In MERN how do I manage JWT cookies client-side?

Viewed 796

Can anybody explain to me how to use cookies with the MERN stack? I'm trying to make an analog for social media. I understand first steps but then - I don't know how to proceed.

  1. I create endpoints for login, register, logout.
  2. I create react app and made register form, login form. And from there - I'm sending axios request to my express endpoints.
  3. In express - I'm saving to MongoDB user or checking login + password from DB.
  4. I'm creating a JWT token with id payload and sending it via cookie.

But what do I do next? How to save which user is logged in in the react app? And how do I check if the user is still logged in and the cookie exists? Thanks for any help!

2 Answers

I have a repo that does much of what you are trying to do. In a React component called SignInForm.js I authenticate the user using a POST request. If the authentication is successful the server sets a cookie called 'token' and the client then redirects to a component called Dashboard.js. In Dashboard.js I have, among other things, the following lines of code:

import {useCookies} from 'react-cookie'

export const AppContext = createContext()

export default function DashBoard() {

    const [cookies, setCookie, removeCookie] = useCookies(['token'])
    let [authenticated, setAuthenticated] = useState(cookies.token !== undefined)
    
    return (
        <AppContext.Provider value={{authenticated, setAuthenticated}}>
   

The above code looks for the cookie called 'token'. If it exists then it sets authenticated to true and loads it into the AppContext provider. The server API routes, of course, are protected server side. But client side I can use the value of authenticated in other components to allow or disallow access. For example in a component called UserForm.js, I check authenticated like so (some code removed for clarity):

import { AppContext } from '../DashBoard'

export default function UserForm(){
    let { authenticated, setAuthenticated} = useContext(AppContext)

    if(!authenticated){
        document.location = '/signin'
        return <></>
    }

and if they aren't authenticated then I redirect them to the SignIn.js component.

When you hit the backend route in which you are sending the token, on success the token will be automatically set in the browser. You can check by opening cookies in the Networks tab in the browser. But in order to do so you need to set the proxy.

In the frontend package.json file add:

"proxy": "http://localhost:{your-port-number}/"

Now cookie will be set automatically.

Now in order to authenticate user, you need to send this token to backend from frontend. In order to do so whenever you make a request to backend do the following(example):

axios.get('userdashboard', { withCredentials: true })

This will make sure that cookies will be used. (In this case 'userdashboard' is the route which only logged in user can access.)

Related