Auth and Security

How does JWT authentication work in NestJS with Passport?

On login, LocalStrategy.validate(email, password) checks the bcrypt hash; the controller signs a JWT with JwtService.signAsync({ sub, roles }). On later requests, JwtStrategy (passport-jwt) extracts the Bearer token, verifies signature and expiry with the secret, and its validate(payload) return value becomes req.user. AuthGuard('jwt') (or a subclass) triggers this per route or globally.

How do you make all routes protected by default but keep some public?

Register the JWT guard globally with APP_GUARD, create @Public() with SetMetadata('isPublic', true), and in the guard's canActivate read it with reflector.getAllAndOverride(IS_PUBLIC_KEY, [ctx.getHandler(), ctx.getClass()]). If true, return true; otherwise call super.canActivate(ctx). New routes are then secure unless someone explicitly marks them public.

Why use refresh tokens, and how do you make them safe?

Access tokens are short-lived (e.g. 15 min) so a stolen one is useful only briefly, but users should not log in every 15 minutes. A refresh token (7–30 days) gets new access tokens. Make it safe: store only its hash in the DB, rotate it on every use, revoke all sessions if an old one is reused, send it in an httpOnly, secure, sameSite cookie for browsers, and delete it on logout.

Roles guard vs ownership check: what is the difference and why do you need both?

A roles guard answers "may a customer call this route?" Every customer passes. An ownership check answers "is this order Asha's?" Without it, Asha can read Ravi's order by changing the id in the URL (IDOR). Implement ownership in the query (where: { id, userId: user.id }) and return 404 when not found, or use a policy library like CASL for attribute-based rules.