Basic auth in node js - node.js

I am writing a post request with basic auth in node js.I am trying to hit API without authorization field in header, still I am not getting any error.
subscriptionRouter.route('/subscriptions')
.post((req, res) => {
//console.log(JSON.stringify(req.body));
if (!req.headers.authorization || req.headers.authorization.indexOf('Basic ') === -1) {
res.status(401).json({ message: 'Missing Authorization Header' });
}
const base64Credentials = req.headers.authorization.split(' ')[1];
const credentials = Buffer.from(base64Credentials, 'base64').toString('ascii');
if(credentials == 'GsubNode:WelcomeNode#123'){
console.log(req.body);
var msgId = putMessageSync(req.body);
let responseJSON = {};
if (msgId == "") {
responseJSON.statusCode = 400;
responseJSON.statusDesc = "Bad Request";
responseJSON.msgId = msgId;
}
else {
responseJSON.statusCode = 200;
responseJSON.statusDesc = "Posted";
responseJSON.MsgId = msgId;
}
res.json(responseJSON);
}
else{
res.status(401).json({ message: 'Invalid Authentication Credentials' });
}
})

You may want to use a middleware, first declare the function:
function authenticate(req, res, next){
const authHeader = req.headers['authorization'];
const base64Credentials = authHeader && authHeader.split(' ')[1];
if( base64Credentials == null ) return res.sendStatus(401)
if(credentials == 'GsubNode:WelcomeNode#123'){
next()
}
}
Then you'd specify the middleware for each path you'd like to authenticate and run the rest of your code for the api call (using express) like:
express.post('/subscriptions', authenticate, (req, res) => {
console.log(req.body);
var msgId = putMessageSync(req.body);
let responseJSON = {};
if (msgId == "") {
responseJSON.statusCode = 400;
responseJSON.statusDesc = "Bad Request";
responseJSON.msgId = msgId;
}
else {
responseJSON.statusCode = 200;
responseJSON.statusDesc = "Posted";
responseJSON.MsgId = msgId;
}
res.json(responseJSON);
});
EDIT: The answer to this post elaborates on routers and middleware: setting up a middleware in router.route() in nodejs (express)

Related

Error received on token expiration despite of not being outdated in node js app

Good day developers, recently as been working in this node js app, and when implementing jwt library i got an error related to tghe verify() method in this jwt repo.
Kind of :
return secretCallback(null, secretOrPublicKey);
^
TokenExpiredError: jwt expired
The repo is structured in several folders:
controllers
middlewares
helpers
socket controllers
On my middleware folder, sepecifically in a file related to jwt validation i settled this:
file middleware jwt-validation
export {};
const { request, response } = require("express");
const User = require("../models/user-model");
const jwt = require("jsonwebtoken");
const jwtValidator = async (req = request, res = response, next) => {
const token_response = req.header("token-response");
if (!token_response) {
return res.status(401).json({
message: "Not valid token .You don't have authorization",
});
}
try {
const payload = await jwt.verify(token_response, process.env.SECRETKEYJWT)
const userAuth = await User.findById(payload.id);
if (userAuth.userState != true) {
return res.status(401).json({
message: "User inhabilitated",
});
}
if (!userAuth) {
return res.status(404).json({
message: "User not found",
});
}
req.user = userAuth;
next();
} catch (error) {
return res.status(500).json({
message: "Not valid token.Error 500",
});
}
};
module.exports = { jwtValidator };
file middleware jwt-validation-sockets
import { UserSchema } from "../interfaces";
const jwt = require("jsonwebtoken");
const User = require("../models/user-model");
const jwtValidatorRenew = async (
token: string = ""
): Promise<UserSchema | null> => {
if (token == "" || token.length < 10 || token == undefined) {
return null;
}
const payloadToken = await jwt.verify(token, process.env.SECRETKEYJWT)
const userTokenDecoded: UserSchema = User.findById(payloadToken.id);
if (userTokenDecoded?.userState) {
return userTokenDecoded;
} else {
return null;
}
};
module.exports = { jwtValidatorRenew };
file helper jwt-generator
const { request, response } = require("express");
const jwt = require("jsonwebtoken");
const createJWT = async (id = "", nickname = "") =>
return new Promise((resolve, reject) => {
const payloadInJWT = { id, nickname };
jwt.sign(
payloadInJWT,
process.env.SECRETKEYJWT,
{
expiresIn: 3600,
},
//calback
(error:any, token:string) => {
if (error) {
alert(error)
reject("Error creating token ");
} else {
resolve(token);
}
}
);
});
};
module.exports = { createJWT };
file socket-controller
const { jwtValidatorRenew } = require("../middlewares/jwt-validation-socket");
const { userData } = require("../helpers/helper-user-schema-data");
const { Socket } = require("socket.io");
const User = require("../models/user-model");
const {
ChatMessage,
Message,
MessagePrivate,
GroupChat,
} = require("../models/chat-model");
const chatMessage = new ChatMessage()
const socketController = async (socket = new Socket(), io) => {
const user = await jwtValidatorRenew(
socket.handshake.headers["token-response"]
);
try {
...some sockets flags
} catch (error) {
socket.disconnect();
}
};
module.exports = { socketController };

auth middleware req.body.authorization 'split' is undefined

I am trying to check if there is token but the 'split' is undefined. I'm still learning MERN so idk what's the problem.
const auths = async (req,res,next) => {
try {
const token = req.headers.authorization.split(" ")[1];
const isCustomAuth = token.length < 500;
let decodedData;
if(token && isCustomAuth){
decodedData = jwt.verify(token, 'todo');
req.userId = decodedData?.id;
}else {
decodedData = jwt.decode(token);
req.userId = decodedData?.sub;
}
next();
console.log('auth tapped!');
} catch (error) {
console.log(error);
}
}
Because header don't have authorization. So req.headers.authorization is undefined. You can use optional chaining to fix issues like this:
const token = req.headers.authorization?.split(" ")[1];

node js cant post unauthorised

i have been facing this error of 401 unauthorized error when i tried to mount my isLoggedinMiddlware.js, and even when i can manage to print the token stored, it stil says its
authorised. Any advice or help would be appreciated! Have a nice day.
this is my isLoggedinMiddleware.js
const jwt = require("jsonwebtoken");
const JWT_SECRET = process.env.JWT_SECRET;
module.exports = (req, res, next) => {
const authHeader = req.headers.authorization;
if (authHeader === null || authHeader === undefined || !authHeader.startsWith("Bearer ")) {
res.status(401).send();
return;
}
const token = authHeader.replace("Bearer ", "");
jwt.verify(token, JWT_SECRET, { algorithms: ["HS256"] }, (error, decodedToken) => {
if (error) {
res.status(401).send();
return;
}
req.decodedToken = decodedToken;
next();
});
};
this is my post api
app.post("/listings/",isLoggedInMiddleware,(req,res)=>{
listings.insert(req.body,(error,result)=>{
if(error){
console.log(error)
console.log(req.body)
console.log(isLoggedInMiddleware)
res.status(500).send('Internal Server Error')
return;
}
console.log(result)
res.status(201).send({"Listing Id":result.insertId})
})
})
This is my front end
const baseUrl = "http://localhost:3000";
const loggedInUserID = parseInt(localStorage.getItem("loggedInUserID"));
const token = localStorage.getItem("token")
console.log(token)
if(token === null || isNaN(loggedInUserID)){
window.location.href = "/login/"
}else{
$('#logoff').click(function(){
event.preventDefault();
localStorage.removeItem('token')
localStorage.removeItem('loggedInUserID')
window.alert('Logging out now')
window.location.href = "/login/"
})
$(document).ready(function () {
$('#submitbtn').click((event) => {
const loggedInUserID = parseInt(localStorage.getItem("loggedInUserID"));
// middleware = {headers:{'Authorization':'Bearer '+token},data:{id: loggedInUserID}}
event.preventDefault();
const itemName = $("#itemName").val();
const itemDescription = $("#itemDescription").val();
const price = $('#price').val();
const image = $('#image').val();
const requestBody = {
itemName: itemName,
itemDescription: itemDescription,
price: price,
fk_poster_id: loggedInUserID,
imageUrl: image
}
console.log(requestBody);
axios.post(`${baseUrl}/listings/`,{headers:{'Authorization':'Bearer '+token},data:{id: loggedInUserID}}, requestBody)
.then((response) => {
window.alert("successfully Created")
})
.catch((error) => {
window.alert("Error")
console.log(requestBody)
})
})
})
}
i can managed to get the token i stored when i log in, however, it stills say 401 unauthorised.

How to implement jwt verify token in node js

I tried to implement jwt token generation in node js.I got jwt token but how to validate token using node js crud operation.but I got token jwt verfiy code using callback function.without call back function used to implement async/awit function implement.
index.js
router.post('/', async (req, res) => {
(async function() {
try {
await client.connect();
console.log("Connected correctly to server");
const db = client.db('olc_prod_db');
//Validation
const { error } = validate.validate(req.body);
if (error)
{
return res.status(400).send(error.details[0].message);
}
else
{
const check_login = req.body
const r = await db.collection('UserRegistration').find().toArray();
r.forEach(element => {
if(element['username'] == check_login['username'])
{
const token = get_token.validate(req.body)
res.send({"token ":token})
}
else
{
return res.send(401,"Un Authorized");
}
});
}
client.close();
} catch(err) {
console.log(err.stack);
}
})();
});
authtoken.js
var jwt = require('jsonwebtoken')
function get_token(userdata)
{
var accessToken = jwt.sign(userdata, 'secretkey', {
//Set the expiration
expiresIn: 3600 //we are setting the expiration time of 1 hr.
});
//send the response to the caller with the accesstoken and data
console.log('Authentication is done successfully.....');
return accessToken
}
exports.validate = get_token;
const jwt = require('jsonwebtoken')
const config = require('../../config/default')
function verifyjwt(req,res,next){
const token = req.headers['authorization']
if(!token) return res.status(401).json('Unauthorize user')
try{
const decoded = jwt.verify(token,config.secret);
req.user = decoded
next()
}catch(e){
res.status(400).json('Token not valid')
}
}
module.exports = verifyjwt
const CONST = require('../../config')
exports.validJWTNeeded = (req, res, next) => {
if (req.headers['authorization']) {
try {
let authorization = req.headers['authorization'].split(' ');
if (authorization[0] !== 'Bearer') {
return res.status(401).send('invalid request'); //invalid request
} else {
req.jwt = jwt.verify(authorization[1], CONST.SECRET);
return next();
}
} catch (err) {
return res.status(403).send(); //invalid token
}
} else {
return res.status(401).send('invalid request');
}
}

jsonwebtoken when do decode returns null for expired token

I am looking for a solution where I can get payload for the expired token. I am using jsonwebtoken.
var token = jwt.verify(data,secret_key, (err,tokendata)=>{
console.log('1'+JSON.stringify(err));
console.log('2'+jwt.decode(tokendata));
console.log('3'+tokendata);
console.log('4'+JSON.stringify(jwt.decode(token)));
if(err) {
if(err.name == 'TokenExpiredError') {
console.log('here');
var decode = jwt.decode(token);
console.log(tokendata);
} else {
var result = {};
var data = {'email' : email};
result['isError'] = true;
result['status'] = 403;
result['message'] = 'Invalid accesstoken';
result['data'] = jwt.decode(token);
resolve(result);
}
} else {
var decode = jwt.decode(token);
resolve(decode);
}
});
Can anyone suggest how I can resolve this issue?

Resources