Reputation: 77
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
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
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
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