How to set authorization header in node js? - javascript

Hello I am working on node application in which I am working on jsonwebtokens,passport-jwt.I created application backend side and working fine on postman but I stuck on front end side. when i send token in headers in postman then token based page open on postman fine but on front side display unauthorized.How can i send token in header so that this page also open on front end side.
My code:
app.post("/login", function(req, res) {
if(req.body.name && req.body.password){
var name = req.body.name;
var password = req.body.password;
}
var user = users[_.findIndex(users, {name: name})];
if( ! user ){
res.status(401).json({message:"no such user found"});
}
if(user.password === req.body.password) {
// from now on we'll identify the user by the id and the id is the only personalized value that goes into our token
var payload = {id: user.id};
var token = jwt.sign(payload, jwtOptions.secretOrKey);
//res.json({message: "ok", token: token});
res.redirect('/secret')
} else {
res.status(401).json({message:"passwords did not match"});
}
});
app.get("/secret", passport.authenticate('jwt', { session: false }), function(req, res){
res.json("Success! You can not see this without a token");
});
Where am i doing wrong??

in your /login you can save them tokens in a sessionStorage for future use...
something like this
if(user.password === req.body.password) {
....
var payload = {id: user.id};
var token = jwt.sign(payload, jwtOptions.secretOrKey);
req.session.token = token ;
}
}
use this session to update sessionStorage on client side
here is an article that is what you need for keeping logged in post login...
also you need to destroy the cookies on Logout

if you are getting token,you can send it as:
**
let headers = new Headers({ 'Content-Type': 'application/json',
'Authorization': 'Bearer ' + this.token });
**

Related

How do I transfer a jwt token from local storage on the web browser to the server backend?

I am currently designing a simple website, where users can log in as a normal user or as an admin. Right now I am coding out the portion for when the user wants to go to an admin only web page, and the server will retrieve the jwt token stored in the local storage on the web browser to validate it.
This is what the local storage looks like
Here is the code for retrieving the jwt token
var verifyFn = {
verifyToken: function (req, res, next) {
const authHeader = localStorage.getItem("jwt_token");
console.log("THIS IS THE HEADER")
console.log(authHeader)
if (authHeader === null || authHeader === undefined ){
return res.status(401).send({ message: 'not authenticated BEARER TOKEN ISSUE' });
}
const token = authHeader
console.log("NEW TOKEN")
console.log(token)
jwt.verify(token, config.jwt.secret, { algorithms: ['HS256'] }, (err, decoded) => {
if (err) return res.status(401).send({ message: 'not authenticated' });
req.decodedToken = decoded;
console.log("DECODED TOKEN: " + req.decodedToken)
next();
});
}
However, whenever I try to run the server and browse to the admin page, there will be an error saying 'localstorage is not defined'. As such, I am not sure about how I can retrieve the jwt_token from the web browser to the server back end.
A server has no access to the browser's localStorage object, as it is accessible from the client only, and does not exist in the server context.
What is usually done is sending the token in an Authorization header. It looks like you are using Node, so consider the following example request using the fetch API on the client:
const jwtToken = localStorage.getItem('jwt_token')
fetch('your-api-url', {
method: 'request method here',
headers: {
Authorization: `Bearer ${jwtToken}`
},
body: JSON.stringify(your request body here)
}).then(response => ...)
In the server, you can then get the JWT token by looking at the request headers, something like this:
var verifyFn = {
verifyToken: function (req, res, next) {
let authHeader = req.headers['Authorization']
// the auth header will have Bearer prepended, so remove it
authHeader = authHeader.replace('Bearer ', '')
console.log("THIS IS THE HEADER")
console.log(authHeader)
if (authHeader === null || authHeader === undefined ){
return res.status(401).send({ message: 'not authenticated BEARER TOKEN ISSUE' });
}
const token = authHeader
console.log("NEW TOKEN")
console.log(token)
jwt.verify(token, config.jwt.secret, { algorithms: ['HS256'] }, (err, decoded) => {
if (err) return res.status(401).send({ message: 'not authenticated' });
req.decodedToken = decoded;
console.log("DECODED TOKEN: " + req.decodedToken)
next();
});
}

How do I make node.js using express find a JSON Web Token (JWT) inside of a response header cookie in user's browser?

I have a question on how to search for my JWT token inside of a user's browser cookies.
Below I have some code that searches the user's browser for cookies in the response header, but I am not sure how to make the code more specific and search for the JWT token within the cookie and verify that it is an actual JWT token that was a assigned to that user.
const jwt = require('jsonwebtoken');
const router = require('express')();
const cookieParser = require('cookie-parser');
router.use(cookieParser());
module.exports = function(req,res,next){
const token = req.header('Cookie');
if (!token) {
return res.status(403).send('Access Denied');
}
try{
const verified = req.header('Cookie');
req.user = verified;
// const verified = jwt.verify(token, process.env.TOKEN_SECRET);
// req.user = verified;
next();
} catch (err) {
res.clearHeader;
res.status(403).send('Invalid Token');
}
};
I hope I didn't misunderstand your question and waste a bunch time.
Short Answer: How to retrieve information
Use req.body or req.headers. If something will contain the token or authentication details, then it's one of these two.
Full Auth Walkthrough:
To get the JSON Web Tokens you first have to generate them. Wouldn't recommend implementing your own token authentication though. I'll show how to create a whole authentication system here step by step.
For simplicity, let's say we have an exported route in a file auth.js, this route will be a sub-route domain.com/auth, an array of all active refreshTokens and the jwt:
const express = require("express")
const jwt = require("jsonwebtoken")
let route = (exports.route = express())
let refreshTokens = []
What we will do is generate a long-lasting refresh token, which users will be able to use to generate a smaller 15-minute access token. Afterwards, you generate a new access token with the refresh token and so on. But to get the refresh token you need to login or register. Users can also logout killing the refresh token.
route.post("/token", async (req, res) => {
// Input: Refresh Token
// Output: Access Token Generation
})
route.post("/login", async (req, res) => {
// Input: User, Password
// Output: Refresh Token
})
route.delete("/logout", async (req, res) => {
// Input: Token to Remove
})
Let's start with the end. You have a refresh token, you won't to destroy it. Simply filter the array against this token and submit a status. The token becomes unusable after it's cleared from the array, that's the goal here.
route.delete("/logout", async (req, res) => {
refreshTokens = refreshTokens.filter((token) => token != req.body.token)
res.sendStatus(204)
})
With me so far? Now let's jump back to the start. If you log in with an email and password, if they're wrong respond with an error message, if they're correct receive the tokens.
route.post("/login", async (req, res) => {
const username = req.body.username
const password = req.body.password
// This is just a quick demonstration,
// you would have to use the bcrypt hash
// or other hash/salt methods. DO NOT
// STORE passwords plaintext
// Not existent user = Unauthorized
if (username != 'admin') return res.sendStatus(401)
// Wrong Password = Forbidden
if (password != 'abc123') return res.sendStatus(403)
const user = {
id: 0,
username: username,
password: password
}
const accessToken = generateAccessToken(user)
const refreshToken = generateRefreshToken(user)
let result = {
success: true,
accessToken: accessToken,
refreshToken: refreshToken,
}
res.send(result)
})
Now how do we sign the JSON web tokens? Let's take a look at the two methods used here:
function generateAccessToken(content) {
return jwt.sign(content, process.env.ACCESS_TOKEN_SECRET, {
expiresIn: "15m",
})
}
function generateRefreshToken(content) {
const token = jwt.sign(content, process.env.REFRESH_TOKEN_SECRET)
refreshTokens.push(token)
return token
}
Both use some sort of environment tokens, but why? That's the token you will have to generate once for the back end. It will be used as a public key. We simply generate the access tokens for 15 minutes and push the refresh tokens to the array.
route.post("/token", async (req, res) => {
const refreshToken = req.body.token
if (refreshToken == null) return res.sendStatus(401)
if (!refreshTokens.includes(refreshToken)) return res.sendStatus(403)
jwt.verify(refreshToken, process.env.REFRESH_TOKEN_SECRET, (err, user) => {
if (err) return res.sendStatus(403)
res.json({ accessToken:
generateAccessToken({
id: 0,
username: user.name,
password: user.password
})
})
})
})
We verify the refresh token, if it exists and it is valid, return a new access token for 15 minutes. That's it for the token part, you can login (create refresh token), retrieve an access token and logout (kill refresh token)
How to Use: Authenticate and Authorize
Admin pages should return 403 while the forum board should be different whether you're logging as a guest or an actual user. The first one is authentication, the second authorization.
Let's create two functions for each. Express is quite handy with the next() function
exports.authenticate = function (req, res, next) {
const authHeader = req.headers["authorization"]
const token = authHeader?.split(" ")[1]
jwt.verify(token || "", process.env.ACCESS_TOKEN_SECRET, (err, user) => {
req.user = err ? {} : user
next()
});
};
exports.authorize = function (req, res, next) {
const authHeader = req.headers["authorization"]
const token = authHeader?.split(" ")[1]
if (token == null)
return res.sendStatus(401)
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
if (err) return res.sendStatus(403)
req.user = user
next()
})
}
Now you're done with the whole authentication system (aside some cleanup's) and probably the registration system. Let's make use of it.
Client side you can create a REST api like so:
POST http://localhost:8081/auth/login
Content-Type: application/json
{
"username": "admin",
"password": "abc123"
}
# Returns refresh and access token.
###
DELETE http://localhost:8081/auth/logout
Content-Type: application/json
{
"token": "REFRESH_TOKEN"
}
# Logs out a user.
###
POST http://localhost:8081/auth/token
Content-Type: application/json
{
"token": "REFRESH_TOKEN"
}
#
# This is how you can provide the access token
# when making a request to say a forum api
#
GET http://localhost:8081/forum/api/board/0
Authorization: Bearer ACCESS_TOKEN
Usage:
route.get("forum/board/:id", authenticate, async (req, res) => {
res.send(req.user)
})
Expected Output when going to localhost:8081/forum/board/7 authenticated:
{id:0,username:"admin",password:"abc123"}
Otherwise:
{}
Nevertheless, do not try implementing your own authentication. Really, you shouldn't.
Source
https://www.youtube.com/watch?v=mbsmsi7l3r4

how to send jwt token to a middleware in a get request in express node.js

Js and web development I've tried searching the web crazy but I couldn't find a solution that could help me...
I have completed creating a project for a small lab...now I'm trying to create its login page and creating a web token using JWT...
I manage to successfully create a user and hash user password using bcrypt.... and successfully create an access token and refresh token....
I have also created a middleware that will authenticate the token
now I don't know how to send the token to that middleware
This is the authenticate token function
function authenticateToken(req, res, next)
{
try {
// header contains the token
// format
// Bearer Token
// inside autherization header
var authHeader = req.headers['authorization'];
var token = authHeader && authHeader.split(' ')[1]
if (token == null) {
// Meaning the user has not send a token.
// return res.sendStatus(401);
res.redirect('/login/');
}
// req.token = token;
// let headers = new Headers({ 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token });
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user)=>{
if (err) {
console.log("invalid token");
res.redirect('/login/');
return res.sendStatus(403);
// invalid token
}
req.user = user;
next();
});
} catch (error) {
return res.send(error.message);
}
}
I will not post all the data as its not relevant as it will populate the text area and will increase the difficulty level in understanding.... I will only share the part where I'm stuck.
this is the part where I check if the user exists and password is correct after successful authentication then I want to redirect to the dashboard page...or the main page
I cant send the access token to the route with the middleware of user authentication
router.post('/authenticate', (req,res,next)=>{
// console.log("Authenticate");
// console.log(req.body);
// console.log("Authenticate");
var email = req.body.email;
var password = req.body.password;
var sqlQuery = "select * from user where email = '"+email+"' and display = 'yes' ;;";
try {
con.query(sqlQuery,(error,result)=>{
if (!error) {
// console.log(result);
var oriPassword = result[0].PASSWORD;
var user =
{
id : result[0].ID,
name : result[0].LASTNAME,
mobileNo : result[0].MOBILENO,
};
bcrypt.compare(password, oriPassword,(err,res)=>{
if (!err) {
var accessToken = generateAccessToken(user);
var refreshToken = jwt.sign(user, process.env.REFRESH_TOKEN_SCRET);
sqlQuery = "update user set AccessToken = '"+accessToken+"' ,refreshtoken =
'"+refreshToken+"' where id = "+user.id+";";
con.query(sqlQuery,(error,result)=>{
if (!error) {
console.log("RefreshToken Inserted.");
console.log({accessToken:accessToken, refreshToken:refreshToken});
req.headers.authorization = accessToken;
} else {
console.log(error.message);
}
});
}
else {
}
});
console.log("redirecting to login user");
// console.log("Response Header");
// console.log(res.header.authorization );
res.redirect('/login/loginUser');
// res.send({accessToken:accessToken, refreshToken:refreshToken});
} else {
console.log(error.message);
}
});
} catch (error) {
console.log(error.message);
}
});
the route I want to go
router.get('/loginUser',authenticateToken,(req,res,next)=>{
// console.log(req.user);
// res.render("pages/dashboard/index");
// res.redirect("/");
res.send("Success");
console.log("Login SuccessFull..");
});
please help me I'm stuck in this form 3 days...
From what i get, you want to send some data(in this case, access token) to a certain route. You can always use query strings. Check out how it is used here.
However, I am not sure if passing around tokens in non-public api is secure.
You can parse request header to the route with the token like this.
And you can access that token in the middleware function by using this function.
function getTokenFromHeader() {
if (
(req.headers.authorization &&
req.headers.authorization.split(' ')[0] === 'Token') ||
(req.headers.authorization &&
req.headers.authorization.split(' ')[0] === 'Bearer')
) {
return req.headers.authorization.split(' ')[1];
}
return null;
}

How to set the token to local storage or cookies so that i can allow user to access certain web pages

I am trying to build an authentication system so, i used node , mysql,express for that so now i am simply saving and checking user exist in database can access but now i added JWT to it, so now i want this JWT token to store in localstorage or in cookies so, can someone guide me how can i do so
this is my authentication controller.js
var Cryptr = require('cryptr');
cryptr = new Cryptr('myTotalySecretKey');
var express = require('express');
const ap = express();
var jwt = require('jsonwebtoken');
var connection = require('./../config');
module.exports.authenticate = function (req, res) {
var email = req.body.email;
var password = req.body.password;
connection.query('SELECT * FROM users WHERE email = ?', [email], function (error, results, fields) {
if (error) {
res.json({
status: false,
message: 'there are some error with query'
});
} else {
if (results.length > 0) {
decryptedString = cryptr.decrypt(results[0].password);
if (password == decryptedString) {
jwt.sign({ email, password },
'secretkey',
{ expiresIn: '10days' },
(err, token) => {
console.log('token:' + token);
module.exports = token;
console.log(token);
res.redirect('/home.html');
}
);
} else {
res.redirect('/login.html');
console.log("Wrong Input");
}
}
else {
res.redirect('/login.html');
}
}
});
};
now i want to pass the token value to the local-storage or cookies so that i can restrict someone from acessing a page, i am reallly new to node js so any help would be appriciated
First I should notify you that do not put any secret things like password in jwt payload because the values of the payload could be accessed easily, you can try to copy paste a jwt in jwt.io site and see the payload.
set jwt in cookie like below, this will use express cookie method that does set Http Set-Cookie header:
res.cookie('jwt', generated_cookie)
.redirect('/home.html');
Also if you want to use localStorage you can set jwt in header and then in your code get the jwt from the header of login request and save it in localStorage and after that you should pass it as header in all other request, but this approach is a better solution for api calls like when you use react or vue ...
res.set({x-token: generated_token});
// In your code get
// get token from response
localStorage.setItem('token', token);
// now whenever calling api pass token as header
I show you one solution using jwt token, you choose another way:
Back-end file e.g. api.js
let jwt = require('jsonwebtoken')
let secret = 'yourSecret'; //secret key necessary to encode token
let Cryptr = require('cryptr');
let cryptr = new Cryptr('myTotalySecretKey');
module.exports = function(router,upload) {
function tokenAuth(req, res, next){
let token = req.body.token || req.body.query || req.headers['x-access-token']
if(token){
jwt.verify(token, secret, function(err,decoded){
if(err){
res.json({ authenticated: false, message:'Invalid token'})
} else {
req.decoded = decoded;
next()
}
})
} else {
res.json({success:false, message:'No token provided'});
}
}
router.post('/authenticate', function(req, res){
connection.query('SELECT * FROM users WHERE email = ?', [email], function (error, results, fields){
if(error) {
res.json({ success:false, message: err })
}
if(!results.length){
res.json({success:false, message:'User no found'})
} else if (results.length>0){
if(!req.body.password){
res.json({success:false, message:'Password was not provided'});
} else {
var validPassword = cryptr.decrypt(results[0].password);
if(validPassword === req.body.password){
res.json({success:false, message:'Incorrect password'})
} else {
var token = jwt.sign({username: results[0].username, email: results[0].email}, secret, {expiresIn: '24h'})
res.json({success:true, message:'You have logged in correctly!', token: token })
}
}
}
})
})
//If you want create a route for authenticated users for example comment posts, you can use our `tokenAuth function`
router.post('/post/comment',tokenAuth,function(req,res){
//access only for authenticated users
}
return router
}
This tokenAuth function we'll be use in paths restricted to authenticated users
server file e.g. server.js
const express = require('express');
const app = express();
const port = process.env.PORT || 80;
const http = require('http').Server(app);
const routes = require(path_to_api.js)(router);
app.use('/myApi', routes)
//***Here you should implement more details about your project such as routes, body parsers and other middlewares*****//
//Connect to your database
http.listen(port, ()=> console.log(`Server running on ${port}`))
Front-end file e.g. controller.js
function(login){
return fetch('/myApi/authenticate',{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(login)
}).then(result=>result.json()).then(data=> window.localStorage.setItem('token', data.token))
}
//`login` argument should be an object and should be like {username: 'user username', password: 'user password'}
In order to make a user store cookies, you can use the Set-Cookie header. From MDN:
Set-Cookie: <cookie-name>=<cookie-value>
In order to pass a header using Express, you can use res.set(), e.g. res.set("Set-Cookie", "Token=" + token). I also suggest you use the HttpOnly cookie directive, since it seems from your post that you don't access this token directly via Javascript and you simply want to check it when the client requests a webpage: res.set("Set-Cookie", "Token=" + token + "; HttpOnly").
The client will send the Cookie header to you when it requests a resource. You can check this header using req.header('Cookie'), and the output will be "Token=<token>" if the user is authenticated. You can then check this token for authenticity.

How to set headers for json web token in expressjs?

Hello I am working on mock authentication in nodeJs using express framework.I am using passport-jwt and jasonwebtoken for authentication. I created api and working well on postman.But I stuck on front end side I am not able to use protected api's on front end side.In postman i send token using headers and it works well.But it does not work on front end side.How to send token and verify from front end side??
My code is:
app.post("/login", function(req, res) {
if(req.body.name && req.body.password){
var name = req.body.name;
var password = req.body.password;
}
var user = users[_.findIndex(users, {name: name})];
if( ! user ){
res.status(401).json({message:"no such user found"});
}
if(user.password === req.body.password) {
var payload = {id: user.id};
var token = jwt.sign(payload, jwtOptions.secretOrKey);
res.json({message: "ok", token: token});
} else {
res.status(401).json({message:"passwords did not match"});
}
});
and if token is valid this post method should redirect to this page
app.get("/secret", passport.authenticate('jwt', { session: false }), function(req, res){
res.json("Success! You can not see this without a token");
});
npm install cookie-parser
var cookieParser = require('cookie-parser')
app.use(cookieParser())
app.use(function (req, res, next) {
var cookie = req.cookies.jwtToken;
if (!cookie) {
res.cookie('jwtToken', theJwtTokenValue,
{ maxAge: 900000, httpOnly: true });
} else {
console.log('let's check that this is a valid cookie');
// send cookie along to the validation functions...
}
next();
});

Categories

Resources