Passport: Docs are simply not clear

Created on 21 Jul 2017  路  14Comments  路  Source: jaredhanson/passport

I have been trying to get the basic (local) use case working for the better part of a day and I don't even have it hooked up to a db, and yet things don't make sense or even work.

I hope I'm wrong but an API should not be more complicated than the 2 or 3 IF / ELSE conditions it needs to wrap around, ugh.

Its not clear how to provide authorization checking on all non /login /logout calls that need to be protected. The docs for serializeUser don't seem to suggest doing anything. The language looks like passport does this for you, but then the code examples seem like its really an API call a user would need to make / create. Where does this fit in with routes?

Where is the API docs for each passport function located? It looks like some methods can take an object param, others a function, this really needs to be explained somewhere other than inspecting code or looking at examples which don't fully explain behavior.

I take issue with this paragraph...

"Each subsequent request will not contain credentials, but rather the unique cookie that identifies the session. In order to support login sessions, Passport will serialize and deserialize user instances to and from the session."

I'm using session and there is no SetCookie header being sent back from the server and I have done the login as suggested by the docs. What is the name of the cookie? More so, this last sentence to me say passport will serialize / deserialize for me, but why are there samples of the API calls right below?

Is req.IsAuthenticated() supposed to do something here? It seems to be important except for 2 reasons.

  1. Its not in the docs
  2. Its not a function (at least in my code, its not a method inside the request object)

How does passport add this method to the request object? seems like its some magically middleware step that forgot to make its way into the docs?

All 14 comments

seems like this bit is missing somewhere

var isAuthenticated = function (req, res, next) {
  if (req.session.passport && req.session.passport.user) {
    return next();
  }
  else {
    res.send(401, {'message': 'Not authorized'});
  }
}

...

app.use('/some/path/that/requires/auth', isAuthenticated, require('./server/routes/somerouter').router);

so this seems silly / bad to do a check on the session like that, or rather the passport should be doing this for me right? I mean its creating the session value "user", seems bad I'm guessing at that being there. What am I missing here...

Passport has been terribly confusing for me as well. Why is isAuthenticated() completely undocumented? I'd be happy to contribute documentation myself, but I'm currently having trouble finding where the documentation repo is.

This video really helped me.
https://www.youtube.com/watch?v=twav6O53zIQ
I had a similar problem, after looking at lots of examples I couldn't even get it working at all. The video covers almost everything you need for a simple LocalStrategy setup using passport-local, the passport docs were good enough to fill in the rest. Hope that helps

Everyone knows. There is a great course on pluralsight.

req.isAuthenticated() will check whether the user has an authenticated session (i.e. logged in at some point in the past). If it returns false you need to redirect to a route that authenticates the user with passport. In our application we redirect to /login.

If you want to check whether they are authenticated on a request and automatically redirect to /login, I would highly recommend checking out the connect-ensure-login middleware.

I think my issue is req.isAuthenticated is undefined. So perhaps I did not set this all up correctly. I'll take a look at connect-ensure-login. I just created my own isAuthenticated method and I use that instead which seems to work but also seems hackery. I would like to use the official function.

Oh I see, in that example, _req.isAuthenticated_ is supposed to be

undefined

if the user is not authenticated? I see the confusion. Its used as a 1. "function" and as an 2. "undefined" type. That is a very difficult assumption to make as I assumed it was always a method that would return true or false

If it is undefined then your middlewares may not be in the correct order. Register passport first and then your route.

Great, that helps, I think i figured out my issue. Docs still need to show this in action tho.

Actually the docs are very clear but only when read carefully. To quote the first couple of sentences:

Passport's sole purpose is to authenticate requests, which it does through an extensible set of plugins known as strategies. Passport does not mount routes or assume any particular database schema, which maximizes flexibility and allows application-level decisions to be made by the developer.

Passport is structured to just authentication middleware. You're trying to ask questions that Passport should not be able to answer. If Passport included a default (de)serialisation method for users it would have to make an irrelevant assumption about what users are and how they are structured.

I suggest you look at pre-defined strategies for starting with Passport. For your specific case I'd suggest looking the basic LocalStrategy. The server.js file has plenty of comments to explain exaclty how passport works and is easy to understand. https://github.com/passport/express-4.x-local-example

Edit:
Just to be clear - I do agree that the purpose and usage of Passport should be described in a more approachable manner in the README.md. I'd suggest improving the headings on the current README. Renaming USAGE to Getting Started and include a simple tutorial to actually build a functioning LocalStrategy (most of this content can be taken from here: https://github.com/passport/express-4.x-local-example/blob/master/server.js). Being able to build a simple demo without leaving the README creates familiarity with Passport and builds confidence for new users. After that I'd suggest a separate section describing (third party) Strategies, why you have them and how to use them.

These changes are relatively small but I think they would add a great deal of clarity to the confusion. I also had my frustrations when first using Passport and understanding its ecosystem.

Actually the docs are very clear but only when read carefully.

No matter how carefully I read, isAuthenticated() is still not documented.

I understand you. But you're missing my point I think. Again quoting from the first paragraph:

The API is simple: you provide Passport a request to authenticate, and Passport provides hooks for controlling what occurs when authentication succeeds or fails.

isAuthenticated() is not documented because I think it is not considered a core feature of passport. How it made its way into request.js is unclear to me. I suppose it's because of the intended express.js support. You can see that since 2012 @jaredhanson has taken a stance against implementing session management into passport. Read: https://github.com/jaredhanson/passport/issues/385#issuecomment-123807032

You can always fix the documentation if you disagree with this To do so check: https://github.com/passport/www.passportjs.org. 馃槈

As a dumb noobie to Passport (and not exactly a world-renowned expert on Express either) I would like to politely +1 the usefulness of more documentation. If you look at Stack Overflow (eg. https://stackoverflow.com/questions/16434893/node-express-passport-req-user-undefined or https://stackoverflow.com/questions/27637609/understanding-passport-serialize-deserialize) it seems there are a lot of people having difficulty with basic stuff like sessions and the serialization/deserialization process.

Dumb noobies like myself inevitably get things wrong when we try to implement a tool we haven't used before, and docs which both explain (all of) the library's pieces and provide a larger understanding of how those pieces fit together make things _sooo_ much easier. Adding basic (and probably very obvious) things to the docs, like documenting what the arguments to the done callback of serializeUser/deserializeUser are (eg. why am I passing null as the first arg?), or providing a rough/broad overview of the flow between the strategy handler, the user (de)serializers, and the endpoint handler, could potentially save Passport learners a lot of time.

Unfortunately while I'd love to PR some documentation updates myself, I can't because I don't understand how this stuff works either (it's a catch 22: I can't improve the documentation because the documentation doesn't explain the things I'd want to improve).

+1 here... There is not a single good example I found for using passport.
Not even these are good enough:

I've been messing with passport for over a day... and I'm guessing it's much easier to do auth myself by now...

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ginovski picture ginovski  路  6Comments

angel1st picture angel1st  路  7Comments

fvgs picture fvgs  路  6Comments

Gibbo3771 picture Gibbo3771  路  4Comments

itaditya picture itaditya  路  5Comments