GithubHelp home page GithubHelp logo

passport-auth0's Introduction

Auth0 authentication strategy for Passport.js

The Auth0 authentication strategy for Passport.js, an authentication middleware for Node.js that can be unobtrusively dropped into any Express-based web application.

Release npm License CircleCI

๐Ÿ“š Documentation - ๐Ÿš€ Getting Started - ๐Ÿ’ฌ Feedback

Documentation

  • Docs site - explore our docs site and learn more about Auth0.

Getting started

โ„น๏ธ Maintenance Advisory: With the release of https://github.com/auth0/express-openid-connect, we will no longer be adding new features to this library, however we will continue to maintain this library and fix issues. You can read more about the release of our new library at https://auth0.com/blog/auth0-s-express-openid-connect-sdk/

Installation

The Auth0 Passport strategy is installed with npm.

npm install passport-auth0

Customization

State parameter

The Auth0 Passport strategy enforces the use of the state parameter in OAuth 2.0 authorization requests and requires session support in Express to be enabled.

If you require the state parameter to be omitted (which is not recommended), you can suppress it when calling the Auth0 Passport strategy constructor:

const Auth0Strategy = require('passport-auth0');
const strategy = new Auth0Strategy({
     // ...
     state: false
  },
  function(accessToken, refreshToken, extraParams, profile, done) {
    // ...
  }
);

More on state handling here.

Scopes

If you want to change the scope of the ID token provided, add a scope property to the authenticate configuration passed when defining the route. These must be OIDC standard scopes. If you need data outside of the standard scopes, you can add custom claims to the token.

app.get(
	'/login',
	passport.authenticate('auth0', {scope: 'openid email profile'}), 
	function (req, res) {
		res.redirect('/');
	}
);

Force a Specific IdP

If you want to force a specific identity provider you can use:

app.get(
	'/login/google',
	passport.authenticate('auth0', {connection: 'google-oauth2'}), 
	function (req, res) {
		res.redirect('/');
	}
);

If you force an identity provider you can also request custom scope from that identity provider:

app.get(
	'/login/google', 
	passport.authenticate('auth0', {
		connection: 'google-oauth2',
		connection_scope: 'https://www.googleapis.com/auth/analytics, https://www.googleapis.com/auth/contacts.readonly'
	}), 
	function (req, res) {
		res.redirect('/');
	}
);

Getting Access Tokens

If you want to specify an audience for the returned access_token you can:

app.get(
	'/login',
	passport.authenticate('auth0', {audience: 'urn:my-api'}), 
	function (req, res) {
	  res.redirect('/');
	}
);

Silent Authentication

If you want to check authentication without showing a prompt:

app.get(
	'/login',
	passport.authenticate('auth0', {prompt: 'none'}), 
	function (req, res) {
		res.redirect('/');
	}
);

Feedback

Contributing

We appreciate feedback and contribution to this repo! Before you get started, please see the following:

Raise an issue

To provide feedback or report a bug, please raise an issue on our issue tracker.

Vulnerability Reporting

Please do not report security vulnerabilities on the public GitHub issue tracker. The Responsible Disclosure Program details the procedure for disclosing security issues.


Auth0 Logo

Auth0 is an easy to implement, adaptable authentication and authorization platform. To learn more checkout Why Auth0?

This project is licensed under the MIT license. See the LICENSE file for more info.

passport-auth0's People

Contributors

abelptvts avatar alexbjorlig avatar cristiandouce avatar damieng avatar danoncall avatar davidpatrick avatar dependabot[bot] avatar dschenkelman avatar evansims avatar frederikprijck avatar gertsallaerts avatar hzalaz avatar jfromaniello avatar jimmyjames avatar joshcanhelp avatar kertof avatar kierans avatar lbalmaceda avatar luisrudge avatar lzychowski avatar machuga avatar marcinhoppe avatar nchlswtsn avatar ntotten avatar pavelvanecek avatar pose avatar siacomuzzi avatar snyk-bot avatar widcket avatar woloski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

passport-auth0's Issues

Strategy constructor mutates options argument

Description

Strategy constructor uses Object.assign(options, defaultOptions) to add OAuth2 properties to the options argument but this mutates the argument object itself, a side effect that in general should be avoided. Specifically this causes a problem if the same object is later used as an argument to the .authenticate() method because the constructor will set options.state to true by default but this is not a valid value for options.state in the .authenticate() and will cause the OAuth2 authorization code grant flow to fail.

Reproduction

  1. Create a new application with dependencies on express, express-session, passport and passport-auth0.
  2. Create the following simple app entry script:
// app.js

const express = require('express');
const session = require('express-session');
const passport = require('passport');
const Auth0Strategy = require('passport-auth0');

const sessionConfig = { secret: 'secret', resave: false };
const authConfig = {
  domain: 'DOMAIN',
  clientID: 'CLIENT_ID',
  clientSecret: 'CLIENT_SECRET',
  callbackURL: '/callback',
  successRedirect: '/',
};

const strategy = new Auth0Strategy(authConfig);
passport.use(strategy);
passport.serializeUser((user, done) => done(null, user));
passport.deserializeUser((user, done) => done(null, user));

const app = express();
app.use(session(sessionConfig));
app.use(passport.initialize());
app.use(passport.session());

app.use(
  '/',
  (req, res) => res.send(`Is authenticated? ${res.isAuthenticated()}`),
);
app.use(
  '/login',
  (req, res, next) => passport.authenticate('auth0', authConfig)(req, res, next),
);
app.use(
  '/callback',
  (req, res, next) => passport.authenticate('auth0', authConfig)(req, res, next),
);
app.use(
  '/logout',
  (req, res) => {
    req.logout();
    res.send('Logged out');
  },
);

app.listen(3000);
  1. Fill in DOMAIN, CLIENT_ID and CLIENT_SECRET with correct values.
  2. node app.js
  3. Open the browser's developer console and watch network traffic.
  4. Visit http://localhost:3000/login
  5. Note the Location header in the 302 response from the /login route. Observe that the URL has a query parameter state=true instead of the expected state=UID where UID is a 24 character nonce.
  6. Continue with authentication and note that the /callback route returns a 403 response.

Environment

  • Version of this library used: 1.2.0
  • Version of the platform or framework used, if applicable: Node 8+, Express 4
  • Other relevant versions (language, server software, OS, browser): not relevant
  • Other modules/plugins/libraries that might be involved: not relevant

BSD or MIT

package.son references BSD
README.MD references MIT

Custom User Store vs Auth0 Database

I have an app with a working login flow against an Auth0 User-Password Database. If I change the database connection to custom database in the Auth0 dashboard, req.user no longer gets set in express despite a successful authentication.

Is there anything that would need to be changed to passport for using a custom database connection?

"JavaScript heap out of memory" in /qs/lib/parse.js:70

<--- Last few GCs --->
312876625 ms: Mark-sweep 1269.1 (1403.1) -> 1269.0 (1403.1) MB, 1083.5 / 0.0 ms [allocation failure] [GC in old space requested].
312877702 ms: Mark-sweep 1269.0 (1403.1) -> 1269.0 (1403.1) MB, 1076.6 / 0.0 ms [allocation failure] [GC in old space requested].
312878768 ms: Mark-sweep 1269.0 (1403.1) -> 1269.0 (1403.1) MB, 1065.8 / 0.0 ms [last resort gc].
312879862 ms: Mark-sweep 1269.0 (1403.1) -> 1269.0 (1403.1) MB, 1093.1 / 0.0 ms [last resort gc].
<--- JS stacktrace --->
==== JS stack trace =========================================
Security context: 0x1c15735cfb39
1: parseObjectRecursive(aka parseObjectRecursive) [/app/node_modules/qs/lib/parse.js:70] [pc=0x10322d72d146] (this=0x1c1573504381 ,chain=0x3eb84daef901 <JS Array[0]>,val=0x3eb84daefd51 <String[7]: polling>,options=0x3eb84daf0479 <an Object with map 0x14ff9e204ba1>)
2: parseQueryStringKeys(aka parseQueryStringKeys) [/app/node_modules/qs/lib/parse.js:129] [pc=0x10322d72c286] (t...
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
1: node::Abort() [node]
2: 0x109b7ac [node]
3: v8::Utils::ReportApiFailure(char const*, char const*) [node]
4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [node]
5: v8::internal::Factory::NewTransitionArray(int) [node]
6: v8::internal::TransitionArray::Insert(v8::internal::Handlev8::internal::Map, v8::internal::Handlev8::internal::Name, v8::internal::Handlev8::internal::Map, v8::internal::SimpleTransitionFlag) [node]
7: v8::internal::Map::CopyReplaceDescriptors(v8::internal::Handlev8::internal::Map, v8::internal::Handlev8::internal::DescriptorArray, v8::internal::Handlev8::internal::LayoutDescriptor, v8::internal::TransitionFlag, v8::internal::MaybeHandlev8::internal::Name, char const*, v8::internal::SimpleTransitionFlag) [node]
8: v8::internal::Map::CopyAddDescriptor(v8::internal::Handlev8::internal::Map, v8::internal::Descriptor*, v8::internal::TransitionFlag) [node]
9: v8::internal::Map::CopyWithField(v8::internal::Handlev8::internal::Map, v8::internal::Handlev8::internal::Name, v8::internal::Handlev8::internal::FieldType, v8::internal::PropertyAttributes, v8::internal::Representation, v8::internal::TransitionFlag) [node]
10: v8::internal::Map::TransitionToDataProperty(v8::internal::Handlev8::internal::Map, v8::internal::Handlev8::internal::Name, v8::internal::Handlev8::internal::Object, v8::internal::PropertyAttributes, v8::internal::Object::StoreFromKeyed) [node]
11: v8::internal::LookupIterator::PrepareTransitionToDataProperty(v8::internal::Handlev8::internal::JSObject, v8::internal::Handlev8::internal::Object, v8::internal::PropertyAttributes, v8::internal::Object::StoreFromKeyed) [node]
13: v8::internal::StoreIC::UpdateCaches(v8::internal::LookupIterator*, v8::internal::Handlev8::internal::Object, v8::internal::Object::StoreFromKeyed) [node]
12: v8::internal::StoreIC::LookupForWrite(v8::internal::LookupIterator*, v8::internal::Handlev8::internal::Object, v8::internal::Object::StoreFromKeyed) [node]
14: v8::internal::StoreIC::Store(v8::internal::Handlev8::internal::Object, v8::internal::Handlev8::internal::Name, v8::internal::Handlev8::internal::Object, v8::internal::Object::StoreFromKeyed) [node]
15: v8::internal::KeyedStoreIC::Store(v8::internal::Handlev8::internal::Object, v8::internal::Handlev8::internal::Object, v8::internal::Handlev8::internal::Object) [node]
16: v8::internal::Runtime_KeyedStoreIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*) [node]
17: 0x10322d2092a7
Aborted
No newer events found at the moment. Retry.

Infinite redirect loop, "Invalid authorization request state."

I'm trying to get a basic Auth0 app running. I followed the Node example on the Auth0 dashboard but I ran into an infinite redirect loop between /login and /callback. I tried to simplify the code using the getting started example of this repo's readme, right now my routing code looks like this:

app.get('/login',
  passport.authenticate('auth0', {scope: 'openid email profile'}),
  (req, res) => res.redirect("/")
)

app.get("/callback", 
  passport.authenticate('auth0', {failureRedirect: '/login'}),
  (req, res) => {
    if(!req.user) throw new Error("user null")
    res.redirect("/")
  }
)

Everything about my setup follows the instructions I got on my Auth0 dashboard.

I did some digging and found out that /login is called twice, then /callback is called twice, then /login twice and so on and so on. I also found out that if I give the /callback's passport.authenticate a callback, it receives these arguments: null, false, {message: "Invalid authorization request state."}

Google didn't find anything meaningful when I searched for the phrase "Invalid authorization request state." and I did everything according to the docs. Any idea what I'm doing wrong?

[X] I have checked the Auth0 Community for related posts.

[X] I have checked for related or duplicate Issues and PRs.

[X] I have read the Auth0 general contribution guidelines.

[X] I have read the Auth0 Code of Conduct.

[X] I am reporting this to the correct repository (this issue might be for the base Passport library).

  • Version of passport-auth0 used: 1.1.0
  • Version of Node.js used: 10.15.3

profile is empty after succesfull authentication

Hi. Everything works but the profile i receive is almost empty, looks like this:

Profile { displayName: undefined, id: undefined, name: { familyName: undefined, givenName: undefined }, _json: {}, _raw: '{}' }

I was using passportjs with google-oauth2 and facebook strategies and works good with profile properly filled.
In the Auth0 dashboard everything looks good.

What can I try to make this work? Thanks.

Return to same page after login?

Hey
I want that in case the session cookie is expired, the user will be redirected (after re-login) to the same page he was on. Is that possible?
Thanks,
Omer

Auth0Strategy vs OAuth2Strategy

This tutorial is labelled passport-auth0, but uses OAuth2. In the readme, it mentions Auth0Strategy, but in the code is OAuth2Strategy. I'm confused. Can OAuth2 be substituted for Auth0?

could I use cookie-session instead of express-session?

Sorry I am new to this,

I am wondering if I can use cookie-session instead of express-session since JWT is supposed to not storing information in server.

I am asking because I have read a few tutorial of passport and Auth0, and it also mentioned about expression-session only.

I am facing issue with multiple instances + load balancer envrionment where after a user is login at Auth0 login page, and in /callback.

router.get('/login', authenticate('auth0', { scope: 'openid email profile' }), (req, res) => res.redirect('/'));

router.get('/callback', (req, res, next) => {
authenticate('auth0', (authErr, user) => {

  if (authErr) {
    console.error(`Error authenticating user: ${authErr}`);
    return next(authErr);
  }
  if (!user) {
    return res.redirect('/login');
  }

the user is set to false and eventually I see:

[xyzURL] redirected you too many times.
Try clearing your cookies.
ERR_TOO_MANY_REDIRECTS

Since Auth0 is using JWT, could I use cookie-session? if so, what could I do wrong?

PS.
Here is my session config:

const sessionConfig = {
  name: 'sessionId',
  domain: 'example.com',
  secret: uid.sync(18),
  secure: true,
  httpOnly: true,
  maxAge: 1800 * 1000
};

Thank you!

Jay

Specify JWT scope

Hey

Is there a way to specify the scope for JWT in order to include more details from the id_token ?

Thanks

What is the point of this line?

exports.Strategy = Strategy;

I understand the previous line exports = module.exports = Strategy, you need to repoint exports at module.exports since module.exports had its reference changed.

But what is the point of exports.Strategy = Strategy;, Is this just to give callers two ways to new up a strategy?

ex:
var auth0Strat = require('passport-auth0)
var firstStrat = new auth0Strat(.....);
var secondStrat = new auth0Strat.Strategy(......)

Generalize this! (not a movie) ;)

Hi, just a question. While I understand it from your companys view, why not write a OpenId Connect provider instead of a Auth0 specific provider. Using the discovery endpoint and so on, instead of hard coded paths to Auth0 specific urls.

That would be of more use to the community I think. Then it could be used towards any OpenId Connect provider. Or do you think most OpenId Connect providers differ to much (even though there is a standard), that it would be hard to maintain?

Register or token

How can I use this module to register new user or get token if user is already logged in

Unable to verify authorization request state.

I have not changed anything in my original set up (which worked up until last week). My auth0 strategy is as follows:

	// Perform the login
	app.get('/login',  passport.authenticate('auth0', {
	    clientID: env.AUTH0_CLIENT_ID,
	    domain: env.AUTH0_DOMAIN,
	    redirectUri: env.AUTH0_CALLBACK_URL,
	    audience: env.AUTH0_AUDIENCE,
	    responseType: 'code',
	    scope: 'openid profile'
	  }),
	  function(req, res) {
	    res.redirect('/');
	  }
	);

When a user goes to log in, they will be sent to the Auth0s authentication screen.

It lets me successfully log in to an account, however upon returning to this function:

	app.get('/authenticate', passport.authenticate('auth0', { failureRedirect: '/' }, ), 
		function(req, res) {
			console.log('called 4');			
	  	}
	);

The failure re-direct is ALWAYS called. Even though when I check my account, it reports that a successful log in has happened.

So I added the custom call-back to the above function like so:

    app.get('/authenticate', passport.authenticate('auth0', function(err, user, info) {
        console.log("authenticate");
        console.log(err);
        console.log(user);
        console.log(info);
    }, { failureRedirect: '/' }, ), 
		function(req, res) {
                    ...
	  	}
    );

Which now gives me the response:

authenticate
null
false
{ message: 'Unable to verify authorization request state.' }

What does this mean? I cannot find anywhere on the documentation or the community posts that states that on an average authentication method I would need to add a request state.

Passing hosted login page config through to Auth0?

Does anyone know how to use this strategy and pass config options to the hosted login page?

I'd like to set the initialScreen (as per the docs), but can't seem to get that working. This is what I'd expect to work:

  '/signup',
  passport.authenticate('auth0', {
    audience: `https://${env.AUTH0_DOMAIN}/userinfo`,
    responseType: 'code',
    scope: 'openid profile',
    initialPage: 'signUp',
  }),
  (req, res) => {
    res.redirect('/');
  });

I've seen a number of requests in the Community pages about this, but the responses have been fairly generic and point to documentation about the Lock & hosted login page, so I thought I'd try here.

Issues Authenticating specific Routes

Hi There. I've been trying to get this working in my project, I've got everything in the examples working, ie I can login via Auth0 and it redirects back to my callback page. My problem is that the authentication doesn't seem to work for routes - it always 302's to the login page.

passport = require 'passport'
Auth0Strategy = require 'passport-auth0'
security = require('./security')

strategy = new Auth0Strategy 
    domain:       security.auth0.domain
    clientID:     security.auth0.clientID
    clientSecret: security.auth0.clientSecret
    callbackURL:  '/callback'
, (accessToken, refreshToken, profile, done) ->
    console.log "Hit Auth0 strategy"
    done null, profile

passport.use strategy

# This is not a best practice, but we want to keep things simple for now
passport.serializeUser (user, done) -> done null, user

passport.deserializeUser (user, done) -> done null, user

app.configure ->
    app.use express.logger 'dev'
    app.set 'views', "#{__dirname}/views"
    app.engine 'jade', require('consolidate').jade
    app.set 'view engine', 'jade'

    app.use helmet.xframe(), helmet.iexss(), helmet.contentTypeOptions(), helmet.cacheControl()
    app.use express.json(), express.urlencoded()
    app.use express.methodOverride()
    app.use express.cookieParser()
    app.use express.session
        secret: security.cookieSecret
    app.use passport.initialize()
    app.use passport.session()

# Auth0 callback handler
app.get '/callback', passport.authenticate('auth0',
    failureRedirect: '/login'
), (req, res) ->
    if not req.user then throw new Error 'user null'
    console.log "hit callback"
    console.log req.user
    res.redirect "/first-login"

# This get when redirected to from the callback ALLWAYS 302's back to the login page...
app.get '/first-login', passport.authenticate('auth0'), (req, res) -> res.render 'first-login.jade'

Have I done something wrong? As far as I was aware this is the correct way of authenticating routes according to passport.js so I figured it was possibly an issue with passport-auth0.

Please, provide a TypeScript definition file for passport-auth0

I tried to search for a .d.ts file for this library but there is nothing available yet. I'm working on a TypeScript based project and a .d.ts file will be a great addition to proper use the library. Is there any possibility to provide this type definition file?

too many requests once authenticate under more than 1 instance

Infrastructure:

cloud: aws beanstalk turn on nginx for container proxy server application load balancer - https only, default process (https) 2+ instance in private subnet enabled end to end encryption following https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https-endtoend.html https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/https-singleinstance-docker.html

self-signed certificate on instance instance running docker

In local, we have a 3 container to mimic the infrastructure,

1 nginx: 443 as load balancer and https reverse proxy 2 app container: 3000:3000, 3001:3001 respectively so, not end to end encryption yet

software: autho passport (https://github.com/auth0/passport-auth0) express react

workflow: open website, click login link, it then redirect us to auth0 login page, after input username/passport, we click submit.

We are encountering "redirect too many times" when we have more than 1 instance running. The issue goes away if I turn on sticky session on the target group in aws.

We are seeing the same when trying on the local docker environment.

We are not sure why this happens, please advise and help.

Login page loop

When I login it just goes back to the login page on auth0. The auth0 strategy function never gets called. What could be happening?

var strategy = new Auth0Strategy({
   domain:       'your-domain.auth0.com',
   clientID:     'your-client-id',
   clientSecret: 'your-client-secret',
   callbackURL:  '/callback'
  },
  function(accessToken, refreshToken, extraParams, profile, done) {
    console.log('never gets called');
    return done(null, profile);
  }
);

I've verified that my callback is called from auth0, however.

Use native Object.assign instead of xtend

xtend can easily be replaced with Object.assign

This reduce the dependencies and possible also avoid duplicated versions where some package don't use the same version range for the xtend package

// immutable
Object.assign({}, a, b)

// mutable
Object.assign(a, b)

Any way to talk to multiple auth0 clients/credentials?

It seems like I can only use one strategy at a time (which contains client ID and client secret) per node instance. Is that correct or am I missing something? We'd like to fork to different auth0 clients based on our type of user. Does anyone know if that's possible w/o spinning up a different node instance?

Thanks!

Un-caught error while login

Whenever a user is trying to login for some unknown reason this uncaught error comes in play.

TokenError: Invalid authorization code
   at Strategy.OAuth2Strategy.parseErrorResponse (/app/node_modules/passport-oauth2/lib/strategy.js:320:12)
   at Strategy.OAuth2Strategy._createOAuthError (/app/node_modules/passport-oauth2/lib/strategy.js:367:16)
   at /app/node_modules/passport-oauth2/lib/strategy.js:166:45
   at /app/node_modules/oauth/lib/oauth2.js:177:18
   at passBackControl (/app/node_modules/oauth/lib/oauth2.js:123:9)
   at IncomingMessage.<anonymous> (/app/node_modules/oauth/lib/oauth2.js:143:7)
   at emitNone (events.js:85:20)
   at IncomingMessage.emit (events.js:179:7)
   at endReadableNT (_stream_readable.js:913:12)
   at _combinedTickCallback (internal/process/next_tick.js:74:11)
   at process._tickCallback (internal/process/next_tick.js:98:9)

Any help would be appreciated.

refreshToken is always null

is refresh token implemented? I'm always getting an undefined. How would I pass in the offline_access scope so that I can get a refresh token?

Strategy does not return an OIDC-compliant profile

{
  "displayName": "[email protected]",
  "name": {},
  "picture": "https://s.gravatar.com/avatar/image.png",
  "nickname": "martin",
  "_json": {
    "sub": "auth0|1234567899",
    "name": "[email protected]",
    "nickname": "martin",
    "picture": "https://s.gravatar.com/avatar/image.png",
    "updated_at": "2017-06-27T21:44:28.380Z"
  },
  "_raw": "{\"sub\":\"auth0|1234567899\",\"name\":\"[email protected]\",\"nickname\":\"martin\",\"picture\":\"https://s.gravatar.com/avatar/image.png\",\"updated_at\":\"2017-06-27T21:44:28.380Z\"}"
}

You can still access sub easily via _json but we should ideally have a p2 compliant profile.

Auth0 state parameter not always passed through

If you set the state manually, e.g. passport.authenticate('auth0', {state: 'some_state}) and then log in twice in parallel, the first request will correctly get the state passed through. The subsequent requests will all get a new random looking string, something like: g6Fo2SBZNjR2SndFQkZGQVAxS0s2MFVfVUxXQVB0MkNSdjRia6N0aWTZMmdhRm8yU0JOTTNWUlJtZEZVVFpqYVdKdlZWSTNVRmg1TTBSSmNWUTBMVU5qY0dVMFVno2NpZNkgcURNVUtTWkk5M0JlaVpJQ1A2RVZ0bk9tMUt4YTJDZlM

The specific steps to reproduce are:

  1. Initiate login on one browser tab
  2. Initiate login on a second browser tab
  3. complete login on first browser tab, note that state was passed through
  4. complete login on second browser tab, note that state was not passed through

user_id is missing in profile

Hi,

i just did the nodejs/express quickstart for auth0.
It seems like the user_id property is missing in req.user after a use authenticated.

const strategy = new Auth0Strategy(
  {
    domain: '',
    clientID: '',
    clientSecret: '',
    callbackURL: process.env.AUTH0_CALLBACK_URL || 'http://localhost:3000/callback',
    scope: 'openid profile email'
  },
  function(accessToken, refreshToken, extraParams, profile, done) {
    console.log(profile.user_id);   // This is undefined
    return done(null, profile);
  }
);

The docs about the profile clearly states that user_id is always available in the normalize profile:
https://auth0.com/docs/user-profile/user-profile-details#normalized-user-profile

This is what i get when i print out the profile object:

{
  "displayName": "Andre Uschmann",
  "name": {
    "familyName": "Uschmann",
    "givenName": "Andre"
  },
  "picture": "https://lh5.googleusercontent.com/-KymPmQzSHZA/AAAAAAAAAAI/AAAAAAAAAAA/CSvKv_F1Xy8/photo.jpg",
  "locale": "de",
  "nickname": "andre.uschmann",
  "gender": "male",
  "_json": {
    "sub": "google-oauth2|116203000818893399355",
    "name": "Andre Uschmann",
    "given_name": "Andre",
    "family_name": "Uschmann",
    "nickname": "andre.uschmann",
    "picture": "https://lh5.googleusercontent.com/-KymPmQzSHZA/AAAAAAAAAAI/AAAAAAAAAAA/CSvKv_F1Xy8/photo.jpg",
    "gender": "male",
    "locale": "de",
    "updated_at": "2017-08-02T06:45:28.070Z"
  },
  "_raw": "{\"sub\":\"google-oauth2|116203000818893399355\",\"name\":\"Andre Uschmann\",\"given_name\":\"Andre\",\"family_name\":\"Uschmann\",\"nickname\":\"andre.uschmann\",\"picture\":\"https://lh5.googleusercontent.com/-KymPmQzSHZA/AAAAAAAAAAI/AAAAAAAAAAA/CSvKv_F1Xy8/photo.jpg\",\"gender\":\"male\",\"locale\":\"de\",\"updated_at\":\"2017-08-02T06:45:28.070Z\"}"
}

It seems like the user_id is stored in profile._json.sub?
But this is nowhere mentioned in the docs.

Am i missing something?

Setting a proxy

Hi,
Is there anyway of setting a proxy for this? so all traffic goes through the proxy and then on to auth0.
Thanks for all help.
John

Custom Claims?

I'm using Auth0 - Authorization extension and I have configured groups and roles for my application.
After adding users to those groups, I'm not able to access them after authorization. The rule sets groups and roles to user metadata correctly.

Relevant piece of code is here:

app.get("/login", passport.authenticate("auth0", {
        scope: 'openid profile'
    }), function (req, res) {
        // expecting enriched req.user here, but getting basic profile information only
    });

Throwing 'failed to obtain access token' when the exchange is actually successful.

This happens recently that my back-end is throwing 'failed to obtain access token' error all over the place. I am passing an async function when initializing the strategy and that async function is called WITH the access token inside AFTER the error was thrown. I am so confused right now and basically, don't know what to do.

Auth0 authetification error

I am getting this error trying to use the authentification

throw new Error('You must provide the ' + k + ' configuration value to use passport-auth0.');
You must provide the clientID configuration value to use passport-auth0.

Not obvious how to style lock on redirect

Hi! I am using auth0 to protect https://app.unmock.io and I am having trouble styling the lock the way I would if I embedded the widget on my own page. Is there any way to pass config options via passport-auth0 (I'm using it in an express app) so that the lock can be styled on the auth0 page before being redirected to my app? Thank you!

JWT Token

In readme it's said that

extraParams.id_token has the JSON Web Token

but I can't figure it out. I need to take the JWT token of the user with profile but I can't figure out how to do it. Any help will be appreciated

userProfile error handler suppresses error message

The Error constructor only takes a single parameter, so this line suppresses errors produced by oauth2.get

  this._oauth2.get(this.options.userInfoURL, accessToken, function (err, body, res) {
    if (err) { return done(new Error('failed to fetch user profile', err)); }

Is there any reason not to just do this?

  this._oauth2.get(this.options.userInfoURL, accessToken, function (err, body, res) {
    if (err) { return done(err); }

Issue mapping Auth0 authentication result with passport-auth0

Hello,

I am using passport-auth0 (Auth0 platform authentication strategy for Passport.js) to authenticate to my Hyperledger Fabric Composer REST server which uses Passport.js auth0 authentication strategy.

I am using the following lines for starting the composer-rest-server.

export COMPOSER_CARD=admin@smartapp-bna
export COMPOSER_NAMESPACES=always
export COMPOSER_AUTHENTICATION=true
export COMPOSER_TLS=true
export COMPOSER_WEBSOCKETS=true
export COMPOSER_PROVIDERS='{
  "auth0": {
    "provider": "auth0",
    "module": "passport-auth0",
    "domain": "smartapp.auth0.com",
    "clientID": "KBVVrYYF9V19...zAFNe4Tj7NRs8Woq",
    "clientSecret": "xNGbYZXdnQpqJQGw6...kJkTjnX-9W7OzQZn3mxsA2eC_ShPyAzzYd3nsT7Fj",
    "authPath": "/auth/auth0",
    "callbackURL": "/auth/auth0/callback",
    "successRedirect": "/",
    "failureRedirect": "/"
  }
}'
composer-rest-server

Authentication through Auth0 goes fine (logs at auth0 site shows login went through), but when the callback occurs the REST Server issues the following error.

It appears that what Auth0 provides needs to be properly mapped so that the REST server knows how to use it. Any help pointing me in the right direction will be appreciated. How do I go about doing the mapping?

"ValidationError: The user instance is not valid. Details: email is invalid (value: "676f6f676c652d6f617574683...com").\n at /home/hyperuser/.nvm/versions/node/v8.10.0/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/dao.js:1247:16\n at user. (/home/hyperuser/.nvm/versions/node/v8.10.0/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/validations.js:589:13)\n at user.next (/home/hyperuser/.nvm/versions/node/v8.10.0/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/hooks.js:93:12)\n at done (/home/hyperuser/.nvm/versions/node/v8.10.0/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/validations.js:586:25)\n at /home/hyperuser/.nvm/versions/node/v8.10.0/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/validations.js:664:7\n at user. (/home/hyperuser/.nvm/versions/node/v8.10.0/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/validations.js:445:5)\n at /home/hyperuser/.nvm/versions/node/v8.10.0/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/dao.js:2111:9\n at /home/hyperuser/.nvm/versions/node/v8.10.0/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/node_modules/async/dist/async.js:1012:9\n at /home/hyperuser/.nvm/versions/node/v8.10.0/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/node_modules/async/dist/async.js:359:16\n at eachOfArrayLike (/home/hyperuser/.nvm/versions/node/v8.10.0/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/node_modules/async/dist/async.js:928:9)\n at eachOf (/home/hyperuser/.nvm/versions/node/v8.10.0/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/node_modules/async/dist/async.js:990:5)\n at _asyncMap (/home/hyperuser/.nvm/versions/node/v8.10.0/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/node_modules/async/dist/async.js:1005:5)\n at Object.map (/home/hyperuser/.nvm/versions/node/v8.10.0/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/node_modules/async/dist/async.js:995:16)\n at allCb (/home/hyperuser/.nvm/versions/node/v8.10.0/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/dao.js:2025:13)\n at /home/hyperuser/.nvm/versions/node/v8.10.0/lib/node_modules/composer-rest-server/node_modules/loopback-datasource-juggler/lib/connectors/memory.js:512:7\n at _combinedTickCallback (internal/process/next_tick.js:131:7)"

Export Strategy

Many passport modules export the strategy so you can require it like require('passport-dummyModule').Strategy, passport-auth0 should use this method as well.

logout problems

Hi

I'm using this lib with express 4. is there something special i have to do to make logout work? I don't see it in the examples and it seems like standard express stuff isn't actually working. Are there good examples of logout actually removing a session?

Rule Errors do not propagate

The following will not respect pass through any errors that come from Rules as error_description

Strategy.prototype.authenticate = function (req, options) {
  if (req.query && req.query.error) {
    return this.fail(req.query.error);
  }
  this._base.authenticate.call(this, req, options);
};

"failed to fetch user profile" after the user just registered, but user created successfully

After registration, I get:

Error: failed to fetch user profile
    at .../node_modules/passport-auth0/lib/index.js:128:28
    at passBackControl (.../node_modules/oauth/lib/oauth2.js:132:9)
    at IncomingMessage.<anonymous> (/Users/emile/github/cvrm/node_modules/oauth/lib/oauth2.js:157:7)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)

but subsequent attempts log in just fine

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.