I have one post like this
app.post('/auth', passport.initialize(), passport.authenticate('local', { session: false,scope: [] }), serialize, generateToken, respond);
this is working correctly.
Now I have made above post as a function and calling from different page
accesstokenController.auth = function(req, res) {
console.log('Here auth called');
passport.initialize(), passport.authenticate(
'local', {
session: false,
scope: []
}), serialize, generateToken, respond
};
and calling this method from differnt rout page.
This is not working means passport.intialize() or passport.authenticate is not being called
Router calling method
var oauth = require("../oauth/accesstoken");
router.post('/auth', function(req, res) {
oauth.auth(req, res);
});
What's wrong there
Thanks
See the express reference for
app.method
and
passing middleware arguments.
You can export an array of handler functions like so:
// ./oauth.js
exports.init = [
// express_session({secret: 'use express-session if you like'),
// passport.session(),
passport.initialize()
];
exports.login = [
passport.authenticate('local', options),
serialize,
generateToken,
(req, res) => res.send('you are logged in')
];
and use them in your app/router:
// ./app.js
const auth = require('./oauth');
app.use(auth.init);
app.post('/login', auth.login);
To follow the passport docs,
you should configure the module and call passport.initalize (a function returning an express middleware function, hence the brackets) separately with app.use
Related
The passport docs use this to protect a route:
app.get('/api/me',
passport.authenticate('basic', { session: false }),
function(req, res) {
res.json(req.user);
});
How does authenticate() know which request to authenticate? I don't pass the request to it.
The passport.authenticate returns a function.
You can try this
console.log(passport.authenticate('basic', { session: false }));
and it will print something like
function(req, res, next){ ... }
This means that the app.get will look something like this after your app starts
app.get('/api/me',
function(req, res, next){
// now passport has access to the "req" even though you didn't pass request to it
// passport's authentication logic here
},
function(req, res) {
res.json(req.user);
});
I am currently developing a website using MERS stack. I am using express-session and passport.js for my back-end authentication. When I try to log in from my back-end server, the API works fine. However, when I try to send a POST request from my client-side (React), it is not authenticated.
I have tried to console.log the request from front-end and back-end, and the request is identical. One thing I notice is when I do not put an authentication middleware in my API, my front-end gets the data after being redirected to the API; the opposite happens when I put the middleware.
//This is my POST code
router.post(
"/userLogin",
passport.authenticate("local", {
successRedirect: "/api/user",
failureRedirect: "/api/user/asktologin"
}),
(req, res) => {}
);
//This is my middleware
const isLoggedIn = (req, res, next) => {
if (req.isAuthenticated()) {
console.log(req.isAuthenticated);
} else {
console.log(req);
}
};
Your isLoggedIn middleware is not calling the next function in the stack. It should look like this
const authenticationMiddleware = (req, res, next) => {
if (req.isAuthenticated()) {
console.log(req.isAuthenticated);
next()
} else {
console.log(req);
res.send(400);
}
};
// Then you configure it like so
app.use(authenticationMiddleware);
// Your "router" config goes here
post("/userLogin",
passport.authenticate("local", {
successRedirect: "/api/user",
failureRedirect: "/api/user/asktologin"
}),
(req, res) => {
// Do stuff
}
);
For more detailed information on how to use middlewares, make sure you check out the docs.
I'm developing a RESTful API with Express.js and I'm using Passport.js for authentication purposes.
Here is an example of how I'm using passport with routes:
const beerRoutes = require('./beerRoutes') // an instance of express router
let authenticateRoute = passport.authenticate('jwt', { session: false })
router.use('/beer', authenticateRoute, beerRoutes)
Inside beerRoutes.js :
const router = require('express').Router()
router.post('/', (req, res) => {})
router.get('/', (req, res) => {})
router.patch('/', (req, res) => {})
router.delete('/', (req, res) => {})
The problem is, I want unauthenticated clients to be able to create new users (i.e. POST /beer/).
But I also want to give additional permissions to authenticated clients when they send a request to the same endpoint.
How can I achieve this without letting unauthenticated clients to access other routes inside beerRoutes (e.g. PATCH /beer/)?
This can be addressed with a custom middleware which calls the Passport.js middleware.
const authenticationWhiteList = [
'POST /beer'
]
function Authenticate (request, response, next) {
let route = `${request.method} ${request.baseUrl}`
if (_.indexOf(authenticationWhiteList, route) !== -1) {
next()
} else {
passport.authenticate('jwt', { session: false })(request, response, next)
}
}
Then change the authentication code to this one:
const beerRoutes = require('./beerRoutes') // an instance of express router
// let authenticateRoute = passport.authenticate('jwt', { session: false })
let authenticateRoute = Authenticate
router.use('/beer', authenticateRoute, beerRoutes)
js and Passport.js. So I have this :
router.post('/login', middleware1, middleware2);
I also have this on my app.js
passport.use(new passportLocal(
{ usernameField: 'email' },
function(email, password, done) {
// working logic here
// this returns a user object
// to the middleware1 if query is ok
// returns error otherwise.
}
));
And here are my middlewares
middleware1 = function (req, res, next) {
passport.authenticate('local', function(error, user, message){
// How do I get the 'user' object and pass it
// to the outer req or res?
req.user = user; // <- is this ok?
})(req, res, next);
req.user = user;
next();
}
middleware2 = function (req, res, next) {
console.log("user ", req.user); // <- this will obviously print null or undefined
}
Now. How do I pass the user object from inside the passport.authenticate() to middleware2. I'm thinking of using promise something like this passport.authenticate().then() but I dont know the syntax. Please help. Thanks.
app.post('/login',
passport.authenticate('local'),
function(req, res) {
// If this function gets called, authentication was successful.
// `req.user` contains the authenticated user.
res.redirect('/users/' + req.user.username);
});
authenticate()'s function signature is standard Connect middleware, which makes it convenient to use as route middleware
Why are you wrapping the passport.authenticate() in another function?
I'm not sure what you are trying to do, but I would probably start without the misdirection
router.post('/login', passport.authenticate('local'), middleware2(req,res,next));
function middleware2(req,res,next) {
console.log("user ", req.user);
}
If you want the req object passed to your function set the passport js options 'passReqToCallback: true '
I want to just verify something but have't been able to find anything in the Express docs or online regarding this (although I know it's a feature).
I could just test this out but I don't really have a nice template and would like to hear from the community.
If I define a route in express like such:
app.get('/', function (req, res) {
res.send('GET request to homepage');
});
I can also define a middleware and load it directly, such as
middleware = function(req, res){
res.send('GET request to homepage');
});
app.get('/', middleware)
However, I can also chain at least one of these routes to run extra middleware, such as authentication, as such:
app.get('/', middleware, function (req, res) {
res.send('GET request to homepage');
});
Are these infinitely chainable? Could I stick 10 middleware functions on a given route if I wanted to? I want to see the parameters that app.get can accept but like mentioned I can't find it in the docs.
Consider following example:
const middleware = {
requireAuthentication: function(req, res, next) {
console.log('private route list!');
next();
},
logger: function(req, res, next) {
console.log('Original request hit : '+req.originalUrl);
next();
}
}
Now you can add multiple middleware using the following code:
app.get('/', [middleware.requireAuthentication, middleware.logger], function(req, res) {
res.send('Hello!');
});
So, from the above piece of code, you can see that requireAuthentication and logger are two different middlewares added.
It's not saying "infinitely", but it does say that you can add multiple middleware functions (called "callbacks" in the documentation) here:
router.METHOD(path, [callback, ...] callback)
...
You can provide multiple callbacks, and all are treated equally, and behave just like middleware, except that these callbacks may invoke next('route') to bypass the remaining route callback(s). You can use this mechanism to perform pre-conditions on a route then pass control to subsequent routes when there is no reason to proceed with the route matched.
As you can see, there's not distinction between a middleware function and the function that commonly handles the request (the one which is usually the last function added to the list).
Having 10 shouldn't be a problem (if you really need to).
Express version "express": "^4.17.1" or above
From the document: Series of Middleware
var r1 = express.Router();
r1.get('/', function (req, res, next) {
next();
});
var r2 = express.Router();
r2.get('/', function (req, res, next) {
next();
});
app.use(r1, r2);
Let's try a real life example:
tourController.js
exports.checkBody = (req, res, next)=>{ // middleware 1
if (!req.body.price){
return res.status(400).json({
status:'fail',
message:'Missing price!!!'
})
}
next();
}
exports.createTour = (req, res) => { // middleware 2
tours.push(req.body);
fs.writeFile(
`${__dirname}/dev-data/data/tours-simple.json`,
JSON.stringify(tours),
(err) => {
res.status(201).json({
status: 'success',
data: {
tour: newTour,
},
});
}
);
};
tourRouter.js
const express = require('express');
const tourController = require('./../controller/tourController')
const router = express.Router();
router.route('/')
.get(tourController.getAllTours)
.post(tourController.checkBody, tourController.createTour);
//muliple Middleware in post route
module.exports = router //need this or the following step will break
app.js
const express = require('express');
const tourRouter = require('./route/tourRouter');
const app = express();
app.use(express.json());
app.use('/api/v1/tours', tourRouter);
module.exports = app;