feathersjs-ecosystem / authentication

[MOVED] Feathers local, token, and OAuth authentication over REST and Websockets using JSON Web Tokens (JWT) with PassportJS.
MIT License
317 stars 118 forks source link

Session support using state #677

Closed davejtoews closed 5 years ago

davejtoews commented 6 years ago

Attempting to upgrade my application from:

"feathers": "^2.0.0",
"feathers-authentication": "^0.7.10",

to:

"@feathersjs/feathers": "^3.1.4",
"@feathersjs/authentication": "^2.1.5",

Among other Feathers upgrades.

My application uses a Reddit login via passport-reddit. Reddit requires a state parameter passed in the URL string, but this seems to be causing an issue for Feathers.

Upon arriving at my redirect url - something like: example.app/auth/reddit/callback?state=[STATE]&code=[CODE], I hit a server error and get the following error message on server log:

OAuth 2.0 authentication requires session support when using state. Did you forget to use express-session middleware?

I've read through a number of issues and threads regarding sessions but I've yet to find a way to resolve this.

daffl commented 6 years ago

Have you tried adding the express-session middleware? I would recommend to first upgrade the old feathers-authentication to a 1.x version and then update everything else.

That's kind of how was intended since there has been over a year between auth 1.0 and Feathers Buzzard (where authentication didn't really change much).

davejtoews commented 6 years ago

I've tried making use of express-session but unclear exactly how to implement. The /auth/reddit/callback endpoint is being created by @feathersjs/authentication and isn't something I've previously had to modify. Auth worked more or less out-of-the-box in the previously used version.

Did previous versions of feathers authentication have express-middleware baked in? Would any such versions still be compatible with feathers core @ 3.x, or what's the simplest way to get express-middleware running on the auth endpoints?

Have tried creating a new feathers app with latest versions via generator just to figure out this auth piece, but I'm hitting the same issue and confused about the specifics of implementation.

daffl commented 6 years ago

If it was there were probably good reasons why it was removed. Sessions can be enabled and used like any other Express middleware though by just adding

var session = require('express-session')

app.use(session());

Somewhere before app.configure(authentication()).

davejtoews commented 6 years ago

This got me further. I did have to pass in a secret:

app.use(session({secret: app.get('auth').secret}));

And now I'm getting a FeathersError:

Forbidden: Unable to verify authorization request state.

This seems to originate in the passport-oauth2 module.

daffl commented 6 years ago

Did you find a solution? I can still look into it with a repository to reproduce the problem.

davejtoews commented 6 years ago

@daffl Haven't found a solution. Added you as a collaborator, not on existing project but on relatively clean feathers install using Reddit login.

Seemed like the best way both to isolate the problem and keep oAuth secret in private repo.

https://github.com/davejtoews/feathers-reddit-auth

ccummings commented 6 years ago

@davejtoews I just solved this in my own app while getting passport-auth0 to work. It also requires express-session to support a state parameter.

My solution was to add express-session in the src/authenticate.js file that is normally generated by feathers. (An example of this file can be found in the chat example)

Before the app.configure(authentication(config)); line I added the following:

  app.use(session({
    secret: config.secret,
    resave: false,
    saveUninitialized: false
  }));

I reuse the secret from the config (which should avoid that error you got initially). the rest of the config is documented and may require specific values for your provider.

Hopefully that helps you out

davejtoews commented 6 years ago

@ccummings Thanks. That didn't work for me though. I get the same result whether this code is in app.js or authentication.js.

Sieabah commented 6 years ago

@ccummings Doesn't that mean your auth requests must be routed to the same instance?

RickEyre commented 5 years ago

Has anyone been able to solve this? I'm running into the same issue.

{ Forbidden: Unable to verify authorization request state.
    at new call (/Users/reyre/Code/example/node_modules/@feathersjs/errors/lib/index.js:107:17)
    at req.app.authenticate.then (/Users/reyre/Code/example/node_modules/@feathersjs/authentication/lib/express/authenticate.js:57:31)
    at processTicksAndRejections (internal/process/next_tick.js:81:5)
  type: 'FeathersError',
  name: 'Forbidden',
  message: 'Unable to verify authorization request state.',
  code: 403,
  className: 'forbidden',
  data: { message: 'Unable to verify authorization request state.' },
  errors: {} }

It seems like if you use a state parameter you have to be able to pass it to the authenticate call in passportjs.

RickEyre commented 5 years ago

For example, passport.authenticate('strategy', { state: true }), but I'm unsure how to get the options into that call through FeathersJS.

daffl commented 5 years ago

Feathers v4 authentication no longer uses Passport but allows to fully customize the authentication flow (including custom Passport strategies). Please see the migration guide for more information. Closing this issue in order to archive this repository. Related issues can be opened at the new code location in the Feathers main repository.