Skip to content
This repository has been archived by the owner on Sep 14, 2022. It is now read-only.

How to add middleware before specific route controller (need code example) #421

Closed
sandipwane opened this issue Aug 11, 2016 · 6 comments
Closed

Comments

@sandipwane
Copy link

I have been searching everywhere and don't seem to have found anything useful. I have generated a swagger project for express and been trying to add a auth middleware to specific route. I have implemented a custom auth middleware and been trying to execute it before getUserList controller.
How do I do that if some one could explain with an example that would be very helpful.

@jerry8050
Copy link

+1

@frederik
Copy link

frederik commented Sep 1, 2016

What we did for our jwt token based out is first define securityDefinitions for the routes that should be authenticated (in the swagger definition - in your case that's getUserList) and then add swaggerSecurityHandlers (also see here) to our SwaggerExpress config.

The handler itself then calls Passport or whatever middleware to then attach the user object to the request so it can be used in the following controller.

Does that sound like sth. that would work for you?

@patryk-wlaz
Copy link

Hi frederik, it sounds like something that would sure work for me. I've already wasted two days looking for simple answer how to use passport and swagger. I once had working app with passport but without proper restful api neither swagger. Now I'm refactoring.
Lets say I had e.g.
router.post('/user', passport.authenticate('local-signup')
Now I have working swagger (set up without swagger-tools, just swagger project create, swagger project edit, created yaml file, created controller). Works cool, but I dont know how to add passport middleware (or any other one).
Could you provide some code snippet for your solution? I'm not really sure how to implement JWT tokens (do I need them while working with passport local strategy only, cause I never used them before)? Can it be done without swagger-tools?

@frederik
Copy link

Hi Patryk, (in hope this is still useful to someone)

whether you need JWT really depends on your use case (maybe have a look here).

With JWT it'd look sth. like this. First, you need to add the handler to the swagger config like this.

swaggerSecurityHandlers: {
            jwt_token: (req, authOrSecDef, scopes, callback) => {
                authenticateJwt(req, callback);
            }
        }

To configure passport you can register it with express like this:

export let initializePassport = (express) => {

    express.use(Passport.initialize());

    const strategyOptions: PassportJwt.StrategyOptions = {
        jwtFromRequest: PassportJwt.ExtractJwt.fromAuthHeader(),
        secretOrKey: "your-secret-here--seriously-change-me",
        issuer: "mydomain.org"
    }

    const jwtStrategy = new PassportJwt.Strategy(strategyOptions, (jwt_payload, done) => {
        var userId: string = jwt_payload.sub;
        done(null, userId);
    });

    Passport.use(jwtStrategy);
}

Then define the authenticateJwt where it has access to the configured Passport

export let authenticateJwt = (req, callback) => {
    const handler = Passport.authenticate('jwt', { session: false }, (err, user, info) => {
        if (err) return callback(new Error('Error in passport authenticate'));
        if (!user) return callback(new Error('Failed to authenticate oAuth token'));
        req.user = user;
        callback();
    });
    
    handler(req, null, callback);
};

@phil-warner
Copy link

Hi Frederik,

Great job. Worked for me. Thank you!

@patryk-wlaz
Copy link

I ended up not using passport, neither swagger as framework (just documenting my routes set up in traditional way). Anyway, thanks for your answer :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants