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
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 };
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];
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.
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');
}
}
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?