NestJS Authenticated sessions documentation has major gaps and is seemingly wrong
See original GitHub issueI’m submitting a…
[ ] Regression
[ ] Bug report
[ ] Feature request
[x] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Current behavior
“Session” instructions in “Authentication” section of documentation is erroneous and this functionality is otherwise undocumented. (And non-obvious.)
Expected behavior
It should be clear how to implement AuthGuard with a cookie-based sessions.
Please see my comment from Sept. 14 here.
At this point I DO have my browser at least storing a cookie after adding stuff directly to my main.ts, which I think is bad form:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as session from 'express-session';
import * as passport from 'passport';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use(session({
secret: 'a secret',
name: 'abcd',
resave: true,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
await app.listen(3000);
}
bootstrap();
This at least gets me a cookie with key “abcd” in my Chrome Developer Tools “Application” > “Cookies” section, with a long value (s%3Ac1xPblaYplJQL2DLmfIUVoLdLIbkjsYQ.e8Q69kfkdn1Mm96Clk6BMg4Ea0k647RnIkT2bP60Lwc
).
In my custom Guard, I can actually inspect the request and see that it has a session
property with a Session object in it. The Session object has an id RUHHx_IvcDIPFWt-9MHeZHruw1bSO7-O
which is different from what’s stored in my cookie – but that may be normal. The request object also has a sessionID
property, with the same ID… And a sessionStore
property with a MemoryStore object that has as property of sessions
in it, that’s just an empty object.
Going back to the documentation’s recommended code: just calling super.logIn(theRequestObject)
sends me directly to my Google Auth strategy’s serializeUser
function, which is supposed to callback with the user that gets passed to it and/or an error.
Unfortunately, there is never any user that gets passed to it. I’m not sure how the User is intended to be retrieved from the session memory store, or where it’s intended to be set to the memory store…
So there’s a ton of stuff missing here. 😦
Environment
Nest version: 5.4.0
For Tooling issues:
- Node version: 8.11.3
- Platform: Fedora 25; Windows 10 x64
Other: @kamilmysliwiec It seems at least 3 other people are confused about this. It’s very frustrating. I think NestJS is so cool, but I took a break from it largely because I was spinning my wheels with this very issue. It would be one thing if I felt like I was just confused, but as it stands the docs are clearly wrong (or at least misleading), so I don’t feel like I can move forward.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:34
- Comments:43 (9 by maintainers)
Top GitHub Comments
I was able to get this working – here’s the solution I came up with:
configure sessions and passport to use sessions
In
main.ts
(or wherever you’re settting up nest):session
from theexpress-session
package.guards
I’m using
passport-local
so myLocalAuthGuard
class looks like this:configure the serializer
If you look at the implementation of
PassportSerializer
(from@nestjs/passport
) you’ll notice that bothserializeUser
anddeserializeUser
are abstract…so they need to be implemented by you. Take a look: https://github.com/nestjs/passport/blob/master/lib/passport/passport.serializer.tsMy barebones serializer looks like this:
update auth module
Then in the module (for example I’m using
AuthModule
), this needs to be included. So myAuthModule
class looks like this:session guard
Create a guard to check to see if the user is in the session.
putting it all together
Here is how this can be used in a controller:
You can test this out with cURL/Postman:
Logging in:
Then to test it out:
Thanks @kamilmysliwiec for all your work on NestJS – seems very slick!
Hi all,
After digging into whole Nestjs framework, I find it really cool. But, the security aspects are very painful. Implementing a simple local-strategy session should not be as difficult as the code @TrejGun has provided (thanx for that btw). We have to provide :
Look at this snippet from Spring Security for example :
This code can be used for LDAP, local strategy, Google/Facebook and whatever you want without changing any single line of code in your controllers.
With UserGuard/Auth annotations, we tie the controllers code with custom annotations. There’s no notion of Principal, only req.session.passport user which is very low level.
We should be able to say in app.module that we want a Passport local strategy (session/basic or other) and all the boilerplate code that we generally see should be generated or implemented in NestJS for us.
My 2 cents
Sami