Coder Social home page Coder Social logo

passport-oauth2-refresh's Introduction

Passport OAuth 2.0 Refresh

An add-on to the Passport authentication library to provide a simple way to refresh your OAuth 2.0 access tokens.

Build Status npm version npm downloads per week Dependency Status

Installation

npm install passport-oauth2-refresh

Usage

When setting up your passport strategies, add a call to refresh.use() after passport.use().

An example, using the Facebook strategy:

const passport = require('passport');
const refresh = require('passport-oauth2-refresh');
const FacebookStrategy = require('passport-facebook').Strategy;

const strategy = new FacebookStrategy({
  clientID: FACEBOOK_APP_ID,
  clientSecret: FACEBOOK_APP_SECRET,
  callbackURL: "http://www.example.com/auth/facebook/callback"
},
function(accessToken, refreshToken, profile, done) {
  // Make sure you store the refreshToken somewhere!
  User.findOrCreate(..., function(err, user) {
    if (err) { return done(err); }
    done(null, user);
  });
});

passport.use(strategy);
refresh.use(strategy);

When you need to refresh the access token, call requestNewAccessToken():

const refresh = require('passport-oauth2-refresh');
refresh.requestNewAccessToken(
  'facebook',
  'some_refresh_token',
  function (err, accessToken, refreshToken) {
    // You have a new access token, store it in the user object,
    // or use it to make a new request.
    // `refreshToken` may or may not exist, depending on the strategy you are using.
    // You probably don't need it anyway, as according to the OAuth 2.0 spec,
    // it should be the same as the initial refresh token.
  },
);

Specific name

Instead of using the default strategy.name, you can setup passport-oauth2-refresh to use an specific name instead.

// Setup
passport.use('gmail', googleStrategy);

// To refresh
refresh.requestNewAccessToken('gmail', 'some_refresh_token', done);

This can be useful if you'd like to reuse strategy objects but under a different name.

Custom OAuth2 behaviour

Most passport strategies that use OAuth 2.0 should work without any additional configuration. Some strategies, however require custom OAuth configuration, or do not expose an oauth2 adapter for internal use. In these cases, a callback can be specified by calling the use function with an extra options parameter:

const { OAuth2 } = require('oauth');

refresh.use(strategy, {
  setRefreshOAuth2() {
    return new OAuth2(/* custom oauth config */);
  },
});

The setRefreshOAuth2 callback should return an instance of the node-oauth OAuth2 class.

The callback is called with two named parameters, which can be used to further customise the OAuth2 adapter:

refresh.use(strategy, {
  setRefreshOAuth2({ strategyOAuth2, refreshOAuth2 }) {
    // These named parameters are set for most strategies.
    // The `refreshOAuth2` instance is a clone of the one supplied by the strategy, inheriting most of its config.
    // Customise it here and return if necessary.
    // For example, to set a proxy:
    refreshOAuth2.setAgent(new HttpsProxyAgent(agentUrl));
    return refreshOAuth2;
  },
});

Additional parameters

Some endpoints require additional parameters to be sent when requesting a new access token. To send these parameters, specify the parameters when calling requestNewAccessToken as follows:

const extraParams = { some: 'extra_param' };
refresh.requestNewAccessToken('gmail', 'some_refresh_token', extraParams, done);

Multiple instances

Projects that need multiple instances of Passport can construct them using the Passport constructor available on the passport module. Similarly, this module provides an AuthTokenRefresh constructor that can be used instead of the single instance provided by default.

const { Passport } = require('passport');
const { AuthTokenRefresh } = require('passport-oauth2-refresh');

const passport = new Passport();
const refresh = new AuthTokenRefresh();

// Additional, distinct instances of these modules can also be created

Examples

  • See issue #1 for an example of how to refresh a token when requesting data from the Google APIs.

Why?

Passport is a library which doesn't deal in implementation-specific details. From the author:

Passport is a library for authenticating requests, and only that. It is not going to get involved in anything that is specific to OAuth, or any other authorization protocol.

Fair enough. Hence, this add-on was born as a way to help deal with refreshing OAuth 2.0 tokens.

It is particularly useful when dealing with Google's OAuth 2.0 implementation, which expires access tokens after 1 hour.

License

MIT

passport-oauth2-refresh's People

Contributors

bencmbrook avatar boutell avatar dependabot-preview[bot] avatar fiznool avatar joshhornby avatar yasharf 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

passport-oauth2-refresh's Issues

Unique instance of _oauth2

What is the reason you decided to create a new _oauth2 object rather than just getting the one from the provided strategy?

refreshOAuth2: new OAuth2 rather than refreshOAuth2: strategy._oauth2

I had to create a custom OAuth2 because MS has to do things their own way and can't use your module out of the box because of that. Am I missing something? Is there value in it being a new instance?

Looking for new maintainer

I don't use passport.js any more, and so I'm not the best person to be maintaining this repository. If anyone is interested in taking this on, please let me know and I'd be happy to transfer ownership.

Question : Multiple Strategies

Hi, I just wondered, does it work if my app has multiple OAuth strategies?

refresh.use(GoogleStrategy);
refresh.use(FacebookStrategy);

Thanks !

Specify additional parameters to the refresh request

VisualStudio Online requires a Callback URL be provided as a parameter on the refresh request. The current implementation doesn't allow for that parameter to be added.

Can a mechanism be added to specify extra parameters beyond the coded
var params = { grant_type: 'refresh_token' };

Access Token Timeout

Hi,
I'm using refresh with Google OAuth, how do you handle token timeout ?

  • Should I ask for a accessToken refresh every time ?
  • Where can I find accessToken timeout (passport only provide accessToken, refreshToken, profile)
  • I don't want to wait for an error to perform the refresh
  • Should I assume 1 hour ?

Regards

Access to raw SSO response

Hi there,

Firstly, many thanks for this library, it looks very useful ๐Ÿ™‚

In a client application of this library, I can imagine two ways of knowing when to request a new token:

  1. wait for a 401 response, request new token, re-run original request.
  2. maintain token expiry time in the local state, and when that time is past, request new token.

With the API that I am using, on refreshing a token, the SSO response includes an expiry time as well as a new token. So I would like to use method 2 (and I suspect many API maintainers would prefer 2 was used as well ๐Ÿ˜), but I can't see a way of accessing the result of the SSO response to get at this new expiry time.

Additionally, the SSO API may return a new refresh token as part of a policy of enforcing rotation of refresh tokens, so I need to get at that data as well. In any case, I think having the choice would be nice.

Perhaps I am over looking something! But any thoughts much appreciated, thanks.

Will the refresh token has the same scopes authorization?

I use the same code example as suggested in #1 to request a new access token.

My initial token has access to the following scopes ['profile', 'https://www.googleapis.com/auth/drive']. However, when using the refreshed token, the Google Drive API returns me a File Not Found: . error, which, according to https://developers.google.com/drive/v3/web/handle-errors#404_file_not_found_fileid, seems to be due to the access token not having the right access.

I'm not sure how to create a code that would reproduce this. If you have any suggestion, I could try to put together a gist.

/cc @fiznool

Inherit strategy's overwritten getOAuthAccessToken function

Some strategies overwrite the _oauth2.getOAuthAccessToken function, mostly for the purpose of custom headers (e.g. Reddit and Spotify require HTTP Basic Auth headers with the Refresh request). Here's the Reddit strategy (see line 78), and the Spotify strategy.

In this repo, the strategy._oauth.constructor from #3 still inherits the getOAuthAccessToken from the original oauth module, instead of inheriting the Strategy's overwrite. So Reddit isn't receiving the required header and is failing.

Any thoughts on how to get the strategy's version of the function to be inherited and called instead? If I figure it out I'd be happy to submit a PR.

i can not pass the accessToken out of the refresh function

var newAccessToken;
refresh.requestNewAccessToken('google', refreshToken, (err, accessToken) => {

                        if (err || !accessToken) {
                            console.log("we got error ", err);
                        } else {
                            console.log("got new token", accessToken);
                            newAccessToken = accessToken;
                        }
                        
                    });
 console.log(newAccessToken) // return undefined 

can you help me to pass access to req or outside the refresh function ?

Refresh Token undefined

I'm using passport to oAuth with google. In my callback after the user has logged in, although the parameters are: (accessToken, refreshToken, profile, done), the refreshToken is undefined while every other parameter is what it should be. Am I using the library incorrectly? Why I am not receiving a refresh token from google?

I am using the below library to define my google strategy:

'require('passport-google-oauth').OAuth2Strategy'

Behind proxy!

Because of the new refreshOAuth2: new OAuth2(...) , agentUrl isn't transferred and the Proxy setup in the strategy might be lost. Maybe you could include in the README about externally setting the AgentUrl as:

'''
oauth2strategy._oauth2.setAgent(new HttpsProxyAgent(uaaConfig.agentUrl);
'''

or accomodate it in the new OAuth2() part.

Github Refresh Token - Undefined - using passport-github2

Github Refresh Token - Undefined - using passport-github2

As commented in this "GitHub OAuth Busy Developer's Guide"

Tokens don't have to expire.

You can check an OAuth application authorization, delete it or revoke it.
But the token itself doesn't seem to be bound to an expiry date.

badsyntax adds in the comments:

I also found this useful:

"An OAuth token does not expire until the person who authorized the OAuth App revokes the token."
From "Migrating OAuth Apps to GitHub Apps".

Nest Js Support

Hello! Does anyone know how to use this package with Nest JS and is this possible?

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.