简体   繁体   中英

Protecting an API with Scopes (oauth2orize, passport, express, Nodejs)

I'm trying to create an API with node/express, and secure it with Passport and oauth2orize. I've got the API working, I've got the oauth2 stuff working, but I can't seem to figure out how to implement securing API methods with scopes.

The oauth2orize token hander-outer:

server.exchange(oauth2orize.exchange.password(function (client, username, password, scope, done) {
scope = scope || ['unauthorized'];
db.collection('oauth_users').findOne({username: username}, function (err, user) {
    if (err) return done(err);
    if (!user) return done(null, false);
    for (i in scope)
        if(user.scope.indexOf(scope[i]) < 0) return done(null, false);
    bcrypt.compare(password, user.password, function (err, res) {
        if (!res) return done(null, false);

        var token = utils.uid(256)
        var refreshToken = utils.uid(256)
        var tokenHash = crypto.createHash('sha1').update(token).digest('hex')
        var refreshTokenHash = crypto.createHash('sha1').update(refreshToken).digest('hex')

        var expirationDate = new Date(new Date().getTime() + (3600 * 1000))

        db.collection('oauth_access_tokens').save({token: tokenHash, expirationDate: expirationDate, clientId: client.clientId, userId: username, scope: scope}, function (err) {
            if (err) return done(err)
            db.collection('oauth_refresh_tokens').save({refreshToken: refreshTokenHash, clientId: client.clientId, userId: username}, function (err) {
                if (err) return done(err)
                done(null, token, refreshToken, {expires_in: expirationDate})
            })
        })
    })
}) }))

The passport bearer token checker:

passport.use("accessToken", new BearerStrategy(
{passReqToCallback: true},
function (req, accessToken, done) {
    console.dir(req.params);
    var accessTokenHash = crypto.createHash('sha1').update(accessToken).digest('hex')
    db.collection('oauth_access_tokens').findOne({token: accessTokenHash}, function (err, token) {
        if (err) return done(err);
        if (!token) return done(null, false);
        if (new Date() > token.expirationDate) {
            db.collection('oauth_access_tokens').remove({token: accessTokenHash}, function (err) { done(err) });
        } else {
            db.collection('oauth_users').findOne({username: token.userId}, function (err, user) {
                if (err) return done(err);
                if (!user) return done(null, false);
                // no use of scopes for no
                var info = { scope: '*' }
                done(null, user, info);
            })
        }
    })
}))

The API security:

router.get('/restricted', passport.authenticate('accessToken', { scope: "unauthorized", session: false }), function (req, res) {
res.send("Restricted Function");})

I can find no example of accessing the "scope" option passed in passport.authenticate to passport.use. I was thinking it was in the req object, but I can't find it in there. Any help?

A bit late. But thought this might help. The info object that you pass as the third parameter can be used from the middleware as req.authInfo . If you have scope attached with the user object or if you have declared it at passport.authenticate initialize level, you can pass it through this parameter and make use of in the middleware. Please have a look at this link Usage of scopes

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM