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

Expose token validation function #43

Open
jkrems opened this issue Dec 22, 2014 · 7 comments
Open

Expose token validation function #43

jkrems opened this issue Dec 22, 2014 · 7 comments
Assignees

Comments

@jkrems
Copy link

jkrems commented Dec 22, 2014

It can be useful csrf tokens as a state parameter to oauth callbacks. Those are a bit of a snowflake: the state is expected to be part of the query of an otherwise normal GET request.

It would be great if something along the lines of this would work:

app.get('/oauth/callback', function(req, res, next) {
  req.csrfToken.verify(req.query.state, function(err) {
    if (err) return next(err);
    // ... react to token that is passed into the callback ...
    res.redirect('/actually-do-stuff');
  });
});
@dougwilson dougwilson self-assigned this Dec 22, 2014
@gabeio
Copy link
Member

gabeio commented Jan 8, 2015

👍 this would be great especially in situations where you are not using the body-parser module as it currently can not handle multipart bodies.

@dougwilson
Copy link
Contributor

Though remember that multer and connect-multiparty will have you covered in that situation.

@dougwilson
Copy link
Contributor

Or simply pass the token in the query string :)

@gabeio
Copy link
Member

gabeio commented Jan 8, 2015

at the moment I have taken a liking to formidable I am playing with it at the moment I might have a work around... if I can parse the form before csurf gets a hold of it I can just fill the fields into the req.body anyway and just let it pretend it's body-parser

@gabeio
Copy link
Member

gabeio commented Jan 8, 2015

yeah I got it working I just put the formidable processor before csurf and filled req.body worked perfectly but still would like to see more public api for validation thanks! might help with that if I have time :)

@dougwilson dougwilson assigned dougwilson and unassigned dougwilson Feb 15, 2015
YourDeveloperFriend added a commit to YourDeveloperFriend/csurf that referenced this issue Sep 14, 2015
@YourDeveloperFriend
Copy link

Please check out my pull request for this issue: #82

@BowlingX
Copy link

I used the following to implement a state parameter for passportjs and oauth2 just in case somebody stumbles upon this topic. You can just use the csrf library to generate the state on your own:

// @flow

import Tokens from 'csrf'

type Options = {
  cookieKey: string,
  cookieSecure: boolean
}

export class CsrfTokenStore {
  options: Options
  csrf: Tokens

  constructor(options: Options) {
    this.options = options
    this.csrf = new Tokens()
  }

  store(req: Object, cb: Function) {
    // create a secret and store it inside the cookie
    const secret =
      req.signedCookies[this.options.cookieKey] ||
      (req.locals ? req.locals.secret : null)
    if (!secret) {
      throw new Error('Could not find auth secret')
    }
    cb(null, this.csrf.create(secret))
  }

  verify(req: Object, providedState: string, cb: Function) {
    const secret = req.signedCookies[this.options.cookieKey]
    cb(null, this.csrf.verify(secret, providedState))
  }

  configureMiddleware(app: Object, path: ?string) {
    app.use(path, async (req, res, next) => {
      if (!req.signedCookies[this.options.cookieKey]) {
        const secret = await this.csrf.secret()
        req.locals = {
          secret
        }
        res.cookie(this.options.cookieKey, secret, {
          httpOnly: true,
          secure: this.options.cookieSecure,
          signed: true
        })
      }
      next()
    })
  }
}

And then in your middleware:

import OAuth2Strategy from 'passport-oauth2'
import cookieParser from 'cookie-parser'
import cookieEncrypter from 'cookie-encrypter'
import passport from 'passport'

/** .. other thinks */

const secret = process.env.APP_SECRET

const authStateStore = new CsrfTokenStore({
    cookieKey: authStateCookieName,
    cookieSecure: /**  true / false */
  })
const auth0Strategy = new OAuth2Strategy(
    {
      /**... all the other parameters */
      store: authStateStore,
    }
  )
  passport.use(auth0Strategy)
  app.use(cookieParser(secret))
  app.use(cookieEncrypter(secret))
  authStateStore.configureMiddleware(app, '/oauth_login')
  app.use(passport.initialize())

  app.get(
     '/oauth_login',
    passport.authenticate('oauth2', {
      scope: ['openid', 'offline_access', 'roles']
    }),
    (req, res) => {
      res.redirect('/')
    }
  )

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

No branches or pull requests

5 participants