Chen
Chen

Reputation: 291

why is this redirecting me even if the user is not in the database?

I'm trying to build a login verification form with a mongoDB database. And whenever the user logs in with the correct details he should be redirected to the homepage and if it is wrong, he should stay in the same page. Everything works fine with storing the user and veryfing it from server side. But whenever I try to log the user in even if the user is incorrect it still redirects me.

Here is the login form:

import React, {useState} from 'react'
import './login.css'
import axios from 'axios'
import { useHistory } from "react-router-dom";


function Login() {
    const [username, setUsername] = useState("")
    const [password, setPassword] = useState("")
    const [data, setData] = useState(null)

    const history = useHistory()


    const onChangeUsername = (e) => {
      setUsername(e.target.value)
    }

    const onChangePassword = (e) => {
      setPassword(e.target.value)
    }

    const onSubmit = (e) => {
      e.preventDefault()

      const users = {
        username: username,
        password: password
      }
      axios.post('http://localhost:4000/users/login', users)
      .then(res => console.log(res.data))
    }

    const loginUser = () => {
      axios.get("http://localhost:4000/users/user", {
        withCredentials: true
      }).then(res => {
        setData(res)
        if(res.status === 200) return history.push("/home")
        else return history.push("/login")
      })
    }
    console.log(data)

    return (
        <div>
          <img src="https://www.freepnglogos.com/uploads/twitter-logo-png/twitter-logo-vector-png-clipart-1.png" className="twitterlogo____image"/>
          <h1 className="login_____headertext">Log in to Twitter</h1>
          <div className="placeholder_____global">
          <form onSubmit={onSubmit}>
            <input className="placeholder____div" placeholder="Phone, email or username" onChange={onChangeUsername}/>
            <div>
              <input className="placeholder____div" placeholder="Password" type="password" onChange={onChangePassword}/>
            </div>
            <div>
              <button className="twitter___loginbuttonpage" onClick={loginUser}>Log in</button>
            </div>
            </form>
            <div className="forgetPassword_____div">
              <p>Forgot password?</p>
              <p>·</p>
              <p>Sign up for Twitter</p>
            </div>
          </div>
        </div>
    )
}

export default Login

server side passport authentication:

const express = require('express');
const router = express.Router();

const Users = require('../models/users.model.js')
const passport = require("passport")

require('../authentication/passportConfig.js')(passport)


router.route('/').get((req, res) => {
  Users.find()
    .then(users => res.json(users))
    .catch(err => res.status(400).json('Error:' + err))
})

router.route('/user').get((req, res) => {
  res.send(req.user)
})

router.route('/login').post((req, res, next) => {
  passport.authenticate("local" , (err, user, info) => {
    if (err) throw err;
    if (!user) res.send("No user exists")
    else {
      req.logIn(user, err => {
        if (err) throw error;
        res.send("Succesfully Authenticated")
      })
    }
  })(req, res, next)
})

router.route('/add').post(async(req,res) => {
  const hashedPassword = await bcrypt.hash(req.body.password, 10)
  const username = req.body.username
  const password = hashedPassword
  const email = req.body.email
  const phone = req.body.phone
  const monthOfBirth = req.body.monthOfBirth
  const dayOfBirth = req.body.dayOfBirth
  const yearOfBirth = req.body.yearOfBirth

  const newUsers = new Users({
    username,
    password,
    email,
    phone,
    monthOfBirth,
    dayOfBirth,
    yearOfBirth
  })

  newUsers.save()
  .then (() => res.json("User Added"))
  .catch(err => res.status(400).json('error' + err))
})



module.exports = router

Upvotes: 0

Views: 41

Answers (1)

Abhishek Agarwal
Abhishek Agarwal

Reputation: 371

Whenever you click on the Login button, it executes two methods:

  • loginUser(): Because it is being called via onClick attribute of the button
  • onSubmit(): Because it is being called on form's submission via onSubmit

Now let's talk about the server-side of things. The loginUser method on client-side calls the /user endpoint which always returns a 200 status code because all it does is send back a user from the request via res.send(req.user), while onSubmit method on client-side actually triggers authentication through the /login endpoint.

On the client side, the implementation of loginUser method checks for the status 200 of the response via:

if(res.status === 200) return history.push("/home")
    else return history.push("/login")

In this scenario, since /user endpoint that loginUser calls will always simply send the response back via res.send(req.user), it is bound to always have status equals to 200, hence, the if-else expression on the client-side will never execute the else part of it, and continue to redirect to /home, irrespective of the correctness of the credentials.

Solution

A better approach IMO would be to avoid executing 2 methods on clicking of Login button, and only have onSubmit method executed on form submission on the client-side, letting it trigger /login endpoint to handle the authentication and then according to the API's response, managing redirection to /login page or /home page.

Upvotes: 1

Related Questions