Alpha
Alpha

Reputation: 77

How to pass token to verify user across html pages using node js

I am trying to pass a token that verifies which user is logged in across html pages. Once the user logs in a token is created which contains the user _Id. I want to use that information to get the users name and display it across html pages.

/api/user/login

router.post('/login', async (req, res) => {
    //Validate befor use
    const { error } = loginValidation(req.body);
    if (error) return res.status(400).send(error.details[0].message);

    const user = await User.findOne({ email: req.body.email });
    if (!user) return res.status(400).send('Email is not found');

    const validPass = await bcrypt.compare(req.body.password, user.password);
    if (!validPass) return res.status(400).send('Invalid pasword');

    //Create and assign a token
    const token = jwt.sign({ _id: user._id }, process.env.Token_SECRET);
    res.header('auth-token', token);
    if (!error) res.redirect('/public/index.html');
});

The problem I am having is once I res.redirect back to the index, I lose the token. I want to be able to pass the token across other html pages.

I have thought of a some ways of solving this but the only way I could think of was creating another routes file so that I could use

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

But this brings be back to the same problem that I cant pass the token to other html pages.

Upvotes: 0

Views: 1348

Answers (3)

user12716323
user12716323

Reputation:

Why don't you attach the token to the Redirect Url? JWT usually has a limited lifetime. Someone who can access your token at some later time won't be able to use it.

Upvotes: 0

Marcus Castanho
Marcus Castanho

Reputation: 143

I assume you have control of the front-end application as well, if so, I believe one way is to require the token for each request the API gets that classifies as "session logged in page", for example: get info from API, delete account...

For that, once you send in the res the token, every time the api gets a "must be logged in" request you could add a middleware used in all requests that require the token, something like this:

    const jwt = require('jsonwebtoken');
    const authConfig = require('./auth.json');// defining a SecretKey for the authtoken
    
    
    module.exports = (req, res, next) => {
    const authHeader = req.headers.authorization;

    if (!authHeader) {
        return res.status(401).send({ error: 'No token provided' });
    }

    jwt.verify(token, authConfig.secret, (err, decoded) => { // here you verify the authtoken = key + token
        if (err) {
            return res.status(401).send({ error: 'Token invalid' });
        }
        return next();
    });
}

As for the front-end, you will have to save locally the token provided, possibly on safe cookies, as showed in MDN documents here, like this:

document.cookie='authToken=[token]'// where token is the value saved as a string

And the next time the client proceeds with a request to a logged in page you send the token saved as a cookie in a authorization header, for example:

    myGETRequest = () => {
        const authToken = document.cookie.split('; ').find(row => row.startsWith('authToken'))
  .split('=')[1]; //all cookies are saved together in one string

        fetch(`http://yourURL`, {
            "method": "GET",
            "headers": {
                "authorization": authToken, 
                "Content-Type": "application/json"
            },
        })
            .then(res => {
                res.json().then(res => console.log(res))
            })
            .catch(err => {
                console.log(err)
            })
    }

For more info, you can check the W3schools docs about cookies here or MDN docs here

Upvotes: 1

turbopasi
turbopasi

Reputation: 3625

One very common solution is to keep a token client side after the user logged in. To keep it client-side across 1 origin you can use localStorage.


localStorage.setItem('token', 'xxxxxxaaaaaaannnnnnnnccccc.asdaasdasdasdasd');
const token = localStorage.getItem('token');

In your login route you will obviously have to return the data, not redirect. So return the token to the user, and after the user gets the token, store it in localStorage and then you can do a redirect also on the client side.

// server
// after successful token create
res.status(200).json({ token : token });
// client
// similar behavior as an HTTP redirect
window.location.replace("http://stackoverflow.com");

// similar behavior as clicking on a link
window.location.href = "http://stackoverflow.com";

If the new page is within the same origin, the localStorage you set is still available.

Upvotes: 1

Related Questions