简体   繁体   中英

Login system works properly in Postman but in not in browser

Here is my router

 router.post("/login", async (req, res) => 
    {
        try
        {
            const user = await User.findByCredentials(req.body.email, req.body.password)  
            // console.log(user)
            const token = await user.generateAuthToken()
            // console.log(token)
            res.redirect("/takvim")
        }
        catch(e)
        {
            res.status(400).redirect("/")
        }
    })

Here is my user model that I use in the function above

UserSchema.methods.generateAuthToken = async function () 
{
    const user = this
    const token = jwt.sign({_id: user._id.toString()}, "secret")
    user.tokens = user.tokens.concat({token})
    await user.save()
    return token
}

UserSchema.statics.findByCredentials =  async function (emails, passwords)
{    
  const user = await User.findOne({email: emails})
  console.log(user)
  const isMatch = await bcrypt.compare(passwords, user.password)
  if(!isMatch)
  {
    throw new Error("unable to login")
  }
  return user   
}

I am making the request from frontend using a button

$uyeolForm.addEventListener("submit", () => 
{
    if(!$uyeolFormEmail.value.includes(".com"))
    {
       return $uyeolFormHata.innerHTML = "email geçersiz" 
    }
    const xhr = new XMLHttpRequest();
    let form = JSON.stringify({
    email: $uyeolFormEmail.value,
    password: $uyeolFormPassword.value
    });
    xhr.open("POST", "/login")
    xhr.setRequestHeader('Content-type', 'application/json')
    xhr.send(form);
})

Problem is when I am using the postman, application redirects me to the page i want and doesn't give an error. When I send the request with button it still finds user but it doesn't redirect me to the page I expect and in the console i see the user(expected) and null which is not expected.

Thanks to everyone.

You are making an HTTP request with XMLHttpRequest when a submit event is triggered but you aren't preventing the default behaviour of a form submission.

So the XMLHttpRequest object is created and makes a request and then immediately after (and possibly cancelling the request depending on how quickly things go) the <form> is submitted to the URL specified in the action .

You said the endpoint was being hit twice, once where you get the user you expect and ones where you don't.

When you get the user you expect it is from the XHR submission.

When you don't, that is from the regular form submission (which won't be JSON encoded as HTML forms don't support JSON encoding so it doesn't find the user because it doesn't decode the data in the form correctly).


Since you said you wanted to redirect, don't use Ajax . Ajax is a method for making an HTTP request without leaving the current page .

Change the server-side code to accept the data in the format the <form> is encoding it (probably application/x-www-form-urlencoded unless you changed it with the enctype attribute).

You want to know what's the error message, always. Add a console.error(JSON.stringify(e)) before the response, and tell us what does it say.

catch(e)
{
    console.error(JSON.stringify(e));
    res.status(400).redirect("/");
}

If You're going to use application/json and application/x-www-form-urlencoded to support both ajax and usual form submission way - You've to redirect it on frontend level by reading Location header :

$uyeolForm.addEventListener("submit", (event) => {
    event.preventDefault();

    if(!$uyeolFormEmail.value.includes(".com")) {
       return $uyeolFormHata.innerHTML = "email geçersiz" 
    }
    
    fetch('/login', {
        method: "POST",
        credentials: "include",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify({
          email: $uyeolFormEmail.value,
          password: $uyeolFormPassword.value
        })
    })
    .then(function(response) {
      if (response.redirected) {
        const redirectTo = response.headers.get('Location');
        if (redirectTo) {
          window.location.href = redirectTo;
          return;
        }
      }
    })
    .catch(function(error) {
      alert(error.message);
    });
})

keep in mind that to support both application/json and application/x-www-form-urlencoded You've to attach 2 body parsers as middleware:

const bodyParser = require('body-parser');
router.use(bodyParser.urlencoded(true));
router.use(bodyParser.json());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM