Link to home
Start Free TrialLog in
Avatar of Seham Hammad
Seham Hammad

asked on

JWT with nodejs

Hello
I am trying to authenticate my API calls using JWT with nodejs and javascript using qeuelize and mysql . I was able to get the token and send it in the headers using postman, but if i want to send it from the html form once the user sign in and then the token will be send or go through to authenticate the user. how will I store the token so the user can send it with the middle ware to be reauthorized to access the index page.
signin function:

exports.signIn = (req, res) => {
	console.log("Sign-In");
	console.log(req.body.username);

	User.findOne({

		where: {
            username: req.body.username,
		}
	}).then(user => {
	    console.log(user.password);
		if (!user) {
			return res.status(404).send('User Not Found.');
		}
        let passwordIsValid = bcrypt.compareSync(req.body.password, user.password);
        if (!passwordIsValid) {
			return res.status(401).send({ auth: false, accessToken: null, reason: "Invalid Password!" });
		}

        const token = jwt.sign({id: user.id}, config.secret, {
            expiresIn: 86400 // expires in 24 hours
        });


       // res.status(200).send({ auth: true, accessToken: token });
       res.sendFile(path.resolve(__dirname,'../public/index.html'));


    }).catch(err => {
		res.status(500).send('Error -> ' + err);
	});
};
/************************************** verifyToken function****************/
verifyToken = (req, res,next) => {
  const token = req.headers ['x-access-token'] || req.headers['authorization'];
    if(!token){
      return res.status(403).send({
        auth: false, message: 'No token provided'   
      });
  }
  jwt.verify(token, config.secret, (err, decoded) =>{
      if (err){
           return res.status(500).send({
               auth: false,
               message: 'Fail to Authenticate token' + err
           });
      }
      req.userId = decoded.id;
      next();
  });
};

Open in new window

Avatar of David Favor
David Favor
Flag of United States of America image

Normally this is done using HTTPS (so no one can snoop data), then using a combination of nonces + Apache headers or in your case NodeJS.

My suggestion is you look at the entire plumbing of how WordPress handles this.

A bit complex to get exactly right.

And HTTPS wrapping is first step, as it will do you no good to get all this working if your transactions are plain text + all your authentication tokens can be scraped off the wire.
Tip: Also, do incremental debugging.

For example, first step will be to embed a user/pass you know into your code + then verify your entire API call flow works using curl.

Then add in your user/pass MySQL database.

Then add in other layers of code... one by one... testing/verifying each work... incrementally...
Avatar of Seham Hammad
Seham Hammad

ASKER

Thanks
Are you asking how to send your token from the client or receive it in Node?

The question seems to be about the client but your code is Node

This part is not clear
but if i want to send it from the html form once the user sign in and then the token will be send or go through to authenticate the user. how will I store the token so the user can send it with the middle ware to be reauthorized to access the index page.
at the moment I got a javascript side in my sign in html that the user enters username and password to get the token, I have stored the token in localStorage but i cant send it with the request and i get forbidden if i want to access another web page using the token that i got.
function SignIn() {

        let username = $("#username").val();
        console.log(username);
        let password = $("#password").val();

        $.ajax({
            url: "http://localhost:2002/signIn",
            type: 'POST',
            dataType: "json",
            data: {username, password},
            headers: {
                'Authorization': 'Basic' + btoa(username + '+' + password)
            },
            success: function (data, status) {
                console.log(data);
                localStorage.setItem('Id_token', data.accessToken);
                let headers = new Headers();
                let token = localStorage.getItem('Id_token');
                // headers: {"Authorization": 'Bearer ' + token},
                headers.append('Authorization', 'Bearer ' + token);
                //window.location.href = "http://localhost:2002/admin";

            }
        }),
            $.ajax({
                type: 'GET',
                url: "http://localhost:2002/admin",  //the url to call
                dataType: 'json',
                headers: {
                    'Authorization': 'Basic' + btoa(username + '+' + password)
                },
                success: function (data, status) {
                    console.log(data);
                }
            })
    }
</script>
I can not access the admin page it says forbidden or the token is not sent.
When you sign in - you get a JWT token back which you store in localStorage - correct?

This is the token you must use to authenticate subsequent requests to your server. In your example you keep sending your username and password which is incorrect.

The JWT token must be passed in the Authorization header as
Authorization: Bearer token

Open in new window


$.ajaxSetup({
    beforeSend: function (xhr)
    {
       // GET FROM localStorage
       var token =   localStorage.getItem('Id_token');

        // ADD AUTHORIZATION HEADER WITH TOKEN
       xhr.setRequestHeader("Authorization","Bearer " + token);        
    }
});

Open in new window


Also take some time to read about localStorage and security issues - and why cookies might be an alternative option.
Hi Julian,
Will try that , thanks very much for your reply
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.