Bell Providers
If you want to write your own provider please see the section at the bottom of this page.
Existing Providers
Each provider may specify configuration options that are unique. Any of these unique options are documented here and must be provided during strategy creation. See the API Documentation for all other options.
ArcGIS Online
scope: No default scopeconfig: not applicableauth: https://www.arcgis.com/sharing/rest/oauth2/authorizetoken: https://www.arcgis.com/sharing/rest/oauth2/token
The default profile response will look like this:
credentials.profile = {
provider: 'arcgisonline',
orgId: profile.orgId,
username: profile.username,
displayName: profile.fullName,
name: {
first: profile.firstName,
last: profile.lastName,
},
email: profile.email,
role: profile.role,
raw: profile,
};Auth0
scope: Defaults to['openid', 'email', 'profile']config:domain: Your Auth0 domain name, such asexample.auth0.comorexample.eu.auth0.com
auth: /authorizetoken: /oauth/token
To create a token for a specific endpoint, add it to the providerParams and tokenParams options, eg.:
providerParams: {
endpoint: 'https://api.service.com'
},
tokenParams: {
endpoint: 'https://api.service.com'
}To authenticate a user with a specific identity provider directly, use providerParams. For example:
providerParams: {
connection: 'Username-Password-Authentication';
}The default profile response will look like this:
credentials.profile = {
id: profile.user_id,
email: profile.email,
displayName: profile.name,
name: {
first: profile.given_name,
last: profile.family_name,
},
raw: profile,
};Specific fields may vary depending on the identity provider used. For more information, refer to the documentation on user profiles.
Bitbucket
scope: not applicableconfig: not applicableauth: https://bitbucket.org/site/oauth2/authorizetoken: https://bitbucket.org/site/oauth2/access_token
The default profile response will look like this:
credentials.profile = {
id: profile.uuid,
username: profile.username,
displayName: profile.display_name,
raw: profile,
};Cognito
scope: Defaults to['openid', 'email', 'profile']config:uri: Point to your Cognito user pool uri. Intentionally no default as Cognito is organization specific.
auth: https://your-cognito-user-pool.amazoncognito.com/oauth2/authorizetoken: https://your-cognito-user-pool.amazoncognito.com/oauth2/token
The default profile response will look like this:
credentials.profile = {
id: profile.sub,
username: profile.preferred_username,
displayName: profile.name,
firstName: profile.given_name,
lastName: profile.family_name,
email: profile.email,
raw: profile,
};DigitalOcean
scope: defaults toreadscopeconfig: not applicableauth: https://cloud.digitalocean.com/v1/oauth/authorizetoken: https://cloud.digitalocean.com/v1/oauth/token
The default profile response will look like this:
credentials.profile = {
id: profile.account.uuid,
email: profile.account.email,
status: profile.account.status,
dropletLimit: profile.account.droplet_limit,
raw: profile.account,
};Discord
scope: Defaults to['email', 'identify']config: not applicableauth: https://discord.com/api/oauth2/authorizetoken: https://discord.com/api/oauth2/token
The default profile response will look like this:
credentials.profile = {
id: profile.id,
discriminator: profile.discriminator,
username: profile.username,
email: profile.email,
mfa_enabled: profile.mfa_enabled,
verified: profile.verified,
avatar: {
id: profile.avatar,
url:
'https://discord.com/api/users/' +
profile.id +
'/avatars/' +
profile.avatar +
'.jpg',
},
raw: profile,
};Dropbox
scope: No default scopeconfig: not applicableauth: https://www.dropbox.com/1/oauth2/authorizetoken: https://api.dropbox.com/1/oauth2/token
The default profile response will look like this:
// default profile response from dropboxFacebook
scope: Defaults to['email']config:fields: List of profile fields to retrieve, as described in Facebook's documentation. Defaults to'id,name,email,first_name,last_name,middle_name,gender,link,locale,timezone,updated_time,verified'.
auth: https://www.facebook.com/v3.1/dialog/oauthtoken: https://graph.facebook.com/v3.1/oauth/access_token
The default profile response will look like this:
credentials.profile = {
id: profile.id,
username: profile.username,
displayName: profile.name,
name: {
first: profile.first_name,
last: profile.last_name,
middle: profile.middle_name,
},
email: profile.email,
raw: profile,
};Fitbit
scope: Defaults to['activity', 'profile']config: not applicableauth: https://www.fitbit.com/oauth2/authorizetoken: https://api.fitbit.com/oauth2/token
The default profile response will look like this:
credentials.profile = {
id: profile.user.encodedId,
displayName: profile.user.displayName,
name: profile.user.fullName,
};Foursquare
scope: No default scopeconfig: not applicableauth: https://foursquare.com/oauth2/authenticatetoken: https://foursquare.com/oauth2/access_token
The default profile response will look like this:
credentials.profile = {
id: profile.id,
displayName: profile.firstName + ' ' + profile.lastName,
name: {
first: profile.firstName,
last: profile.lastName,
},
email: profile.contact.email,
raw: profile,
};Github
scope: Defaults to['user:email']config:uri: Point to your github enterprise uri. Defaults tohttps://github.com.
auth: /login/oauth/authorizetoken: /login/oauth/access_token
The default profile response will look like this:
credentials.profile = {
id: profile.id,
username: profile.login,
displayName: profile.name,
email: profile.email,
raw: profile,
};GitLab
scope: No default scope.config:uri: Point to your gitlab uri. Defaults tohttps://gitlab.com.
auth: /oauth/authorizetoken: /oauth/token
The default profile response will look like this:
// Defaults to gitlab response (https://gitlab.com/help/api/users.md#current-user)Google
scope: Defaults to['profile', 'email']config: not applicableauth: https://accounts.google.com/o/oauth2/v2/authtoken: https://www.googleapis.com/oauth2/v4/token
The default profile response will look like this:
credentials.profile = {
id: profile.id,
displayName: profile.name,
name: {
given_name: profile.given_name,
family_name: profile.family_name,
},
email: profile.email,
raw: profile,
};Google Plus
You must also enable the Google+ API in your profile. Go to APIs & Auth, then APIs and under Social APIs click Google+ API and enable it.
scope: Defaults to['profile', 'email']config: not applicableauth: https://accounts.google.com/o/oauth2/v2/authtoken: https://www.googleapis.com/oauth2/v4/token
The default profile response will look like this:
credentials.profile = {
id: profile.id,
displayName: profile.displayName,
name: profile.name,
emails: profile.emails,
raw: profile,
};Instagram
scope: Defaults to['basic']config:extendedProfile: Boolean that determines if extended profile information will be fetched
auth: https://api.instagram.com/oauth/authorizetoken: https://api.instagram.com/oauth/access_token
The default profile response will look like this:
credentials.profile = {
id: params.user.id,
username: params.user.username,
displayName: params.user.full_name,
raw: params.user,
};
// if extendedProfile is true then raw will have access to all the informationLinkedIn
scope: Defaults to['r_basicprofile', 'r_emailaddress']config: not applicableauth: https://www.linkedin.com/uas/oauth2/authorizationtoken: https://www.linkedin.com/uas/oauth2/accessToken
The default profile response will look like this:
credentials.profile = {
id: profile.id,
name: {
first: profile.firstName,
last: profile.lastName,
},
email: profile.email,
headline: profile.headline,
raw: profile,
};You can request additional profile fields by setting the fields option of providerParams. All possible fields are described in the Basic Profile Fields documentation (see an example on this page under Requesting additional profile fields).
Here is an example of a custom strategy configuration:
providerParams: {
fields: ':(id,first-name,last-name,positions,picture-url,picture-urls::(original),email-address)';
}Medium
scope: Defaults to['basicProfile']config: not applicableauth: https://medium.com/m/oauth/authorizetoken: https://medium.com/v1/tokens
The default profile response will look like this:
credentials.profile = {
id: profile.data.id,
username: profile.data.username,
displayName: profile.data.name,
raw: profile.data,
};Meetup
scope: Defaults to['basic']config: not applicableauth: https://secure.meetup.com/oauth2/authorizetoken: https://secure.meetup.com/oauth2/access
The default profile response will look like this:
// Defaults to meetup response (http://www.meetup.com/meetup_api/docs/2/member/#get)Microsoft Live
scope: Defaults to['wl.basic', 'wl.emails']config: not applicableauth: https://login.live.com/oauth20_authorize.srftoken: https://login.live.com/oauth20_token.srf
The default profile response will look like this:
credentials.profile = {
id: profile.id,
username: profile.username,
displayName: profile.name,
name: {
first: profile.first_name,
last: profile.last_name,
},
email: profile.emails && (profile.emails.preferred || profile.emails.account),
raw: profile,
};Nest
scope: No default scopeconfig: not applicableauth: https://home.nest.com/login/oauth2token: https://api.home.nest.com/oauth2/access_token
The default profile response will look like this:
// According to the official docs, no user data is available via the Nest
// OAuth service. Therefore, there is no `profile`.Phabricator
scope: Defaults to['whoami']config:uri: URI of phabricator instance
auth: /oauthserver/auth/token: /oauthserver/token/
The default profile response will look like this:
credentials.profile = {
id: profile.result.phid,
username: profile.result.userName,
displayName: profile.result.realName,
email: profile.result.primaryEmail,
raw: profile,
};Pingfed
scope: Defaults to['openid', 'email']config:uri: Point to your Pingfederate enterprise uri. Intentionally no default as Ping is organization specific.
auth: https://www.example.com:9031/as/authorization.oauth2token: https://www.example.com:9031/as/token.oauth2
The default profile response will look like this:
credentials.profile = {
id: profile.sub,
username: profile.email,
displayName: profile.email,
email: profile.email,
raw: profile,
};Pinterest
scope: Defaults to['read_public', 'write_public', 'read_relationships', 'write_relationships']config: not applicableauth: https://api.pinterest.com/oauth/token: https://api.pinterest.com/v1/oauth/token
The default profile response will look like this:
credentials.profile = {
id: profile.data.id,
username: profile.data.username,
name: {
first: profile.data.first_name,
last: profile.data.last_name,
},
raw: profile,
};Reddit
scope: Defaults to['identity']config: not applicableauth: https://www.reddit.com/api/v1/authorizetoken: https://www.reddit.com/api/v1/access_token
The default profile response will look like this:
// Defaults to reddit responseSlack
scope: Defaults to['identify']config:extendedProfile: Set tofalseif all you want is theaccess_token, withoutuser_id,user,raw, etc...
auth: https://slack.com/oauth/authorizetoken: https://slack.com/api/oauth.access
To authenticate user in a specific team, use providerParams. For example:
providerParams: {
team: 'T0XXXXXX';
}The default profile response will look like this:
credentials.profile = {
scope: params.scope,
access_token: params.access_token,
user: params.user,
user_id: params.user_id,
};
// credentials.profile.raw will contain all of the keys sent by Slack for the `auth.test` methodSpotify
scope: Defaults to-allowing to read the public information only. Spotify Scopesauth: https://accounts.spotify.com/authorizetoken: https://accounts.spotify.com/api/token
Read more about the Spotify Web API's Authorization Flow here: https://developer.spotify.com/web-api/authorization-guide/
The default profile response will look like this:
credentials.profile = {
id: profile.id,
username: profile.id,
displayName: profile.display_name,
email: profile.email,
raw: profile,
};trakt.tv
scope: not applicableconfig: not applicableauth: https://api.trakt.tv/oauth/authorizetoken: https://api.trakt.tv/oauth/token
The default profile response will look like this:
credentials.profile = {
username: profile.username,
private: profile.private,
joined_at: profile.joined_at,
name: profile.name,
vip: profile.vip,
ids: profile.ids,
location: profile.location,
about: profile.about,
gender: profile.gender,
age: profile.age,
images: profile.images,
};Twitter
scope: not applicableconfig:extendedProfile: Request for more profile informationgetMethod: Twitter API GET method to call whenextendedProfileis enabled. Defaults to'users/show'getParams: Additional parameters to pass to the GET method. For example, theinclude_emailparameter for theaccount/verifyroute
temporary: 'https://api.twitter.com/oauth/request_token'auth: https://api.twitter.com/oauth/authenticatetoken: https://api.twitter.com/oauth/access_token
The default profile response will look like this:
credentials.profile = {
id: params.user_id,
username: params.screen_name,
};
// credentials.profile.raw will contain extendedProfile if enabledVk
scope: No default scopeconfig: not applicableauth: https://oauth.vk.com/authorizetoken: https://oauth.vk.com/access_token
The default profile response will look like this:
credentials.profile = {
id: profile.uid,
displayName: profile.first_name + ' ' + profile.last_name,
name: {
first: profile.first_name,
last: profile.last_name,
},
raw: profile,
};Yahoo
scope: not applicableconfig: not applicabletemporary: https://api.login.yahoo.com/oauth/v2/get_request_tokenauth: https://api.login.yahoo.com/oauth/v2/request_authtoken: https://api.login.yahoo.com/oauth/v2/get_token
The default profile response will look like this:
credentials.profile = {
id: profile.profile.guid,
displayName: profile.profile.givenName + ' ' + profile.profile.familyName,
name: {
first: profile.profile.givenName,
last: profile.profile.familyName,
},
raw: profile,
};Tumblr
scope: not applicabletemporary: https://www.tumblr.com/oauth/request_tokenauth: https://www.tumblr.com/oauth/authorizetoken: https://www.tumblr.com/oauth/access_token
The default profile response will look like this:
credentials.profile = {
username: profile.response.user.name,
raw: profile.response.user,
};Twitch
scope: Defaults to'user_read'auth: https://api.twitch.tv/kraken/oauth2/authorizetoken: https://api.twitch.tv/kraken/oauth2/token
The default profile response will look like this:
// default profile response from TwitchSalesforce
scope: not applicableconfig:uri: Point to your Salesforce org. Defaults tohttps://login.salesforce.comextendedProfile: Request for more profile information. Defaults to trueidentityServiceProfile: Determines if the profile information fetch uses the Force.com Identity Service. Defaults to false (UserInfo Endpoint)
auth: /services/oauth2/authorizetoken: /services/oauth2/token
The default profile response will look like this: UserInfo Response
credentials.profile = {
"sub": "https://login.salesforce.com/id/00Dx0000000A9y0EAC/005x0000000UnYmAAK",
"user_id": "005x0000000UnYmAAK",
"organization_id": "00Dx0000000A9y0EAC",
"preferred_username": "user@ example.com",
"nickname": "user",
"name": "Pat Patterson",
"email": "user@ example.com",
"email_verified": true,
"given_name": "Pat",
"family_name": "Patterson",
...
}The Force.com Identity profile response will look like this: Force.com Identity Response
credentials.profile = {
"id":"https://login.salesforce.com/id/00D50000000IZ3ZEAW/00550000001fg5OAAQ",
"asserted_user":true,
"user_id":"00550000001fg5OAAQ",
"organization_id":"00D50000000IZ3ZEAW",
"username":"user@ example. com",
"nick_name":"user1.2950476911907334E12",
"display_name":"Sample User",
"email":"user@ example. com",
"email_verified": true,
"first_name": "Sample",
"last_name": "User",
...
}Stripe
scope: defaults toread_onlyscopeconfig: not applicableauth: https://connect.stripe.com/oauth/authorizetoken: https://connect.stripe.com/oauth/token
The default profile response will look like this:
credentials.profile = {
id: profile.id,
legalName: profile.business_name,
displayName: profile.display_name,
email: profile.email,
raw: profile,
};Office 365
scope: Defaults to['openid','offline_access', 'profile']config: not applicableauth: https://login.microsoftonline.com/common/oauth2/v2.0/authorizetoken: https://login.microsoftonline.com/common/oauth2/v2.0/token
The default profile response will look like this:
credentials.profile = {
id: profile.Id,
displayName: profile.DisplayName,
email: profile.EmailAddress,
raw: profile,
};Okta
scope: Defaults to['openid', 'email', 'offline_access']config:uri: Point to your Okta enterprise uri. Intentionally no default as Okta is organization specific.authorizationServerId: If you are using a custom authorization server you need to pass the alphanumeric ID here.
auth: https://your-organization.okta.com/oauth2/v1/authorizetoken: https://your-organization.okta.com/oauth2/v1/token
The default profile response will look like this:
credentials.profile = {
id: profile.sub,
username: profile.email,
displayName: profile.nickname,
firstName: profile.given_name,
lastName: profile.family_name,
email: profile.email,
raw: profile,
};WordPress
scope: Defaults to'global'auth: /oauth2/authorizetoken: /oauth2/token
The default profile response will look like this:
credentials.profile = {
id: profile.ID,
username: profile.username,
displayName: profile.display_name,
raw: profile,
};Writing a new provider
When writing a new provider see existing implementations (in lib/providers) for reference as well as any documentation provided by your provider. You may want to support uri or extendedProfile options depending on your needs.