OAuth Client
Creating an OAuth client generates a Client ID (client_id) and Secret Key (client_secret) which are then used to generate access tokens for Nitro APIs. You can view the Secret Key for any OAuth Client you create. Secret Keys belonging to other users are hidden.
All Nitro Studio functionality that requires a token, except data import, will use the default OAuth Client. The default Client (studio) is created the first time you use a feature that requires it. Data import requires you to create an OAuth Client named batch-import that uses the batch_import scope.
Token Management Best Practices
When using web components and blocks, Bunchball recommends that you create a minimum of two OAuth clients:
- Gamification User Scope Client- this read-only client will be used for embedding in the token attribute of any web components or blocks in your program. This client requires a 3-legged token. Your token request with this client should include a userId parameter that will bind the token with the specific user session. Nitro tokens have a 24 hour expiration (86400). As long as your application user sessions are less than 24 hours, this token should not expire.
- Log Action Scope Client - this client should have a scope limited to write user actions and does not require a userId to be passed in when the token request is made. This token is valid for 24 hours (86400) and can be used for all user action logging while valid. This token should never be exposed to front-end client code. When making the log action method calls to Nitro, your application code should handle any 403 status responses by first requesting a new token and then resending the failed request with the valid token.
A new token should not be requested with each user session. Your code should 1) request a token, 2) listen for a 401 https code indicating the token is invalid, and then 3) request a new token when you receive the expiration message.
Create an OAuth Client
OAuth runs through the API Gateway and does not require or support whitelisting. They do not work together.
- Open Nitro Studio > Configuration > OAuth.
- Click New Client.
- In the Name field, enter a descriptive name.
Typically, the name identifies what you are using the OAuth client for. - If necessary, enter a Redirect Url.
The Redirect URL is used to set up a specific type of authorization that is not required by Nitro. - In the Scopes field, select the access you need.
- In the Duration (minutes) field, set the amount of time a user can access the feature using this token in one session.
- In the Maximum Duration Per Day (minutes) field, set the amount of time a user can access the feature using this token in one day.
Scope |
Access |
Use |
---|---|---|
access-token.delete |
Delete access to the access-token API. |
|
actions |
Read/write access to the actions service. |
Grants access for POST /actions. |
actions.read |
Read access to the actions data. |
Grants access for GET /actions. |
actions.write |
Write access to the actions data. |
Access needed for admins to create actions. |
analytics-settings.read |
Read access to the analytics-settings API. |
|
award-account |
Read/write access to the award-account API. |
|
award-account.read |
Read access to the award-account API. |
|
award-account.write |
Write access to the award-account API. |
|
award-transactions.read |
Read access to the award account transactions data. |
|
award-transactions-status-history.read |
Read access to the award account transactions history data. |
|
backup |
Read/write access to the backup service. Minimum access needed to back up a Nitro site. Also grants access to delete a backup. |
Grants access for GET /backup, POST /backup, PUT /backup, and DELETE /backup.
|
batch-import |
Read/write access to data import and batch import data. |
Required scope for data import. The name of the OAuth Client must be batch-import. |
blocks-configs |
Read/write access to block configuration data. |
|
blocks-configs.read |
Read access to block configuration data. |
|
challenges |
Read/write access to the challenges (missions) service. |
|
challenges.read |
Read access to missions data. |
|
challenges.write |
Write access to missions data. |
|
events |
Read/write access to the events data. |
|
events.read |
Read access to the events data. |
Grants access for GET /events used in the Events web component. |
events.write |
Write access to the events data. |
|
gamification_user |
Alias allowing common access scopes for an end user. |
Preferred scope for all end users. Requires a 3-legged token. Grants access to most /users scopes without allowing write access to points or actions. |
global |
Read/write access to all APIs. |
Requires a 2-legged token. When requesting a token with an OAuth Client that has a global scope, you will be able to use that token for reading and writing all available resources through the API. |
go_service |
Grants access to the Bunchball Go mobile site. |
Preferred scope for Bunchball Go. Grants access to services needed by Bunchball Go. |
group-classes |
Read/write access to the group classes service. |
|
group-classes.read |
Read access to the group classes service. |
|
group-classes.write |
Write access to the group classes service. |
|
group-classes/group |
Write access to be able to disassociate a group from a group class. |
|
groups |
Read/write access to the groups service. |
|
groups.read |
Read access to the groups data. |
|
groups.write |
Write access to the groups data. |
|
groups/actions |
Read/write access to group actions. |
|
groups/actions.read |
Read access to group actions. |
|
groups/actions.write |
Write access to group actions. |
|
groups/challenges |
Read/write access to group missions. |
|
groups/challenges.read |
Read access to group missions. |
|
groups/preferences.read |
Read/write access to group preferences. |
|
labels |
Read/write access to labels. |
|
labels.read |
Read access to labels. |
|
labels.write |
Write access to labels. |
|
leaderboard-layouts |
Read/write access to leaderboard layouts. |
|
leaderboard-layouts.read |
Read access to leaderboard layouts. |
|
leaderboard-layouts.write |
Write access to leaderboard layouts. |
|
leaderboards |
Read/write access to leaderboard data. |
|
leaderboards.read |
Read access to leaderboard data. |
|
leaderboards.write |
Write access to leaderboard data. |
|
levels |
Read/write access to levels. |
|
levels.read |
Read access to levels. |
|
point-categories |
Read/write access to point categories. |
|
point-categories.read |
Read access to point categories. |
|
point-categories.write |
Write access to point categories. |
|
quizzes |
Access to quiz admin functions. |
Grants access for creating, modifying, and deleting quizzes. |
quizzes.read |
Read access to quiz data, including questions and answers. |
|
quizzes.write |
Write access to quiz data. |
|
restore |
Minimum access needed to restore a Nitro site. |
Grants access for POST /restore. |
token-info.read |
Read access to the token information. |
|
uploadURLs/data-import.read |
Read access to the API endpoint to retrieve presigned URLs. |
|
users.read |
Read access to the user's search. |
|
users/actions |
Full access to the user's actions. |
|
users/actions.read |
Read access to the user's actions. |
Access needed to read user actions with the Actions API. |
users/actions.write |
Write access to the user's actions. |
This is the REST equivalent of the user.logAction method. |
users/award-balance |
Read/write access to the user's award balance. |
|
users/award-balance.read |
Read access to the user's award balance. |
|
users/award-catalog |
Read/write access to the user's award catalog. |
|
users/award-catalog.read |
Read access to the user's award catalog. |
|
users/award-country-code.read |
Read access to the user's country code. |
|
users/award-enrollment.write |
Write access to the user award account enrollment. |
|
users/award-ots |
Read/write access to the user's On The Spot award data. |
|
users/award-verification |
Read/write access to the user verification. |
|
users/award-verification.read |
Read access to the user verification. |
|
users/award-verification.write |
Write access to the user verification. |
|
users/badges |
Read/write access to the user's badges. |
|
users/badges.read |
Write access to the user's badges. |
|
users/challenges |
Write access to the user's missions. |
Grants access for GET /users when querying for a user's eligible, in progress, or completed missions. |
users/challenges.read |
Read access to the user's missions. |
|
users/change-log.read |
Read access to the users change log. |
|
users/exchanges |
Read/write access to the user's exchanges. |
|
users/exchanges.read |
Read access to the user's exchanges. |
|
user/exchanges.write |
Write access to the user's exchanges. |
|
users/groups |
Read/write access to the user's groups. |
|
users/groups.read |
Read access to the user's groups. |
|
users/groups.write |
Write access to the user's groups. |
|
users/icon |
Read/write access to the user's icon. |
|
users/icon.read |
Read access to the user's icon. |
|
users/icon.write |
Write access to the user's icon. |
|
users/id.read |
Read access to the user's data. |
|
users/id.write |
Write access to the user's data. |
|
users/interactions |
Read/write access to the user's interactions sent through the Recognitions web component. |
|
users/interactions.read |
Read access to the user's interactions sent through the Recognitions web component. |
|
users/interactions.write |
Write access to the user's interactions sent through the Recognitions web component. |
|
users/interactions-collection |
Read/write access to the user's interactions sent through the Recognitions block. |
|
users/interactions-collection.read |
Read access to the user's interactions sent through the Recognitions block. |
|
users/interactions-collection.write |
Write access to the user's interactions sent through the Recognitions block. |
|
users/leaders |
Read/write access to the leaderboard. |
|
user/levels.read |
Read access to the user's levels. |
|
users/notification-preferences |
Read/write access to the notification preference service. |
|
users/notification-preferences.read |
Read access to the notification preference service. |
|
users/notification-preferences.write |
Write access to the notification preference service. |
|
users/point-balance |
Full access to the user's point balance. |
|
users/point-balance.read |
Read access to the user's point balance. |
|
users/point-balance.write |
Write access to the user's point balance. |
|
users/points |
Deprecated. Use users/point-balance. |
|
users/points.read |
Deprecated. Use users/point-balance.read. |
|
users/points.write |
Deprecated. Use users/point-balance.write. |
|
users/points-history.read |
Deprecated. Use users/point-transactions.read. |
|
users/points-history.write |
Deprecated. Use users/point-transactions.write. |
|
users/point-transactions |
Full access to the user's point transactions. |
|
users/point-transactions.read |
Read access to the user's point transactions. |
|
users/point-transactions.write |
Write access to the user's point transactions. |
|
users/preferences |
Read/write access to the user's preferences. |
|
users/push-subscriptions.read |
Read access to the user's push subscriptions. |
|
users/push-subscriptions.write |
Write access to the user's push subscriptions. |
|
users/quizzes |
Read/write access to the user's quizzes. |
|
users/ranked-challenges |
Read/write access to ranked missions. |
|
users/self-reported-rules |
Full access to the user's self-reported rules. |
|
webhook-triggers |
Read/write access to the webhook triggers service. |
|
webhooks |
Read/write access to the webhooks data. |
|
webhooks.read |
Read access to the webhooks data. |
|
webhooks.write |
Write access to the webhooks data. |
|
widget_challenges |
Deprecated. Use widget_missions for the Missions web component. |
|
widget_events |
Minimum access needed for the Events web component. |
Preferred scope for the Events web component. Using this scope allows the OAuth Client to be flexible if Bunchball needs to evolve the scope's access over time to meet changing requirements. |
widget_interaction |
Minimum access needed for the Recognitions web component and Recognitions block. |
Preferred scope for Recognitions. Using this scope allows the OAuth Client to be flexible if Bunchball needs to evolve the scope's access over time to meet changing requirements. |
widget_missions |
Minimum access needed for the Missions web component. |
|
widget_profile |
Minimum access needed for the Profile web component. |
Preferred scope for the Profile web component. Using this scope allows the OAuth Client to be flexible if Bunchball needs to evolve the scope's access over time to meet changing requirements. |
widget_quiz |
Minimum access needed for the Quiz web component. |
Preferred scope for the Quiz web component. Using this scope allows the OAuth Client to be flexible if Bunchball needs to evolve the scope's access over time to meet changing requirements. |
widget_trophy |
Minimum access needed for the Trophy Case web component. |
Preferred scope for the Trophy Case web component. Using this scope allows the OAuth Client to be flexible if Bunchball needs to evolve the scope's access over time to meet changing requirements. |
widgets |
Read/write access to the widgets service. |
Grants access to Bunchball APIs for web component data.
|
widgets.read |
Read access to the widget's data. |
|
widgets.write |
Write access to the widget's data. |
Note: The default timezone for all duration based tokens is Eastern Standard Time (EST). Although you can define token duration for user access, this is not a recommended feature for all programs as it can limit effectiveness. A duration can be used where strict limitations are needed for compliance.
- Click Save.
Generate an OAuth Access Token
In your app, include the code to generate an OAuth token. A token is typically generated at user login. Use the client_secret and client_id from your OAuth client to acquire the token. The Client Id and Secret Key are available on the Site Settings > OAuth tab. Note: This code should not be visible to a browser.
When you request an access token without passing a user ID, you get a 2-legged token. This is typically reserved for administrative scenarios such as updating your groups. When your token request includes a user ID, you get a 3-legged token. This is necessary for a user centric experience like web components and blocks.
Access tokens with a gamification_user scope require a 3-legged token and tokens with a global scope require a 2-legged token. Access will be denied if the token does not meeting the security requirements.
OAuth Request Example
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=client_credentials&client_id=<client_id>&client_secret=<client_secret>&xoauth_end_user_id=<user_id>" "https://api.bunchball.com/oauth/token" |
<?php
class Nitro {
/**
* Generate an access token
*
* @param $clientId : OAuth client ID (string | required)
* @param $clientSecret : OAuth client secret (string | required)
* @param $threeLegToken : Generate 3 leg token when true (bool | optional)
* @param $userId : User ID to pass in (string | optional)
*/
public function makeOAuthToken($clientId, $clientSecret, $threeLegToken = false, $userId = ''){
$endpoint = "https://api.bunchball.com/oauth/token/";
$headers = ['Content-Type: application/x-www-form-urlencoded'];
$data = "grant_type=client_credentials&client_id=".$clientId."&client_secret=".$clientSecret;
if($threeLegToken){
$data .= "&xoauth_end_user_id:" . $userId;
}
$response = $this->executePost($endpoint, $data, $headers);
return $response;
}
/**
* Execute URL (POST)
*
* @param $url : URL to be passed in (String | Required)
* @param $data : Post data to send (Array | Required)
* @param $headers : Headers to send with request (Array | Optional)
*/
public function executePost($url, $data, $headers = []){
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $this->response = $response;
}
}
Would be used as:
<?php
require_once('path/to/Nitro.php');
$clientId = '<CLIENT_ID>';
$clientSecret = '<CLIENT_SECRET>';
$userLoginId = '<USER_ID>';
$nitro = new Nitro();
//Generate three legged token
$threeLeggedToken = $nitro->makeOAuthToken($clientId, $clientSecret, true, $userLoginId);
//Generate two legged token
$twoLeggedToken = $nitro->makeOAuthToken($clientId, $clientSecret);
var request = require('request'); //Using request module for post request
"use strict";
module.exports = class NitroOauth{
constructor(client, secret){
this.client = client;
this.secret = secret;
this.endpoint = 'https://api.bunchball.com';
}
makeToken(userId = ''){
return new Promise((resolve) => {
let data = {
grant_type: "client_credentials",
client_id: this.client,
client_secret: this.secret,
};
if(userId){ //If userID is passed in generate a three legged token
data.xoauth_end_user_id = userId;
}
let options = {
form: data,
json: true,
}
request.post(this.endpoint+'/oauth/token/', options,
function(err, resp, body){
resolve(body);
});
});
}
}
Would be used as:
var NitroOauth = require('path/to/NitroOauth');
var client = '<CLIENT_ID>';
var secret = '<CLIENT_SECRET>';
var userId = '<USER_ID>';
var nitro = new NitroOauth(client, secret);
//Generate three legged token
nitro.makeToken(userId)
.then(result =>{
console.log(result);
})
.catch((error) => {
console.log(error);
});
//Generate 2 legged token
nitro.makeToken()
.then(result =>{
console.log(result);
})
.catch((error) => {
console.log(error);
});
Response
{
"token_type": "bearer",
"access_token": "5a2ccdee047515c1a8",
"expires_in": 86400
}
See also