100+ Supported Providers / OAuth Playground
23andme
| 500px
| acton
| amazon
| angellist
| appnet
| asana
| assembla
| basecamp
| beatport
| beatsmusic
| bitbucket
| bitly
| box
| buffer
| campaignmonitor
| cheddar
| coinbase
| concur
| constantcontact
| copy
| coursera
| dailymile
| dailymotion
| deezer
| delivery
| deviantart
| digitalocean
| discogs
| disqus
| dribbble
| dropbox
| echosign
| edmodo
| elance
| etsy
| eventbrite
| evernote
| everyplay
| eyeem
| facebook
| familysearch
| feedly
| fitbit
| flattr
| flickr
| flowdock
| formstack
| foursquare
| freshbooks
| geeklist
| getbase
| getpocket
| github
| gitlab
| gitter
| goodreads
| google
| harvest
| heroku
| imgur
| infusionsoft
| instagram
| jawbone
| kakao
| linkedin
| live
| mailchimp
| mapmyfitness
| meetup
| mixcloud
| moves
| myob
| odesk
| openstreetmap
| paypal
| plurk
| podio
| pushbullet
| ravelry
| rdio
| redbooth
| reddit
| runkeeper
| salesforce
| shoeboxed
| shopify
| skyrock
| slack
| slice
| smartsheet
| socrata
| soundcloud
| spotify
| square
| stackexchange
| stocktwits
| stormz
| strava
| stripe
| surveygizmo
| surveymonkey
| thingiverse
| todoist
| trakt
| traxo
| trello
| tripit
| tumblr
| twitch
| twitter
| uber
| underarmour
| upwork
| uservoice
| vend
| vimeo
| vk
| weibo
| withings
| wordpress
| wrike
| xero
| xing
| yahoo
| yammer
| yandex
| zendesk
- Providers
- Middleware
- Configuration
- Advanced Configuration
- Response Data
- Misc
- Examples
npm install grant-express
var express = require('express')
, session = require('express-session')
var Grant = require('grant-express')
, grant = new Grant({/*configuration - see below*/})
var app = express()
// REQUIRED: (any session store - see ./example/express-session)
app.use(session({secret:'grant'}))
// mount grant
app.use(grant)
npm install grant-koa
var koa = require('koa')
, session = require('koa-session')
, mount = require('koa-mount')
var Grant = require('grant-koa')
, grant = new Grant({/*configuration - see below*/})
var app = koa()
// REQUIRED: (any session store - see ./example/koa-session)
app.keys = ['grant']
app.use(session(app))
// mount grant
app.use(mount(grant))
npm install grant-hapi
var Hapi = require('hapi')
, yar = require('yar')
var Grant = require('grant-hapi')
, grant = new Grant()
var server = new Hapi.Server()
server.register([
// REQUIRED:
{
register: yar,
options: {cookieOptions: {password:'grant', isSecure:false}}
},
// register grant
{
register: grant,
options: {/*configuration - see below*/}
}
], function (err) {
server.start()
})
/connect/:provider/:override?
/connect/:provider/callback
Alternatively you can require Grant directly (each pair is identical):
// Express
var Grant = require('grant-express')
var Grant = require('grant').express()
// Koa
var Grant = require('grant-koa')
var Grant = require('grant').koa()
// Hapi
var Grant = require('grant-hapi')
var Grant = require('grant').hapi()
Koa requires two additional dependencies:
thunkify
andkoa-route
{
"server": {
"protocol": "http",
"host": "localhost:3000",
"callback": "/callback",
"transport": "session",
"state": true
},
"provider1": {
"key": "...",
"secret": "...",
"scope": ["scope1", "scope2", ...],
"callback": "/provider1/callback"
},
"provider2": {...},
...
}
- server - configuration about your server
- protocol - either
http
orhttps
- host - your server's host name
localhost:3000
|dummy.com:5000
|mysite.com
... - callback - common callback for all providers in your config
/callback
|/done
... - transport - transport to use to deliver the response data in your final callback
querystring
|session
(defaults to querystring if omitted) - state - generate random state string on each authorization attempt
true
|false
(OAuth2 only, defaults to false if omitted)
- protocol - either
- provider1 - any supported provider
facebook
|twitter
...- key -
consumer_key
orclient_id
of your app - secret -
consumer_secret
orclient_secret
of your app - scope - array of OAuth scopes to request
- callback - specific callback to use for this provider (overrides the global one specified under the
server
key) - custom_params - custom authorization parameters (see the Custom Parameters section)
- key -
(additionally any of the reserved keys can be overriden for a provider)
For redirect
URL of your OAuth application you should always use this format:
[protocol]://[host]/connect/[provider]/callback
Where protocol
and host
should match the ones from which you initiate the OAuth flow, and provider
is the provider's name from the list of supported providers.
This redirect
URL is used internally by Grant. You will receive the response data from the OAuth flow in the route specified in the callback
key of your Grant configuration.
You can add arbitrary {object}
keys inside your provider's configuration to create sub configurations that override the global settings for that provider:
// navigate to /connect/facebook
"facebook": {
"key": "...",
"secret": "...",
// by default request publish permissions
"scope": ["publish_actions", "publish_stream"],
// set specific callback route on your server for this provider
"callback": "/facebook/callback",
// navigate to /connect/facebook/groups
"groups": {
// request only group permissions
"scope": ["user_groups", "friends_groups"]
},
// navigate to /connect/facebook/pages
"pages": {
// request only page permissions
"scope": ["manage_pages"],
// additionally use specific callback route on your server for this override
"callback": "/facebook_pages/callback"
}
}
(the custom key names cannot be one of the reserved keys)
Additionally you can make a POST
request to the /connect/:provider/:override?
route to override your provider's configuration dynamically on each request:
<form action="/connect/facebook" method="post" accept-charset="utf-8">
<input name="state" type="text" value="" />
<input name="scope" type="checkbox" value="user_groups" />
<input name="scope" type="checkbox" value="manage_pages" />
<button>submit</button>
</form>
Keep in mind that in this case you'll have to mount the body-parser
middleware for Express or Koa before mounting Grant:
// express
var bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({extended:true}))
app.use(grant)
// koa
var bodyParser = require('koa-bodyparser')
app.use(bodyParser())
app.use(mount(grant))
Alternatively you can make a GET
request to the /connect/:provider/:override?
route:
app.get('/connect_facebook', function (req, res) {
// generate random state parameter on each authorization attempt
var state = (Math.floor(Math.random() * 999999) + 1)
res.redirect('/connect/facebook?state=' + state)
})
Some providers may employ custom authorization parameters outside of the ones specified in the configuration section. You can pass those custom parameters using the custom_params
option:
"google": {
"custom_params": {"access_type":"offline"}
},
"reddit": {
"custom_params": {"duration":"permanent"}
},
"trello": {
"custom_params": {"name":"my app", "expiration":"never"}
}
Additionally any custom parameter that is not a reserved key, and is listed under the
custom_parameters
array for that provider, can be defined along with the rest of the options.
Refer to the provider's OAuth documentation, and the Grant's OAuth configuration (search for custom_parameters
).
In case you have a private OAuth provider that you don't want to be part of the officially supported ones, you can define it in your configuration by adding a custom key for it.
In this case you have to specify all of the required provider keys by yourself:
{
"server": {
"protocol": "https",
"host": "mywebsite.com"
},
"mywebsite": {
"authorize_url": "https://mywebsite.com/authorize",
"access_url": "https://mywebsite.com/token",
"oauth": 2,
"key": "[CLIENT_ID]",
"secret": "[CLIENT_SECRET]",
"scope": ["read", "write"]
}
}
Take a look at the OAuth configuration to see how various providers are configured.
You can easily configure different development environments:
{
"development": {
"server": {"protocol": "http", "host": "dummy.com:3000"},
"facebook": {
"key": "development OAuth app credentials",
"secret": "development OAuth app credentials"
},
"twitter": {...}, ...
},
"staging": {
"server": {"protocol": "https", "host": "staging.mywebsite.com"},
"facebook": {
"key": "staging OAuth app credentials",
"secret": "staging OAuth app credentials"
},
"twitter": {...}, ...
},
"production": {
"server": {"protocol": "https", "host": "mywebsite.com"},
"facebook": {
"key": "production OAuth app credentials",
"secret": "production OAuth app credentials"
},
"twitter": {...}, ...
}
}
Then you can pass the environment flag:
NODE_ENV=production node app.js
And use it in your application:
var config = require('./config.json')
var grant = new Grant(config[process.env.NODE_ENV||'development'])
Once you initialize a new instance of Grant:
var grant = new Grant(require('./config'))
You get a special config
(register.config
for Hapi) property attached to that instance. It contains the generated configuration data for all of the providers defined in your config file.
In case of dynamic access to a non pre-configured provider, it is automatically added to the
config
list on first access to the/connect/:provider
route.
There is a _config
property attached as well, which contains the data from the config/oauth.json file as well as all of the configuration methods used internally by Grant.
Typically you don't want to use the
_config
property directly. Also note that changes made to theconfig
property are per Grant instance, where changes to the_config
property are global.
Very rarely you may need to override the default redirect_uri
that Grant generates for you.
For example Feedly supports only http://localhost
as redirect URL of their Sandbox OAuth application, and it won't allow the http://localhost/connect/feedly/callback
path:
"feedly": {
"redirect_uri": "http://localhost"
}
In case you override the redirect_uri
in your config, you'll have to redirect the user to the [protocol]://[host]/connect/[provider]/callback
route that Grant uses to execute the last step of the OAuth flow:
var qs = require('querystring')
app.get('/', function (req, res) {
if (process.env.NODE_ENV == 'development' &&
req.session.grant &&
req.session.grant.provider == 'feedly' &&
req.query.code
) {
res.redirect('/connect/' + req.session.grant.provider + '/callback?'
+ qs.stringify(req.query))
}
})
After that you will receive the results from the OAuth flow inside the route specified in the callback
key of your configuration.
Some providers require you to set your company name as a subdomain in the OAuth URLs. For example for Freshbooks, Shopify, Vend and Zendesk you can set that value through the subdomain
option:
"shopify": {
"subdomain": "mycompany"
}
Then Grant will generate the correct OAuth URLs:
"authorize_url": "https://mycompany.myshopify.com/admin/oauth/authorize",
"access_url": "https://mycompany.myshopify.com/admin/oauth/access_token"
Alternatively you can override the entire
request_url
,authorize_url
andaccess_url
in your configuration.
Some providers may have sandbox URLs for testing. To use them just override the entire request_url
, authorize_url
and access_url
in your configuration (notice the sandbox
bits):
"paypal": {
"authorize_url": "https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize",
"access_url": "https://api.sandbox.paypal.com/v1/identity/openidconnect/tokenservice"
},
"evernote": {
"request_url": "https://sandbox.evernote.com/oauth",
"authorize_url": "https://sandbox.evernote.com/OAuth.action",
"access_url": "https://sandbox.evernote.com/oauth"
}
Flickr uses a custom authorization parameter to pass its scopes called perms
. However you should use the regular scope
option in your configuration:
"flickr": {
"scope": ["write"]
}
For SurveyMonkey set your Mashery user name as key
and your application key as api_key
:
"surveymonkey": {
"key": "[MASHERY_USER_NAME]",
"secret": "[CLIENT_SECRET]",
"api_key": "[CLIENT_ID]"
}
To use the LinkedIn's OAuth2 flow you should use linkedin2
as provider name, instead of linkedin
which is for OAuth1:
"linkedin2": {
// then navigate to /connect/linkedin2
}
To use the Fitbit's OAuth2 flow you should use fitbit2
as provider name, instead of fitbit
which is for OAuth1.
Additionally set your client id as client_id
in custom_params
collection:
"fitbit2": {
"key": "[CLIENT_KEY]",
"secret": "[CLIENT_SECRET]",
"custom_params": { "client_id": "[CLIENT_ID]" },
}
The OAuth response data is returned as a querystring in your final callback - the one you specify in the callback
key of your Grant configuration.
Alternatively the response data can be returned in the session, see the configuration section above and the session transport example.
For OAuth1 the access_token
and the access_secret
are accessible directly, raw
contains the raw response data:
{
access_token:'...',
access_secret:'...',
raw:{
oauth_token:'...',
oauth_token_secret:'...',
some:'other data'
}
}
For OAuth2 the access_token
and the refresh_token
(if present) are accessible directly, raw
contains the raw response data:
{
access_token:'...',
refresh_token:'...',
raw:{
access_token:'...',
refresh_token:'...',
some:'other data'
}
}
In case of an error, the error
key will be populated with the raw error data:
{
error:{
some:'error data'
}
}
- Register OAuth application on your provider's web site.
- For
redirect
URL of your OAuth application always use this format:[protocol]://[host]/connect/[provider]/callback
- Create a
config.json
file containing:
"server": {
"protocol": "https",
"host": "mywebsite.com"
},
"facebook": {
"key": "[CLIENT_ID]",
"secret": "[CLIENT_SECRET]",
"callback": "/handle_facebook_response"
},
"twitter": {
"key": "[CONSUMER_KEY]",
"secret": "[CONSUMER_SECRET]",
"callback": "/handle_twitter_response"
}
- Initialize Grant and mount it:
// Express
var express = require('express')
, session = require('express-session')
var Grant = require('grant-express')
, grant = new Grant(require('./config.json'))
var app = express()
app.use(session({secret:'grant'}))
app.use(grant)
// or Koa
// or Hapi
- Navigate to
/connect/facebook
to initiate the OAuth flow for Facebook, or navigate to/connect/twitter
to initiate the OAuth flow for Twitter. - Once the OAuth flow is completed you will receive the response data in the
/handle_facebook_response
route for Facebook, and in the/handle_twitter_response
route for Twitter.
(also take a look at the examples)
Once you have your access tokens secured, you can start making authorized requests on behalf of your users. Purest is a generic REST API library that supports hundreds of REST API providers.
For example, you may want to get the user's profile after the OAuth flow has completed:
var Purest = require('purest')
, facebook = new Purest({provider:'facebook'})
, twitter = new Purest({provider:'twitter',
key:'[CONSUMER_KEY]', secret:'[CONSUMER_SECRET]'})
facebook.query()
.get('me')
.auth('[ACCESS_TOKEN]')
.request(function (err, res, body) {
// here body is a parsed JSON object containing
// id, first_name, last_name, gender, username, ...
})
twitter.query()
.get('users/show')
.qs({screen_name:'nodejs'})
.auth('[ACCESS_TOKEN]', '[ACCESS_SECRET]')
.request(function (err, res, body) {
// here body is a parsed JSON object containing
// id, screen_name, ...
})
Full list of all providers and how to get their user profile endpoint can be found here.
MIT