How to force authentication with Passport - passport.js

I have implemented 2 routes:
app.post('/login', passport.authenticate....);
app.get('/admin', myfunction);
If the user first posts to login, I have got him redirected to /admin.
What if the user goes straight to get /admin? How do I ensure that unless he is logged in, he is not allowed to access /admin and is redirected to the login screen?
Also for APIs that are accessed from the application, how do I send 401 if the user is not authenticated by passport?

Passport is middleware that needs to be included where you need route protection
Passport.js is middleware for Express. You include it on any routes that need to be protected, not just on the login route/page.
As a refresher, the approved answer to What does middleware and app.use actually mean in Expressjs? and this link to the off-site page A short guide to Connect Middleware can also help.
Protecting an API route
First, to repeate what was said above...Passport is middleware so you need to include it on the routes defining the API. Additionally, see:
how can I protect an api endpoint with passportjs
passportjs RESTful auth
As for the 401, Passport will generate these for you upon failure if you haven't written your own handler for these.

Related

How do i get the twitter return url when authenticating using passport twitter

I'm using passport twitter to authenticate and while it does work and redirect me to the main page i want to save the oauth token that's there in the url before it redirects me to my main page as i want to use it to update user's profile image
Well turns out it was pretty simple
i just had to use req.url in the passport.authenticate() callback function

passport google strategy with jwt

I did jwt authentication in my previous projects but never worked with oauth/passport auth before..
it's been 3 days i have been learning about passport strategies and i have implemented google+ strategy.
I got new project and this project requires to let users signup/signin themselves with google or facebook or with signup-form using firstName, lastName, phone number and password..
Very briefly in jwt server sends a token to the client and then client sends that particular token in the request header back to server to have access to protected routes.
In passport google strategy a cookie is saved in the browser and is send to server on each request.
What i think is
i cant use two different approaches in one project.. like if i use jwt for signup form and cookie for google strategy how am i gonna protect my routes then? with token in headers or with cookie in browser
Now my question is
how can i use both in the same project?
In google strategy should i generate jwt (token) for client in serializeUser() or somewhere else or what else is possible?
Or should i save jwt token in a browser cookie like passport?
I presented things very briefly, i hope you get it what i'm trying to do here
i cant use two different approaches in one project.. like if i use jwt for signup form and cookie for google strategy how am i gonna protect my routes then? with token in headers or with cookie in browser
You can. Cookie is just a transport mechanism for data between your browser and the server. You can store anything in it (up to allowed size limit) meaning that you can store JWT in a cookie (rather common practice especially for server side rendered single page apps).
You don't even have to develop a custom solution because this is already provided by passport in passport-jwt.
In the scenario where you require to signup the user using predefined fields you could use something known as Local Strategy which is present in passport.passport-local

Properly handling Google OAuth with separated frontend and backend

I have my frontend using React/Next.JS, and I'm wanting to implement Google OAuth for authentication to the users info in the backend.
On the backend, I'm using Express and Passport for routing and authentication respectively. I got all of this working with just the plain username and password, however I decided that I would rather have this with just using OAuth services.
So the current flow:
User on FRONTEND clicks "Login with Google", which redirects them to BACKEND/login/google, which then of course handles logging in with Google, which then once its done redirects to BACKEND/login/google/callback, which will then redirect you to the frontend.
Now here's the issue. On the callback route in my backend, calling Request.isAuthenticated() works just fine. However once the user has navigated back to the frontend, each subsequent request is not authenticated.
My thought here is that since the user is technically being logged in on the backend, the session is being tied to the backend.
What would be a proper way of handling this type of scenario?

How to authenticate/authorize express routes in loopback

I've just created a loopback app and extended User model for the user authentication/authorization.
I'm trying to check if the user is currently logged in or not from my express route so I could redirect user to /login if user is not logged in.
So far it seems loopback only authenticates/authorizes the exposed model methods like /user/update. I'm not able to find anything on how to get loopback to authenticate/authorize the express routes I've defined.
Thanks in advance
Here's the thing, I'm not very good at loopback but I do know a little about Expressjs.
In express, if you wanna do auth, you can use a middleware of your own and use it before other routes handle the request.
You might want to consider express-session as the login status storage.
When log in :
route.post('/login',function(req,res,next){
//login here
req.session.user = user
})
And your own middleware:
function auth(req,res,next){
if(!req.session.user){
res.redirect('/login')
}
}
https://github.com/expressjs/session
In order to enable authentication and authorization for Express routes in a LoopBack application you will need to do the following:
Initialize Loopback Token middleware to use a cookie
Set the signed access_token cookie after you have performed a login
Add middleware to store request context (to enable steps 4 - 6 below)
Add middleware to identify requesting user and store user info in the request context
Add middleware to enable enforcement of login on selected routes
Add login enforcement middleware calls to Express routes as required
If this looks mildly terrifying, fear not because someone has written an awesome blog post on this and provided sample code for all of the above middleware:
Tokens, Sessions and Users, oh my!
Things to note:
If you want your sessions to persist, make sure that LoopBack's AccessToken model is configured to use a data store other than memory. See here for more information: Allow loopback application to use previous access token
The request context middleware as implemented in the blog post does not work as a persistent session store (i.e. only the token persists), the rest is ephemeral.

Passport JWT & Authorize vs Authenticate

Passport seems like a great option for simple authentication, unobtrusive and not hard to setup. I'm building a MEAN stack that authenticates using JWT so I looked to Passport JWT. However there's a few things I'm confused about.
1) Am I correct in assuming that Passport JWT is only used for authenticating requests, not for generating a valid jwt? That is, should it only be used for validating the presence of a token?
2) What's the difference between passport.authorize and passport.authenticate? And when should I use one over the other?
3) I have 3 routes I'm using for authentication related matters, login, signup, and authenticate.
login will check if the user email/password combo exists and matches and then generate a token for the client.
signup will check to make sure the email doesn't already exist and then generate a token for the client.
Now for authenticate this is where I get a little mixed up. Would I even need an authenticate route if I already have login and signup? If anything, it seems like authenticate would be the function that I pass into passport.use for the JWT strategy and then login and signup with the possible addition of a verify_token route would be my only unprotected routes, where everything else would have a call to passport.authenticate or passport.authorize.
Correct. Passport JWT (passport-jwt) is only for authenticating requests. You'll need another tool to actually generate a token. This tutorial uses JWT Simple (jwt-simple) and I've used jsonwebtoken (per this reference).
I haven't seen any references to passport.authorize, so I believe passport.authenticate is what you're looking for. passport.authenticate is what you'll use in your routes to verify that an incoming request has the JWT token and is allowed.
Since you're generating a token via both login and signup, authenticate is redundant and unnecessary. Just make sure you use passport.authenticate in your routes to verify access during requests.
The general setup steps to keep in mind here are:
passport-jwt is for authentication
you need another tool to create a JWT token
the JWT token, which you generate and return to whatever made the request, needs to be present in the header ("Authorization: JWT eyJ0eXAiO...") on subsequent requests
you need to setup your JWT strategy and tell passport to use it
use passport.authenticate to verify access via the JWT token in the header for incoming requests, like:
router.post('/users', passport.authenticate('jwt', {session: false}), function(req, res) {
// do something...
});

Resources