I get error which is cannot access to passport before intializing.
how can i fix it and access to passport through the the route.
and i defined passport in the app.js file and it's middleware
const passport = require(passport) ;
const intializePassport = require("../passportConfig");
const { check,validationResult } = require('express-validator');
const flash = require('express-flash');
const {Router}=require('express');
const authController = require('../controllers/authControllers')
const router = Router()
router.get('/signup',authController.signup_get) ;
router.post('/signup',authController.signup_post);
router.get('/login',authController.login_get);
router.post('/login',passport.authenticate("local",{
successRedirect : "/dashboard",
failureRedirect:"/login",
failureFlash:true ,
})
);
function checkAuthenticated(req,res,next){
if (req.isAuthenticated()){
return res.redirect('/dashboard');
}
next()
}
function checkNotAuthenticated(req,res,next){
if (req.isAuthenticated()){
return next();
}
res.redirect('/login')
}
module.exports=router;
You need to initialize passport before using it, the error is fairly straightforward. If you are still getting error then kindly share your app.js as well. Anyways, just do this:
const intializePassport = require("../passportConfig"); // First
const passport = require(passport); // Second
Related
I create user service with login and register in node js. when i using authenticate middleware i got this kind of errors. if any one have solution. please let me know. i attached code and error image.
this is my route file.
const { Router} = require('express');
const authController = require('../controllers/authController');
const {authMiddleware} = require('../middleware/authMiddleware')
const router = Router();
router.get('/users',{authMiddleware}, authController.users_get);
router.post('/users',authController.users_post);
router.post('/authenticate',authController.authenticate_post);
module.exports = router;
this is my middleware file
const jwt = require('jsonwebtoken');
const requireAuth =(req, res, next)=>{
const token = req.cookie.jwt;
//check json web token exists & is verified
if(token){
jwt.verify(token,'vivekeviv',(err, decodedToken)=>{
if (err){
console.log(err)
}
else {
console.log(decodedToken);
next();
}
})
}
else {
console.log("You need to login")
}
}
module.exports ={requireAuth}
how to add middleware to this code.
i got this kind of error.
You are passing an object where express is expecting a function. You want:
const {requireAuth} = require('../middleware/authMiddleware')
...
router.get('/users', requireAuth, authController.users_get);
i've managed to connect nodejs with postgresql. my problem is this, when trying to retrieve,delete or update a single item, the url '/v1/:id' is not recognized by postman.it throw a cannot get,or cannot delete or update error. but, retrieving all the user items works well. I'm not supposed to use any ORM but pure sql. I've also checked everywhere on the internet with no proper solution or explanation to this. What could be the issue?
//here is my app.js file
const express = require('express');
const bodyParser = require('body-parser');
const pg = require('pg');
const route = require('./routes/user');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.use('/v1',route)
module.exports = app;
//here is my controller file that handles the logic
const db = require('../db/config');
const getAllUsers = (req,res,next)=> {
db.query('select * from users',(err,result)=>{
if(err) {
res.status(400).send('error in connection')
}
res.status(200).json(result.rows);
console.log('this is the getusers route ')
})
}
const getUserById = (req,res,next)=> {
const id =parseInt(req.params.id);
db.query('select * from users where id=$1',[id],(err,results)=>{
if(err) {
throw err
}
res.status(200).send(results.rows);
console.log('successfully found id');
})
}
//delete item
const removeItem = (req,res,next)=> {
const id = parseInt(req.params.id);
db.query('DELETE from users where id=$1',[id],function(err,result){
if(err) {
throw err
}
console.log('item deleted');
})
}
module.exports = {getAllUsers,getUserById,removeItem}
//and here is my route file that handles all the routes
const express = require('express');
const router = express.Router();
const controller = require('../controller/user');
router.get('/',controller.getAllUsers);
router.get('/users/:id',controller.getUserById);
router.delete('/item/:id',controller.removeItem);
module.exports = router;
:id should be treated as URL parameter
http://localhost:8000/v1/users/1234 -> where 1234 is your :id
I'm using POST on my test
id parameter is empty, please enter "id" here
From the screenshot of postman, seems like you missed to set the value for "id" under path variable.
I have making an API using express and node.
Here is my app.js
const express = require('express');
const bodyParser = require('body-parser');
const dotenv = require('dotenv');
// setup dotenv to read environment variables
dotenv.config()
// Load Environment Varibles
const env = require('./utils/env');
// INIT MONGODB CONNECTION
require('./mongoose');
// create a new express application
const app = express();
// setup bodyparser middleware to read request body in requests
// we're only reading JSON inputs
app.use(bodyParser.json());
// Listen to API routes
const apiRoutes = require('./routes')
app.use('/api', apiRoutes);
// Start listening to requests
app.listen(env.PORT, () => {
console.log(`Server started on PORT ${env.PORT}`);
});
And here is the API routes that are being imported
const express = require('express');
const apiController = require('./apiController');
const apiValidator = require('./apiValidator');
const router = express.Router();
router.post('/login', apiValidator.loginUserValidator, apiController.loginUserController);
router.get('/rand', (req, res) => {
res.send('Some randon text');
});
module.exports = router;
Here is the middleware
const {
failureResponse
} = require('./../utils/response');
const errorcodes = require('./../utils/errorcodes');
const loginUserValidator = (req, res, next) => {
const user = req.body;
if (!user.username) {
return res.status(400).json(failureResponse(errorcodes.ERROR_INVALID_BODY_PARAMETER, "Invalid username"));
}
if (!user.password) {
return res.status(400).json(failureResponse(errorcodes.ERROR_INVALID_BODY_PARAMETER, "Invalid password"));
}
if (user.authTokens) {
delete user.authTokens;
}
next();
};
module.exports = {
loginUserValidator
};
Here is the controller
const User = require('./../models/user');
const {
successResponse,
failureResponse
} = require('./../utils/response');
const errorcodes = require('./../utils/errorcodes');
const loginUserController = async (req, res) => {
try {
const user = req.body;
// find if the user already exists
const existingUser = await User.findOne({
username: user.username
});
if (existingUser) {
// user exists. generate token and login user
console.log('Existing user login');
const token = existingUser.generateAuthToken();
return res.status(200).json(successResponse(token));
} else {
console.log('New user login');
const savedUser = await new User(user).save();
const token = savedUser.generateAuthToken();
return res.status(200).json(successResponse(token));
}
} catch (e) {
console.log(e);
return res.status(400).json(failureResponse(errorcodes.ERROR_SERVER_ERROR, "Unable to login user"));
}
};
module.exports = {
loginUserController
};
Here the issue is when I try to hit the login route from Postman, I am getting an error which says Could not get any response.
But when I hit the rand route, the output is correct.
So the issue isn't the arrangement of the code.
Why am I not able to use the login route here?
I've been trying to test the protected routes by using passport and passport-jwt.
I've got it to the point where the token is being generated when a user tries to log in and tested it in Postman.
I've created a route and passed in as an argument passport.authenticate with the jwt strategy and am getting errors all over the place.
In my main server.js, I require passport:
passport = require('passport');
app.use(passport.initialize());
// passport config
require('./config/passport')(passport);
My folder structure is this:
in my passport config file, i have this:
const jwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const mongoose = require('mongoose');
const User = mongoose.model('users')
const keys = require('../config/keys');
const opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = keys.secretOrKey;
module.export = passport => {
passport.use(
new jwtStrategy(opts, (jwt_payload, done) => {
console.log(jwt_payload);
}));
};
And my route is this:
// #route get to /users/current
// #desc: return the current user (who the jwt token belongs to)
// #access: should be public
router.get('/current',
passport.authenticate('jwt', { session: false }),
(req, res) => {
res.json({msg: "Success"})
}
);
The first error I can't seem to get passed is this in the console:
require('./config/passport')(passport);
^
TypeError: require(...) is not a function
In postman, when I try to go to /users/current and pass in a confirmed bearer token, I get this:
Error: Unknown authentication strategy "jwt" at attempt
in passport config file
you have typo module.export actualy its module.exports
thats why after require it does not recongnizing it as function
change the module.export to
module.exports = passport => {
passport.use(
new jwtStrategy(opts, (jwt_payload, done) => {
console.log(jwt_payload);
}));
};
its module.exports and not module.export.
The module.exports property can be assigned a new value (such as a function or object).
module.exports = class Square {
constructor(width) {
this.width = width;
}
area() {
return this.width ** 2;
}
};
nodejs modules documentation reference
For example, in Meteor, there's something like
Router.plugin('ensureSignedIn');
Router.plugin('ensureSignedIn', {
except: ['home', 'atSignIn', 'atSignUp', 'atForgotPassword']
});
So unsigned user cannot access other routes except above four.
How to do this in express.js? I'm using passport.js also.
I'm not familiar with Meteor, but you can do something like the following, assuming you want to make pages available to only authenticated users (passport).
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated())
return next();
else
// Return error content: res.jsonp(...) or redirect: res.redirect('/login')
}
app.get('/account', ensureAuthenticated, function(req, res) {
// Do something with user via req.user
});
The ensureAuthenticated function is just an example, you can define your own function. Calling next() continues the request chain.
I should use middleware for protect my routes, even to protect certain verbs in the same route:
for example: in my endpoint/route.js
// the require sentences are omitted
const express = require('express');
const { /*controllerFunctions*/ } = require('./controller');
const {routeGuard} = require('/*must create a route guard*/');
const router = express.Router();
router.route('')
.get(getAllResources)
;
router.route('/:id') //
.get(validateParam,getOneResource);
router.use(routeGuard);
router.route('/:id')
.post(validateParam,validateBody,postResource)
.patch(validateParam,validateBody,patchProblemById)
.delete(validateParam,deleteResource)
;
module.exports = router;
and my routeGuard file should be like this:
const { promisify } = require('util');
const jwt = require("jsonwebtoken");
const AppError = require('./appError');
const {User} = require('./../endpoints/users/model');
const wrapper = require('./try-wrapper');//try catch wrapper
module.exports.routeGuard = wrapper(async function (req, res, next){
// the err message is the same on purpose
const notAllowed = new AppError('Unauthorized: Invalid or Nonexistent credentials',401);
let token = null;
if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')){
token = req.headers.authorization.split(' ')[1];
}
if (!token) return next(notAllowed );
const payload = await promisify(jwt.verify)(token,process.env.KEY);
const user = await User.findById(payload.id);
if (!user) return next( notAllowed);
if ( ! user.hasSamePasswordSince(payload.iat) )return next( notAllowed );
req.user = user; // further use...
next();
});