GithubHelp home page GithubHelp logo

jaredhanson / passport-http-bearer Goto Github PK

View Code? Open in Web Editor NEW
949.0 15.0 142.0 107 KB

HTTP Bearer authentication strategy for Passport and Node.js.

Home Page: https://www.passportjs.org/packages/passport-http-bearer/?utm_source=github&utm_medium=referral&utm_campaign=passport-http-bearer&utm_content=about

License: MIT License

JavaScript 91.41% Makefile 8.59%
passport oauth2 http bearer

passport-http-bearer's Introduction

passport-http-bearer

HTTP Bearer authentication strategy for Passport.

This module lets you authenticate HTTP requests using bearer tokens, as specified by RFC 6750, in your Node.js applications. By plugging into Passport, bearer token support can be easily and unobtrusively integrated into any application or framework that supports Connect-style middleware, including Express.

🛠️ API Reference • :heart: Sponsors


Advertisement
Node.js, Express, MongoDB & More: The Complete Bootcamp 2020
Master Node by building a real-world RESTful API and web app (with authentication, Node.js security, payments & more)


npm build coverage ...

Install

$ npm install passport-http-bearer

TypeScript support

$ npm install @types/passport-http-bearer

Usage

Configure Strategy

The HTTP Bearer authentication strategy authenticates users using a bearer token. The strategy requires a verify callback, which accepts that credential and calls done providing a user. Optional info can be passed, typically including associated scope, which will be set by Passport at req.authInfo to be used by later middleware for authorization and access control.

passport.use(new BearerStrategy(
  function(token, done) {
    User.findOne({ token: token }, function (err, user) {
      if (err) { return done(err); }
      if (!user) { return done(null, false); }
      return done(null, user, { scope: 'all' });
    });
  }
));

Authenticate Requests

Use passport.authenticate(), specifying the 'bearer' strategy, to authenticate requests. Requests containing bearer tokens do not require session support, so the session option can be set to false.

For example, as route middleware in an Express application:

app.get('/profile', 
  passport.authenticate('bearer', { session: false }),
  function(req, res) {
    res.json(req.user);
  });

Issuing Tokens

Bearer tokens are typically issued using OAuth 2.0. OAuth2orize is a toolkit for implementing OAuth 2.0 servers and issuing bearer tokens. Once issued, this module can be used to authenticate tokens as described above.

Making authenticated requests

The HTTP Bearer authentication strategy authenticates requests based on a bearer token contained in the:

  • Authorization header field where the value is in the format {scheme} {token} and scheme is "Bearer" in this case.
  • or access_token body parameter
  • or access_token query parameter

Examples

For a complete, working example, refer to the Bearer example.

Related Modules

  • OAuth2orize — OAuth 2.0 authorization server toolkit

License

The MIT License

Copyright (c) 2011-2013 Jared Hanson <https://www.jaredhanson.me/>

passport-http-bearer's People

Contributors

dbgb avatar jaredhanson avatar jeroenpelgrims avatar leowinterde avatar tooshar avatar tryzniak 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

passport-http-bearer's Issues

Optional authorization

Is it possible to have endpoints with optional authorization? For example, when if bearer token is provided, we pick the corresponding user for it, if not, we let the next callback in chain to handle that, e.g. no req.user initialized. I need it for endpoints on API that return personalized results when user authorized.

Not Return Status Code 401 for API access without token

Try to access api without defining the token. The server reports property 'statusCode' assigned with 'undefined' value at 150 of passport authenticate.js. Any suggestion to fix the statement res.statusCode = rstatus || 401; if rstatus is undefined.

TypeError: Cannot set property 'statusCode' of undefined
at allFailed (/home/whtang/workspace/uc/node_modules/passport/lib/passport/middleware/authenticate.js:150:22)
at attempt (/home/whtang/workspace/uc/node_modules/passport/lib/passport/middleware/authenticate.js:231:28)
at Context.module.exports.delegate.fail (/home/whtang/workspace/uc/node_modules/passport/lib/passport/middleware/authenticate.js:226:9)
at Context.actions.fail (/home/whtang/workspace/uc/node_modules/passport/lib/passport/context/http/actions.js:35:22)
at Strategy.authenticate (/home/whtang/workspace/uc/node_modules/passport-http-bearer/lib/strategy.js:113:29)
at attempt (/home/whtang/workspace/uc/node_modules/passport/lib/passport/middleware/authenticate.js:243:16)
at Passport.authenticate (/home/whtang/workspace/uc/node_modules/passport/lib/passport/middleware/authenticate.js:244:7)
at zappa.app.route (/home/whtang/workspace/uc/node_modules/zappa/lib/zappa.js:490:34)
at callbacks (/home/whtang/workspace/uc/node_modules/zappa/node_modules/express/lib/router/index.js:272:11)
at param (/home/whtang/workspace/uc/node_modules/zappa/node_modules/express/lib/router/index.js:246:11)
at pass (/home/whtang/workspace/uc/node_modules/zappa/node_modules/express/lib/router/index.js:253:5)
at Router._dispatch (/home/whtang/workspace/uc/node_modules/zappa/node_modules/express/lib/router/index.js:280:5)
at Object.middleware as handle
at next (/home/whtang/workspace/uc/node_modules/zappa/node_modules/express/node_modules/connect/lib/http.js:204:15)
at Passport.initialize (/home/whtang/workspace/uc/node_modules/passport/lib/passport/middleware/initialize.js:69:5)
at next (/home/whtang/workspace/uc/node_modules/zappa/node_modules/express/node_modules/connect/lib/http.js:204:15)
at resume (/home/whtang/workspace/uc/node_modules/express/node_modules/connect/lib/middleware/static.js:60:7)
at SendStream.error (/home/whtang/workspace/uc/node_modules/express/node_modules/connect/lib/middleware/static.js:73:37)
at SendStream.EventEmitter.emit (events.js:95:17)
at SendStream.error (/home/whtang/workspace/uc/node_modules/express/node_modules/send/lib/send.js:147:51)
at SendStream.onStatError (/home/whtang/workspace/uc/node_modules/express/node_modules/send/lib/send.js:248:48)
at SendStream.pipe (/home/whtang/workspace/uc/node_modules/express/node_modules/send/lib/send.js:320:26)
at Object.oncomplete (fs.js:107:15)

Thanks,
Tommy Tang

Custom access token fields

Hi everyone.

Will great if you create in options properties for set custom names for access_token. We have the problem that when one token is send in headers and secons in query -> bearer is brokes up.

I can create a quick pull request for it.

can I use this in a hapi.js project

Im looking for a auth so I need to know if this can also be used in a hapi.js project and if you have some lightning to get this install I would be very happy to hear about it.

Thanks

question about the access token

it's a weird question, perhaps an easy solution, but my head is trying to wrap around it.

In facebook, you can call say: /api/1/friends without a access_token and you will get limited results. If you send the access_token, then it verifies your account, etc...

How to I wrap around the passport.authenticate function so that I an handle the error myself instead of passport doing it?

How do scopes work?

Hi Jared,

I have a hard time wrapping my head around how passport deals with scopes. Here is my scenario:

I have a token store, each token has a scope attached to it. I have some routes that only tokens with admin scope can access and others that require normal token access. In my app I would do something like this:

app.use('/v1', passport.authenticate('bearer', { session: false }):

to catch the normal case and for specific routes that require admin rights I would add something like this into the route's middleware, like
.. passport.authenticate('bearer', { session: false, scopes: ['admin']})

Is this supported by passport or do I have to do it differently?

Stops callback from running

I have a post that runs that simply logs out a phrase and whenever the passport.authenticate is authenticating the route, the callback never runs even though authentication passes.

passport-http-bearer doesn’t work with NestJS: TypeError: Class extends value undefined is not a constructor or null at PassportStrategy

I’m trying to use passport-http-bearer in my nestjs project. I need this package for my auth flow.
But passport-http-bearer seems incompatible with NestJS.

Expected behavior

The application should start without any error.

Actual behavior

When I start my application, I get the following error:

[11:36:00 AM] File change detected. Starting incremental compilation...

[11:36:01 AM] Found 0 errors. Watching for file changes.


/home/jpellat/passport-bux/node_modules/@nestjs/passport/dist/passport/passport.strategy.js:15
    class MixinStrategy extends Strategy {
                                ^
TypeError: Class extends value undefined is not a constructor or null
    at PassportStrategy (/home/jpellat/passport-bux/node_modules/@nestjs/passport/dist/passport/passport.strategy.js:15:33)
    at Object.<anonymous> (/home/jpellat/passport-bux/project-name/src/strategy.ts:4:47)
    at Module._compile (internal/modules/cjs/loader.js:1072:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10)
    at Module.load (internal/modules/cjs/loader.js:937:32)
    at Function.Module._load (internal/modules/cjs/loader.js:778:12)
    at Module.require (internal/modules/cjs/loader.js:961:19)
    at require (internal/modules/cjs/helpers.js:92:18)
    at Object.<anonymous> (/home/jpellat/passport-bux/project-name/src/app.module.ts:5:1)
    at Module._compile (internal/modules/cjs/loader.js:1072:14)

Steps to reproduce

  1. Create a nestjs project with the cli
$ npm i -g @nestjs/cli
$ nest new project-name
  1. Install dependencies npm i --save @nestjs/core @nestjs/common @nestjs/passport rxjs reflect-metadata passport-http-bearer

  2. Create the file strategy.ts in src/ directory

import { PassportStrategy } from '@nestjs/passport';
import { BearerStrategy } from 'passport-http-bearer';

export class Strategy extends PassportStrategy(BearerStrategy, 'okta') {
  constructor() {
    super();
  }

  validate(payload: string): any {
    console.log(payload);
    return payload;
  }
}
  1. Add the following lines in main.ts
import { NestFactory } from '@nestjs/core';
import * as passport from 'passport';

import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(passport.initialize());
  await app.listen(3000);
}
bootstrap();
  1. Add the new Stratgy as provider to the AppModule.ts
import { Module } from '@nestjs/common';

import { AppController } from './app.controller';
import { AppService } from './app.service';
import { Strategy } from './strategy';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService, Strategy],
})
export class AppModule {}
  1. start the application npm run start or npm run start:dev

Environment

  • Operating System: Windows 10 - WSL2 Ubuntu 20.04.3 LTS (Focal Fossa)
  • node version: v14.17.5
  • nestjs version: @nestjs/[email protected]
  • passport version:
└─┬ @nestjs/[email protected]
  └── [email protected]

How about optional AuthN

Hi, I came across the following use case and would like to discuss sensibility of this within passport auth strategies and especially this one:
Think about an API where certain read requests require AuthZ but not for all resource instances.
In this case it is up to the AuthZ layer to make the final decision.
In such an API it would be perfectly ok to issue a request without a token.
Thus it would make sense to have passport authenticating the request in presence of credentials/ tokens -- i. e. ´optional authentication´.
Currently when a strategy is set-up, it returns 401 if no AuthN info can be found.
What do you think?

Allow the ability to change the name of access_token

Allow the ability to pass in the name of the token field. This could be done exactly like the local strategy does with the username and password fields, e.g.:

passport.use(new BearerStrategy(
{accessTokenField: 'api_key'},

Token from the request body should force 'application/x-www-form-urlencoded'

https://tools.ietf.org/html/rfc6750#section-2.2

2.2. Form-Encoded Body Parameter

When sending the access token in the HTTP request entity-body, the
client adds the access token to the request-body using the
"access_token" parameter. The client MUST NOT use this method unless
all of the following conditions are met:

o The HTTP request entity-header includes the "Content-Type" header
field set to "application/x-www-form-urlencoded".

o The entity-body follows the encoding requirements of the
"application/x-www-form-urlencoded" content-type as defined by
HTML 4.01 [W3C.REC-html401-19991224].

o The HTTP request entity-body is single-part.

According to RFC6750, if the access token is sent via the entity body, seems content-type have to be checked equal to application/x-www-form-urlencoded, is this intended for this library?

MEAN.JS integration

Please can you provide example of integration.

strategies/bearer.js (new file)

 exports.signin = function(req, res, next){
    passport.authenticate('bearer', {session: false}, function(err, user, info){
        if(err || !user) {
            res.status(400).send(info);
        } else {
            // Remove sensitive data before login
            user.password = undefined;
            user.salt = undefined;
            req.login(user, function(err){
                if(err) {
                    res.status(400).send(err);
                } else {
                    res.json(user);
                }
            });
        }
    })(req, res, next);
};

Added token field to user model

Added middleware in router

app.route('/games').get(passport.authenticate('bearer', { session: false }), games.list)

Dunno what else i must do, any ideas?

Discussion: How would you recommend combining passport-http-bearer with the passport stack to secure a JSON RESTful API with oAuth bearer tokens?

I am endeavouring to put together a comprehensive CRUD prototype which you can find at https://github.com/jlchereau/Phonegap.Express and which you can currently run at http://expressjs.herokuapp.com.

I have implemented passport-http-bearer to secure API endpoints without difficulty but I couldn't figure out how to combine it with passport-oauth2 (and possibly other derived modules) to authenticate with identity providers (Facebook, Google, Windows Live, ...) and acquire tokens. So the code to acquire tokens is entirely custom as shown here and explained here.

Am I reinventing the wheel? In other words, is this something already available in the passport stack? Any suggestions/samples regarding implementation?

Does passport.authenticated provide a callback

Earlier in my application, I was simply using session based authentication with passport. For this, passport provides a method called isAuthenticated().

However, now I don't have isAuthenticated() because I'm using token based authentication. Before, I had a middleware function called ensureAuth that would check if the user is authentication by the isAuthenticated function. I don't really want to split the ensureAuth function into two - one for the passport.authorize() function and one for the small step I intend to do afterwards before moving onto the next middleware. Let me explain.

For example, my current code is like this:

ensureAuth: function(req, res, next) {  
  // authenticate using the token authentication strategy
  passport.authenticate('bearer', { session: false })
  // user object stored in req.user
  // set req.user.model as the single table inheritance model of the user (e.g. A or B)
  // (I used to do rails and some conventions stuck)
  var UserModel = app.get('Model.'+_str.capitalize(req.user.get('role')))
  req.user.role = new UserModel({ id: req.user.id })
  next();
}

and I want to do something more like this, because the example above doesn't work:

ensureAuth: function(req, res, next) {  
  // authenticate using the token authentication strategy
  passport.authenticate('bearer', { session: false }, function() {
    // user object stored in req.user
    // set req.user.model as the single table inheritance model of the user (e.g. A or B)
    var UserModel = app.get('Model.'+_str.capitalize(req.user.get('role')))
    req.user.role = new UserModel({ id: req.user.id })
    next();
  })
}

So I guess my question is: does passport.authenticated() provide a callback? I couldn't find mention of it in the documentation.

Sorry if I sound like an idiot :(

Bearer is removing attributes from req.body

The 'description' attribute is always absent/undefined, even explicitly passing it.
Just because I'm using passport.authenticate('bearer.... If I remove, it comes.

route.post('/', passport.authenticate('bearer', {session: false}), function(req, res, next){
var name = req.body.name;
var description = req.body.description;
console.log("description:", description);
if (!name || name.trim() == '') {
res.status(400).json({message:"É necessário informar o nome do papel."});
}
else if (!description || description.trim() == '') {
res.status(400).json({message:"É necessário informar a descrição do papel."});
}
else {
var role = new Role({name:name, description: description, user:req.user});
role.save().then(function(role){
res.json(role);
},next);
}
});

Is passing the bearer token in access_token still allowed?

I see this comment in strategy.js:

  • The HTTP Bearer authentication strategy authenticates requests based on
  • a bearer token contained in the Authorization header field, access_token
  • body parameter, or access_token query parameter.

This is in a project which has passport-http-bearer as dependency (version 1.0.1)- https://github.com/NodeBB/nodebb-plugin-write-api

I've tried asking the maintainer of that project but he says the following code is not his:

Strategy.prototype.authenticate = function(req) {
  var token;

  if (req.headers && req.headers.authorization) {
    var parts = req.headers.authorization.split(' ');
    if (parts.length == 2) {
      var scheme = parts[0]
        , credentials = parts[1];

      if (/^Bearer$/i.test(scheme)) {
        token = credentials;
      }
    } else {
      return this.fail(400);
    }
  }

  if (req.body && req.body.access_token) {
    if (token) { return this.fail(400); }
    token = req.body.access_token;
  }

  if (req.query && req.query.access_token) {
    if (token) { return this.fail(400); }
    token = req.query.access_token;
  }

  if (!token) { return this.fail(this._challenge()); }

  var self = this;

  function verified(err, user, info) {
    if (err) { return self.error(err); }
    if (!user) {
      if (typeof info == 'string') {
        info = { message: info }
      }
      info = info || {};
      return self.fail(self._challenge('invalid_token', info.message));
    }
    self.success(user, info);
  }

  if (self._passReqToCallback) {
    this._verify(req, token, verified);
  } else {
    this._verify(token, verified);
  }
};

Wouldn't the above code block those use of the access_token parameter?

When I try to pass the bearer token in as a query or body parameter, I get a 401 but if I pass it as an authorization header, the call works.

Any ideas how I can debug this further to figure out what is blocking the request?

Bearer / passpoet problem on upload files

Hello,

I use passport-http-bearer for my project but i have a problem with upload.
In fact, if I upload a file, it give me a 404 error if I run my App in production mode with Bearer and forever
It looks like bearer again requests the token when there is no need to since it's a session.
If i run my app with : npm start, all work fine.

Here is my code :

Login.js

BearerStrategy = require('passport-http-bearer').Strategy;
var jwt = require('jwt-simple');

function findUser(username, email, fn) {
  for (var i = 0, len = GLOBAL.config.users.length; i < len; i++) {
    var user = GLOBAL.config.users[i];
    if ((user.email === email) && user.username == username) {
      return fn(null, user);
    }
  }
  return fn(null, null);
}

module.exports = function(passport)
{

  passport.use('login', new BearerStrategy({},
    function(token, done)
    {
      process.nextTick(function () {

        var data = jwt.decode(token, 'password');

        findUser(data.username, data.email, function(err, user) {
          if (err) { return done(err); }
          if (!user) { return done(null, false); }
          return done(null, user);
        })
      });
    }
  ));   
}

init.js

var login = require('./login');
var signup = require('./signup');

module.exports = function(passport){

passport.serializeUser(function(user, done) {
  console.log("serializing " + user.username);
  done(null, user);
});

passport.deserializeUser(function(obj, done) {
  console.log("deserializing " + obj);
  done(null, obj);
});

    // Setting up Passport Strategies for Login and SignUp/Registration
    login(passport);
    signup(passport);

}

Route.js

router.post('/upload', isAuthenticated, function(req, res)
    {
        var form = new formidable.IncomingForm();
        form.uploadDir = "temp";

        form.parse(req, function(err, fields, files)
        {

            res.writeHead(200, {'content-type': 'text/plain'});
            res.write('received upload:\n\n');
            res.end(util.inspect({fields: fields, files: files}));
        });
 });

Every file I upload give me a 404 error. I am disconnected from the session.

Can you help me ?

Thank You

A few questions...

I was having a read of the angularjs newsletter this week and saw a link to this article: http://blog.auth0.com/2014/01/07/angularjs-authentication-with-cookies-vs-token/

Having looked into their implementation, I realised that it seemed much more efficient that my current "BASIC" auth method, as it didn't need to query the database for every authenticated request. The user object was stored in the token itself, so could just be passed back and forth to a stateless API server without issue.

As I was currently using Passport.js to do the BASIC auth I thought I'd have a look to see if there was a module for a token based approach, and found this. However am I right in thinking that this works in a different way; the token doesn't contain the user data? Thus, I'd still need to get the user from the database on every request?

I appreciate I may have this all wrong; authentication isn't my strong point, so I'll say thank you in advance to @jaredhanson for the great modules he's written!

Change access_token

This is a question: is there something built in to change "access_token" to something else?

App APIs using multiple accessToken passports

I think I have an odd edge case here. We are working on an iOS app using the http-bearer authentication method + trying to link facebook-token passports together.

When we make a request we would like to pass the bearer auth token to prove a user is logged in and then attach and approve a facebook-token strategy.

I noticed this library sends a 400 if you have a header token + an access_token on the body of a post.

Is this a security issue of not allowing both since 2 potential tokens could be sent? Whats the work around if any?

Custom 401 handler

Looking at current code base I don't see any way to plug-in a custom error handler when invalid bearer token provided. Would be great to have a way to customize the response, e.g. in my case I output JSON with error description..

Unable to send custom messages from passport.authenticate in route

I had implemented passport-http-bearer for authentication and upon token expiry i need to send token expired message from my rest api.For that I throw a message from BearerStrategy .But from the library it throws only 'Unauthorized' message.
`passport.use(new BearerStrategy(
function(accessToken, done) {

    AccessToken.findOne({where:{token:accessToken}}).then((token) => {
        if (!token) { 
            return done(null, false); 
        }  
        
        if( Math.round((Date.now()-token.created_at)/1000) > config.expireTime ) {
            AccessToken.destroy({where:{token: accessToken}}).catch(err =>{console.log(err);return done(err);});
            return done(null, false, { message: 'Token expired' });
        }
        User.findById(token.user_id).then((user)=>{
            if (!user) { 
                return done(null, false, { message: 'Unknown user' }); 
            }
            var info = { scope: '*' };
            done(null, user, info);
        }).catch(err => {console.log(err);return done(err); })

    }).catch(err=>{console.log(err);return done(err);});`

And the api route is
app.get(version+'/grids',passport.authenticate('bearer', { session: false }),gridsController.list);
How to get the token expired message instead of 'Unauthorized' message

OAuth 2.0 : Can't provide none user data to callback

Hey !

According to OAuth2.0 RFC we can use "access token" to authenticate a client with grant_type="client_credentials"
But passport-http-bearer is only compatible with user authentication.

Expected behavior

  • Can provide non user data in callback
  • Can provide client data in callback

Actual behavior

  • Can only provide user data in callback and it can't be set to null
  • Cannot provide client data in callback

Exemple

passport.use(new BearerStrategy(async (token, done) => {
  try {
    console.log("Authenticate Bearer",token);
    var accessToken = await db.oauthAccessTokens.findOne({
        token: token
      })
      .populate('user')
      .populate('client');

    
    if (!accessToken) throw new TokenAuthenticationError();
    console.log("accessToken",accessToken);
    if (accessToken.expires && Date.now() > accessToken.expires) throw new TokenExpiredError();
    
    var scopes = [];

    // Only authenticate USER HERE
    if(accessToken.user){
       Array.prototype.push.apply(scopes,await accessToken.user.getScopes());
       return done(null,true , {
         scopes: scopes,
       });
    }

    // Only authenticate CLIENT HERE
    if(accessToken.client) Array.prototype.push.apply(scopes,await accessToken.client.scopes);
    return done(null,null , {
         scopes: scopes,
         client: client,
    }); // "Unauthorized" because user field is set to null
    
  } catch (err) {
    done(err);
  }
}));

Is it possible to avoid challenge?

Hi!

I am using passport and the bearer strategy in one API. I think I'm having problems with getting petitions hung up because of passport trying to send me the challenge instead of an 401.

Thanks.

Should passport-http-bearer read token from session cookie?

I know it looks like a stupid question, usually a bearer token is stored in LocalStorage and send with request which contain the Authorization header field. However recently I read this article:

https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage

Above article argue that localStorage shouldn't be used because of XSS attacks and suggests using session cookie(with HttpOnly flag) to store the jwt token. This method seems to be reasonable.

in this case, javascript cannot read the cookie (which contains access_token) since HttpOnly flag is set, hence i cannot append the token in the request authorization header.

So any possible that passport-http-bearer will also read token from session cookie in future?

Integration with passport-openidconnect

Can we use the bearer tokens to pass them via header and integrate with passport-openidconnect for token introspection? Is there any working example for this? Thanks!

Question: can you access token from req later?

I am using the bearer strategy and I would like to access the token later in chain. Is that possible?

Also can you set some other objects in the verification callback? I.E. once the verification callback passes can I set some other objects to be set in the req?

Thanks.

Export version info with pkginfo

Hi Jared, small improvement.

Use the pkginfo npm to export the version in you index instead of hardcoding it like so:

require('pkginfo')(module,'version');

Setting { session: false } doesn't seem to work

I have a node/express webapp with session setup. I use connect-mongo to store the sessions in mongodb, in a collection called 'sessions'. Hitting any rest endpoints on node/express seems to create/update an entry in the sessions collection.

Two questions:

  1. I only enforce the local strategy on the /login endpoint. Why does a session get created every time an endpoint is hit? If the user isn't logged in, why does a session need to be created?
  2. I implemented a new 'bearer' strategy. Configured it so session=false. passport.authenticate('bearer', { session: false }, function(err, user, info)

This still creates a session in the mongodb. Why is that?

Authorization header

Authorization header can contain another information like Basic auth data. This case strategy does not handle.

Example:
Basic bW9iaWxlVjE6YWJjMTIzNDU2, Bearer xfDddHcepoDPIUwTlItMfVWgWo4JQTTb5R/s3xaeYk4=

Example is not working

I think it is because if new version of Express.js and its new way is creating and configuring server.

node app.js
/Users/pavelbinar/git/pavelbinar/email-analytics/passport-http-bearer/examples/bearer/app.js:76
var app = express.createServer();
                  ^
TypeError: undefined is not a function
    at Object.<anonymous> (/Users/pavelbinar/git/pavelbinar/email-analytics/passport-http-bearer/examples/bearer/app.js:76:19)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:349:32)
    at Function.Module._load (module.js:305:12)
    at Function.Module.runMain (module.js:490:10)
    at startup (node.js:124:16)
    at node.js:807:3

unable to run TypeError

Hello, i use you library with ECMAScript and babel, when i compile all ok, but when i execute i get the follow error:
.../node_modules/passport-http-bearer/lib/strategy.js:67
this._realm = options.realm || 'Users';
^

TypeError: Cannot read property 'realm' of undefined
Can you help me?

Unable to run handler function in `/:id` route

I've ran into a problem that works on a "regular" route ('/') but not on one at /:id.

passport.authenticate('bearer', { session: false }, function(err, user, info) {
if (user)
// check user's role for premium or not
if (user.role == "premium" || user.role == "editor" || user.role == "moderator" || user.role == "admin")
return ArticleModel.find(function (err, articles) {
return res.send(articles);
});
else
return ArticleModel.find(function (err, articles) {
var response = articles.filter(stripOutPremium);
return res.send(response);
});
else
// return items even if no authentication is present
return ArticleModel.find(function (err, articles) {
var response = articles.filter(stripOutPremium);
return res.send(response);
});
})(req, res, next);

Will just sit and spin forever, I get no response. I can't get the passport.authenticate('bearer'... function to run at all.

Any idea why something like this works on a simple route like app.get('/') and not app.get('/:id')?

Bearer : when invalid token, done(null,false) returns an error

Using passport-http-bearer, the done function with false as a user throws an error.
Same error if using passport-jwt

passport.use(
  new BearerStartegy(function (token, done) {
    return done(null, false, { message: "debug" });
  })
);

Expected behavior

From passport documentation :
By default, if authentication fails, Passport will respond with a 401 Unauthorized status, and any additional route handlers will not be invoked. If authentication succeeds, the next handler will be invoked and the req.user property will be set to the authenticated user.

Actual behavior

TypeError: Cannot convert undefined or null to object
GET http://localhost:8080/api/...

Environment

  • Operating System: ubuntu 21.10
  • Node version: 17.0.1
  bcryptjs: 2.4.3
  body-parser: 1.19.1
  connect-flash: 0.1.1
  cors: 2.8.5
  dotenv: 10.0.0
  ejs: 3.1.6
  express: 4.17.1
  express-oauth-jwt: 1.1.0
  express-session: 1.17.2
  jsonwebtoken: 8.5.1
  mariadb: 2.5.5
  passport: 0.5.0
  passport-http-bearer: 1.0.1
  passport-jwt: 4.0.0
  passport-local: 1.0.0

Custom handling of response on failure

Hi,
Currently, in case of failure, the passport responds either with 401, or redirect if the "failureRedirect" param is set. Is there a way of creating a custom response? E.g., sending JSON on 401 response?

I need to respond with redirect for regular requests and with something else in case of XHR requests since redirect is not an option in XHR due to CORS

I am trying something like this, but it does not work

  app.all('*', function(req, res, next) {
    return passport.authenticate('bearer', {
      session: false
    }, function(err, user, info) {
      if (err) {
        return next(err);
      }
      if (!user) {
        return res.status(401).send({<some JSON response here>});
      }
      return next();
    });
  });

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.