Search code examples
node.jsreactjsauthenticationtokenuse-state

page does not redirect after setting token with localstorage


I am following the tutorial below to create a token system for my login application.

https://www.digitalocean.com/community/tutorials/how-to-add-login-authentication-to-react-applications

Here is my code:

App.js:

import logo from './logo.svg';
import './App.css';
import "bootstrap/dist/css/bootstrap.min.css";
import useToken from './components/useToken';
import Navbar from './components/Navbar';
import AudioDropzone from './components/AudioDropzone';

import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  useLocation
} from "react-router-dom";

import Upload from './pages/Upload';
import Manage from './pages/Manage';
import Menu from './pages/Menu';
import Admin from './pages/Admin';
import Login from './pages/Login';

import { useEffect, useState } from 'react';

<script src="https://unpkg.com/boxicons@latest/dist/boxicons.js"></script>

function App() {

  const { token, setToken } = useToken();
  console.log(token)
  if(!token) {
    return(
      <div className="App">
        <div className="row">
          <div class="col-2">
          </div>
          <div class="col-9">
            <Login setToken={setToken} />
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="App">
      <Router>
        <head>
          <link rel="stylesheet" href="boxicons.min.css" />
        </head>
        <div className="row" >
          <div class="col-2">
          </div>
          <div class="col-9">
            <Switch>
              <Route path="/upload">
                <Upload customer_id={token}/>
              </Route>
              <Route path="/manage">
                <Manage customer_id={token} />
              </Route>
              <Route path="/menu">
                <Menu customer_id={token} />
              </Route>
              <Route path="/admin">
                <Admin />
              </Route>
              <Route path="/admin/upload">
                <Upload />
              </Route>
              <Route path="/admin/manage">
                <Manage />
              </Route>
              <Route path="/admin/menu">
                <Menu />
              </Route>
            </Switch>
          </div>
        </div>

      </Router>
    </div>
  );
}

export default App;

useToken.js:

import { useState } from 'react';

export default function useToken() {
  const getToken = () => {
    const tokenString = localStorage.getItem('token');
    const userToken = JSON.parse(tokenString);
    return userToken?.token
  };

  const [token, setToken] = useState(getToken());

  const saveToken = userToken => {
    localStorage.setItem('token', JSON.stringify(userToken));
    setToken(userToken.token);
  };
  
  return {
    setToken: saveToken,
    token
  }
}

Currently, when login is successful, it just clears the fields and shows the same login page again without showing the second version of App with all of my content. The issue is that the token value is not being updated and populated. I have verified that upon logging in token is updated to an integer value like 13.

This is seen when I log the value of userToken in useToken.js:

  const saveToken = userToken => { 
    console.log(userToken) //returns 13
    localStorage.setItem('token', JSON.stringify(userToken));
    setToken(userToken.token);
  };

Let me know what I am doing wrong!


Solution

  • I believe the bug is in the saveToken function.

    setToken(userToken.token); should be setToken(userToken);

    You don't need the .token because userToken is not an object. It is just an integer value.