0

I have been trying to create a checkAuth function all day, backend is creating a token and saving it in mongodb, when someone logs in the token gets overwritten to a new token, so only one session can be logged in at a time. However, my checkAuth function always returns true.

CheckAuth.js

import React from "react"
import axios from "axios"
    const checkAuth = async () => {
        const userInfo = localStorage.getItem("userInfo");
        const info = JSON.parse(userInfo);
        const email = info.email;
        const origintoken = info.token;
        console.log("origin");
        try {
            const config = {
            headers: {
                "Content-type": "application/json"
            }
            }
            const { data } = await axios.post (
            "/api/users/token",
            {email},
            config
            );
            const token = data.token;
            console.log("origin");
            if (origintoken === token) {
                console.log("origin");
                return true;
            }
            else {
                console.log("else");
                return false;
            }
            
        } catch (error) {
            console.log("error");
            return false;
        }
    }

export default checkAuth

LandingPage.js

import React from "react"
import AuthCheck from "./CheckAuth.js"
import { useEffect } from "react"
import {Redirect} from "react-router-dom"
import { useState} from "react"
import checkAuth from "./CheckAuth.js"

export default function LandingPage() {
    const [redirect, setRedirect] = useState(false);
    
    useEffect(() => {
    
        if(!checkAuth()) {
        setRedirect(true);
        console.log("false");
        }}, [])

        if (redirect) {
            <Redirect to="/"/>
        }
            return (
                <div>
                    <h1>whatsup</h1>
                </div>
            )
}

Serverside:

const checkToken = asyncHandler(async (req, res) => {
    const email = req.body;
    const user = await User.findOne(email)
    if (user) {
        res.json({
            token: user.token,
        });
    } else {
        res.status(400)
        throw new Error("Niet ingelogd.")
    }
});
Nikola Pavicevic
  • 21,952
  • 9
  • 25
  • 46
SuchJitter
  • 47
  • 1
  • 3

2 Answers2

2

As checkAuth is an async function, it always returns a promise which resolves to the value that you return in try block, or rejects with the value that you return in the catch block.

resolves to either true or false:

  if (origintoken === token) {
            console.log("origin");
            return true;
        }
        else {
            console.log("else");
            return false;
        }

rejects with false:

catch (error) {
        console.log("error");
        return false;
    }

So you can't test its return value like a normal function. instead:

     useEffect(async () => {
let authResult=await checkAuth();
    if (!authResult) { // first correction
      setRedirect(true);
    }
  }, [])

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function#description

Erfan
  • 1,725
  • 1
  • 4
  • 12
0

The component should probably look something like this:

import React from "react"
import AuthCheck from "./CheckAuth.js"
import { useEffect } from "react"
import { Redirect } from "react-router-dom"
import { useState } from "react"
import checkAuth from "./CheckAuth.js"

export default function LandingPage() {
  const [redirect, setRedirect] = useState(false);
  useEffect(() => {
    if (!checkAuth()) { // first correction, call the function
      setRedirect(true);
    }
  }, [])
  if (redirect) {
    return <Redirect to="/"/> // second correction, missing return
  }
  return (
    <div>
      <h1>whatsup</h1>
    </div>
   )
}

You can also do this in the useEffect:

useEffect(() => {
  setRedirect(!checkAuth())
}, [])

Update: As suggested in an answer by Erfan Naghashlou, checkAuth is async function so that useEffect should be modified as:

useEffect(() => {
  const x = async () => { 
    const checkAuthResult = await checkAuth()
    setRedirect(!checkAuthResult)
  }
  x()
}, [])

Look at how to handle async await in useEffect

Akshay Kumar
  • 875
  • 13
  • 29
  • 1
    Thank you for your reaction, I have changed it and let the AuthCheck always return false for every condition. However, setRedirect always stay false, logging to console in the condition never works. – SuchJitter Aug 27 '21 at 18:37