Closed zackiles closed 7 years ago
@zackiles did you find a solution for this?
Same problem for me !
Any solution to look at for this?
This might be a bit late, but it's actually pretty easy to do.
I'm using the fromAuthHeaderAsBearerToken()
as extractor
const jwtOptions: JWTStrategyOptions = {
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: Config.auth.jwtSecret()
}
class AuthService {
// Register the strategy
constructor() {
passport.use('authenticate', this.jwtAuthenticateWithoutUserStrategy())
}
// ...
// Setup the strategy
private jwtAuthenticateWithoutUserStrategy() {
return new JWTStrategy(jwtOptions, (payload, callback) => {
if (payload.id) {
callback(null, { id: payload.id })
} else {
const error = { message: 'Invalid user' }
callback(error, null, error)
}
})
}
// ...
// authentication method `AuthService.authenticate`
public get authenticate() {
return passport.authenticate('authenticate', {session: false})
}
// ...
// Optional authentication
public optionalAuthenticate = (request: Request, response: Response, next: NextFunction) => {
const auth = request.header('Authorization')
if (auth) {
this.authenticate(request, response, next)
} else {
next()
}
}
}
const router = Router()
router.get('/myPersonalizedContent', AuthService.optionalAuthenticate, (req, res, next) => {
if (req.user && req.user.id) {
//TODO: Do something with the user ID and fetch some special data
} else {
//TODO: The user is not logged in
}
})
So the AuthService.optionalAuthenticate
checks first if the token is set in the header, if you are using some other extraction method you would need to update this. If the token is set lets the Strategy handle the token and validate everything for us. If the Authorization
is not set... we don't really care and just delegate all the handling to the next function.
This is what the passport-anonymous strategy is for. Just chain it after JWT
one.
The quick guide on using passport-anonymous
with passport-jwt
npm install passport-anonymous
passport.use(new AnonymousStrategy());
router.get("/", passport.authenticate(["jwt", "anonymous"], {session:false}), (req, res) => {
if (req.user) {
console.log("User logged in", req.user);
} else {
console.log("User isn't logged in");
}
});
Keep in mind that jwt
should come first, then anonymous
passport-anonymous
is indeed the right solution.
You can define functions add as middleware on certain routes:
module.exports.requiresAuth = passport.authenticate('jwt', {session: false, failureRedirect: '/'});
module.exports.canHaveAuth = passport.authenticate(['jwt', 'anonymous'], {session: false}
Coming from express cookie session, if a session is found it will automatically set req.user with a logged in user. I'd like to create routes that authenticates req.user for authenticated users but still allow non authenticated users to access the route. Currently the passport.authenticate('jwt') function will just throw an error if there is no authentication forcing me to create authenticated-only routes. Would anybody be as kind to give me a workaround? Maybe a way to call authenticate not within a route handler?