How To Use OAuth 2.0 for REST API Calls

Version 46

    The Jive REST API supports both Basic Authentication and OAuth 2.0 authentication. OAuth takes a little bit more work up front to set up, but it gives your service secure API access and doesn't require that you pass user credentials with each call.

     

    This document describes how to use the Jive REST API with OAuth 2.0 using Jive’s add-on framework.

     

     

    Overview

    oauth-flow.png

    The basic flow is:

    1. A community manager (or someone with the ability to install add-ons) must install a Jive add-on into your community. This add-on contains the registration URL that Jive will call.
    2. Jive sends registration information that includes a Jive signature, as well as a client ID & secret. (Alternatively, you can get the client id & secret manually from the UI.)
    3. You can then verify the authenticity of the source by checking the Jive signature with the Jive Global Registry.
    4. Use the client ID and secret to request an access token and refresh token.
    5. If your client ID and secret check out, Jive grants you an access token and a refresh token.
    6. Use that access token to make REST API calls.
    7. When the access token expires, use the refresh token to request additional tokens.
    8. Jive grants you additional tokens.
    9. Make additional REST API calls.

     

    The detailed instructions below elaborate on each step of this process.

     

    Detailed Instructions

     

    STEP 1a: Build a service. (Optional)

     

    You can build a simple service in order to handle the registration call so that you can acquire a client ID and secret. Jive will call your "register_url" URL that you specify in the meta.json file (see step 1b). You can use this same service to make the REST API calls, or you can use it just for registration. For some sample Node.js code, check out the Reference Material section below.

     

    Alternatively, if you do not want to build a service for this purpose, you can acquire the client ID & secret manually by clicking the action icon from the Add-ons page of your Jive community after you install the add-on. Step 2 describes this process in more detail.

     

    STEP 1b: Create an add-on.

    Note:  This step process has been baked into the Jive SDK (v 0.1.208+). 

     

         jive-sdk create oauth2-client --oauthAuthorizeUrl="YOUR_REDIRECT_URL"

     

    and the SDK will auto-setup your project and build your add-on.  See the jive-sdk help documentation for more information.

    You'll need to create a Jive Add-on in order to use OAuth. You can use the attached add-on package as a starting point. The two critical files in this package are meta.json and definition.json.

     

    meta.json

     

    This JSON file contains the following content:

     

    {
        "package_version": "1.0",
        "id": "INSERT_UUID_HERE",
        "type": "client-app",
        "name": "oauth.support",
        "description": "This add-on provides OAuth 2.0 support for the REST API",
        "minimum_version": "0070300000",
        "icon_16": "lightbulb-16.png",
        "icon_48": "lightbulb-48.png",
        "released_on": "2015-05-12T19:11:11.234Z",
        "register_url": "%serviceURL%/register",
        "unregister_url": "%serviceURL%/unregister",
        "service_url": "http://INSERT_URL_HERE"
    }
                                             

     

    You'll need to:

    • Update the "id" value with a UUID for this add-on.
    • Update the "service_url", "register_url", "unregister_url" fields as necessary. These values are the URLs to your service that you created in the previous step. If you are not using a service for registration, you can ignore these fields.
    • Add a "redirect_url" field if you're going to have the user grant authorization to the client in the OAuth authorization code grant flow.

     

    definition.json

     

    This JSON file contains the following content:

     

    {
        "integrationUser": {
            "systemAdmin": true,
            "jiveServiceSignature": "INSERT_SIGNATURE_HERE"
        }
    }
                                             

     

    You'll need to:

    • Update the "jiveServiceSignature" field with the signature that you can acquire when Creating a Signed Add-on. This will give you system admin access to this community. Alternatively, if you do not intend to sign your add-on, be sure to set "systemAdmin" to "false" and remove the "jiveServiceSignature" (along with the comma at the end of the "systemAdmin" line).

     

    STEP 1c: Install the add-on into your community.

     

    Zip up the add-on package (be sure that meta.json and definition.json are at the root level of the package — not in a subdirectory) and install it into your Jive community.

     

    STEP 2: Receive registration info from the Jive server (or manually acquire client id & secret)

     

    When you install the add-on, Jive attempts to call your service (via an HTTP POST to your "register_url" URL) with registration information. For example:

     

    {
        "clientId": "lh64648h4mwdnucakt52fe08dpnw8u41.i",
        "code": "8r2a8cxwifo4du7rahq0kppqd5xwemmc.c",
        "scope": "uri:/api",
        "tenantId": "bb6360f5-e633-4dcc-bfb4-b357459bf94e-dev",
        "jiveSignatureURL": "https://market.apps.jivesoftware.com/appsmarket/services/rest/jive/instance/validation/2193ba06-170f-4b81-b9eb-de69073603f8",
        "clientSecret": "8rpn9srrgv9p42gs4bykkcd51o6vuh0q.s",
        "jiveSignature": "suKgMCkNJ4n5g4zcNNxdKS7LdnvaMeLdbpWvE40Jc+E=",
        "jiveUrl": "http://your.jive.community.com",
        "timestamp": "2015-05-28T20:35:38.358+0000"
    }
                                                

     

    Note that you can obtain the client ID and secret manually if you do not want to run a service for registration purposes. To do this, click the action icon from the Add-ons page of your Jive community and select "View Client ID and Secret".

    clientidsecret.png

     

    STEP 3: Verify that the information came from a valid source. (Optional)

     

    If you want to ensure that this information came from a valid source, follow these instructions: Ensure Register Calls are Coming from a Genuine Jive Instance

     

    STEPS 4, 5: Request access and refresh tokens. Receive tokens from Jive.

     

    You can now make a call to your Jive community — by adding the /oauth2/token suffix to the "jiveUrl" value — and use the "clientId" and clientSecret" to request access tokens. For example:

     

    curl -u 'lh64648h4mwdnucakt52fe08dpnw8u41.i:8rpn9srrgv9p42gs4bykkcd51o6vuh0q.s'
        -d 'grant_type=password&username=INSERT_USERNAME_HERE&password=INSERT_PASSWORD_HERE'
        https://your.jive.community.com/oauth2/token
                                                

     

    Be sure to specify the desired username and password.

     

    NOTE: If you are using the Jive Developer Sandbox, the "password" grant type (specified in this example) will not work because your sandbox account is federated. You can use the "authorization_code" grant type instead. See Obtaining an Access Token using Authorization Code Grant for more information.

     

    If you specified the correct client ID and secret, Jive responds with an access token and a refresh token. For example:

     

    {
        "access_token":"qwergqefq5bad5fp03rwjwzzyh3da8vyha92wm6f.t",
        "refresh_token":"79wr2gsl32m8xgwxcxbc027fsjzn5sf0l7wrn3g3.r",
        "token_type":"bearer",
        "expires_in":"172799"
    }
                                                

     

    This access token expires in 48 hours (as specified by the "expires_in" field). When it expires, you'll need to use the refresh token to request another access token using the same "jiveUrl" from the previous step.

     

    STEP 6: Make REST API calls.

     

    You can now use the access token (in the Authorization: Bearer header) to make Jive REST API calls. For example, this call creates a new discussion:

     

    curl -X POST -i -H 'Authorization: Bearer qwergqefq5bad5fp03rwjwzzyh3da8vyha92wm6f.t'
        -H 'Content-Type: application/json' 'https://your.jive.commmunity.com/api/core/v3/contents'
        --data '{ "type": "discussion", "content": { "type": "text/html", "text":"Starting a discussion"}, "subject": "A new OAUTH discussion"}'
                                                

     

    STEPS 7, 8, 9: Use refresh token to request another access token.

     

    If you attempt to use the access token after it is expired, you'll receive a 401 response code. In order to acquire another access token, you'll need to use the refresh token provided by the Jive server earlier, along with the client ID and secret, to request additional tokens. For example:

     

    curl -u 'lh64648h4mwdnucakt52fe08dpnw8u41.i:8rpn9srrgv9p42gs4bykkcd51o6vuh0q.s'
        -d 'grant_type=refresh_token&refresh_token=79wr2gsl32m8xgwxcxbc027fsjzn5sf0l7wrn3g3.r'
        https://your.jive.community.com/oauth2/token
                    

     

    Jive responds with an additional access token and refresh token. You can once again use this access token to make Jive REST API calls.

     

     

     

    Reference Material

     

    The following Node.js code is a simple example service you could use as a starting point for your service. It listens on the /register and /unregister endpoints, and prints the body of any request to the console.

     

    var express = require('express');
    
    var app = express();
    var port = 8090;
    var registerEndpoint = 'register';
    var unregisterEndpoint = 'unregister';
    
    // Prints the payload to console and then returns a 204 response.
    function handlePayload(endpoint, req, res) {
        var body = "";
        req.on('data', function (chunk) {
            body += chunk;
        });
        req.on('end', function () {
            console.log('Payload from the '+endpoint+' endpoint:\n' + body);
            res.writeHead(204);
            res.end();
        });
    }
    
    // Handle the register request
    app.post('/'+registerEndpoint+'/', function(req, res) {
      handlePayload(registerEndpoint, req, res);
    });
    
    // Handle the unregister request
    app.post('/'+unregisterEndpoint+'/', function(req, res) {
      handlePayload(unregisterEndpoint, req, res);
    });
    
    // Listen on the specified port
    app.listen(port);
    console.log('Express server started on port ' + port);