Experimenting with OAuth Integrations
This tutorial demonstrates how to perform Webex OAuth2 authentication for a Webex Integration.
anchorObjectives
anchor- Sign up for Webex - take a tour!
- Register a new custom Webex Integration type application with Cisco
- Walk-through a sample application demonstrating how to authenticate with the Webex OAuth2 API from a browser-based JavaScript application
Download the complete sample code project for this tutorial on GitHub.com CiscoDevNet/webex-teams-auth-sample
anchorOverview
anchorWebex is a cloud service providing persistent chat, room-based collaboration, WebRTC video conferencing, and more. Developers can easily integrate solutions with Webex via the Webex REST API - for example to add Webex messaging features to an app user interface, or to automate sending Webex messages to rooms based on business system or real-world events.
Application developers integrating with Webex that wish to use OAuth/SSO for authenticating users and performing API requests on their behalf must register their app via the Cisco Developer Portal portal - defining the application name, permissions, and OAuth2 redirect URL (more on this later). During registration, the system generates a Client ID and Client Secret pair, which are later used by the application to access the Webex OAuth2 authentication service. During this tutorial, you will create a new custom app registration, and generate a Client ID and Secret.
In this tutorial, we will examine a small sample HTML/JavaScript application that demonstrates how to perform a Webex OAuth2 authentication. We'll walk through some of the key concepts and code details, then use the app to generate a Webex API access token.
anchorStep 1: Sign up for Webex and take a tour
anchorIf you already have a Webex account, skip to Step 2.
Sign-up for a Webex account.
Note: you will need to access your email account, as Webex will send a 'You have a Cisco Webex account' email message with a 'Create Password' verification link - this must be completed in order to login to Webex.Log in to Webex and take a quick look around. Feel free to create a new space and invite a friend (note: they will need to complete the email verification step too.)
For more information on Webex features and benefits, check out: https://www.webex.com/team-collaboration.html
anchorStep 2: Registering a custom Webex integration
anchorWebex developers can define new integrated applications by logging into the Webex Developer Portal and providing a couple of details. Creating an app registration accomplishes a few things:
- Generates a unique application Client ID and Client Secret, needed to access the Webex authentication service
- Identifies the application's defined scopes (Webex service permissions)
- Specifies a Redirect URI for the application, where Webex OAuth2 authentication responses will be sent
For more details on Webex OAuth2 authentication, see Developer Portal - Apps & OAuth
- Determine the app's Redirect URI. The Webex OAuth2 flow will redirect the user's browser to a number of different sites and URLs during the authentication sequence. When complete, Webex will need a way to send the browser back to the custom web app (with the OAuth2 authentication code attached.) This is done by specifying a unique Redirect URL URL which points back to the web application. In our case, the URL for the web page itself will be re-used as the Redirect URI:
- Open the sample app in a new tab
- Copy the Redirect URI field value to the clipboard (the sample app detects this URL automatically)
- Navigate to the Developer Portal application registration page:
- Open a new browser tab, and navigate to the Developer Portal page.
- If you like, click Go to Docs and take a tour of the Webex API docs.
- Log in.
- Once logged in, click on your avatar and select My Webex Apps.
- In the Create a new App page, click Create an Integration.
- Complete the New Integration form with the following details, and then click Add Integration:
- Integration Name - Enter any application name you like (e.g., 'test app').
- Icon - Upload an icon image or choose one of the defaults (note the size requirements).
- Description - Enter any description you like.
- Redirect URI(s)s - Paste or enter the Redirect URI that was displayed in the sample app (see above).
- Scopes - Check the scope:
spark:rooms_read
.
- Check the confirmation message, and note your application's generated Client ID, Client Secret, and the OAuth Authorization URL. You will use these later to perform the Webex authentication request. You can use this note-box page to copy/paste into temporarily.
Note: For production apps, record your Client ID and Client Secret in a safe place. The Client Secret will not be displayed again (though you can generate a new one).
anchorStep 3: Exploring the Webex sample oauth app code
anchorThe complete sample code for this project is available on GitHub: CiscoDevNet/webex-teams-auth-sample
Let's take a look at the source code of the sample app, and see how it works:
- Open the sample code on GitHub
To complete the Webex authentication sequence, the application performs three main steps:
- Builds an auth code request URL for the Webex OAuth2
/authorize
service by concatenating your app's registration details, the requested Webex API permission scopes, and some other fixed fields. The app then redirects the browser to the auth code URL, where the user interactively logs in to Webex:
//Build the request URL. The base URL and next 4 items are typically always the same for Webex web apps
var requestUrl = 'https://webexapis.com/v1/authorize?' + //Webex OAuth2 base URL
'response_type=code&' + // Requesting the OAuth2 'Authentication Code' flow
'scope='+ encodeURIComponent('spark:rooms_read') + '&' + // Requested permission, i.e. Webex room info
// The following items are provided by the developer in the source code/config or generated dynamically at run time
'state=' + encodeURIComponent(randomString(63)) + '&' + // Random string for OAuth2 nonce replay protection
'client_id=' + encodeURIComponent(appClientId) + '&' + // The custom app Client ID
'redirect_uri=' + encodeURIComponent(appRedirectUri); // The custom app's Redirect URI
window.location = requestUrl; // Redirect the browser to the OAuth2 kickoff URL
- After Webex authenticates the user, the service redirects the browser back to the application's registered Redirect URI (in this case, the same URL as the original sample app page) attaching the requested OAuth2 auth code as a URL parameter. When the page's
window.onload
event fires, it checks for the presence of the auth code URL parameter, and displays it in the 'Auth Code' input field:
var params = parseQueryStr(window.location.search.substring(1)); // Parse the query string params into a dictionary
if (params['code']) { // If the query param 'code' exists, then...
document.getElementById('code').value = params['code']; // Display the auth code
document.getElementById('tokenButton').removeAttribute('hidden'); // Reveal the 'Request Access Token' button
}
- Finally, the app creates a JavaScript XMLHttpRequest object, builds a JSON request object (which includes the obtained auth code), the app Redirect URI, and some other fixed fields. It then submits the request to the Webex
/access_token
service to exchange for a Webex API access token. If successful (xhttp.status == 200
), the access token is displayed in the 'Access Token' field:
xhttp = new XMLHttpRequest(); // Create an AJAX HTTP request object
xhttp.onreadystatechange = function() { // Define a handler, which fires when the request completes
if (xhttp.readyState == 4) { // If the request state = 4 (completed)...
if (xhttp.status == 200) { // And the status = 200 (OK), then...
var authInfo = JSON.parse(xhttp.responseText); // Parse the JSON response into an object
document.getElementById('token').value = authInfo['access_token']; // Retrieve the access_token field, and display it
} else alert('Error requesting access token: ' + xhttp.statusText)
}
}
xhttp.open('POST', 'https://webexapis.com/v1/access_token', true); // Initialize the HTTP request object for POST to the access token URL
// Build the HTML form request body
var body = 'grant_type=authorization_code&'+ // This is an OAuth2 Authorization Code request
'redirect_uri='+encodeURIComponent(appRedirectUri)+'&'+ // Same custom app Redirect URI
'code='+encodeURIComponent(document.getElementById('code').value)+'&'+ // User auth code retrieved previously
'client_id='+encodeURIComponent(appClientId)+'&'+ // The custom app Client ID
'client_secret='+encodeURIComponent(appClientSecret); // The custom app Client Secret
xhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // Sending the content as URL-encoded form data
xhttp.send(body); // Execute the AJAX HTTP request
anchorStep 4: Retrieve a Webex access token
anchorWe should now be ready to try out the sample app using your new Webex application registration info to log in and generate an access token:
- Make sure the following are ready:
- Webex user account email and password
- Application Client ID
- Application Client Secret
- Application Redirect URI
- The authentication sample app is open
- Using the sample app, login and request the Webex auth code:
- Copy and paste the application Client ID, into the appropriate field (Client Secret is not needed in this step).
- Click Request Auth Code, then follow the directions shown in the sample app to view/confirm the requested application permissions, and log in. When finished, the sample app page should reload and populate the 'Auth Code' field.
- Exchange the auth code for the Webex API access token:
- Copy and paste the application Client ID (once again), and Client Secret into the appropriate fields.
- Click Request Access Token.
The access token should be displayed in the 'Access Token' box.
Note: While not displayed in this sample app, some additional info - such as token expiration info and a refresh token, is also included in the response.
For example:
{
"access_token": "XXXXX"
"expires_in": 1209599
"refresh_token": "YYYY"
"refresh_token_expires_in": 7775082
}
This info shows that the Webex API access token expires in just under 14 days (1209599 seconds.) After that time, the application can use the refresh_token
to obtain a new access token. The refresh token itself is good for about 90 days, renewed whenever it is used to retrieve an access token.
See the Integrations and OAuth page for more details on refresh tokens.
anchorStep 5: Check your work!
anchorLet's take the access token you just retrieved and test it using the Webex interactive documentation to see if it is working as expected. You can use this note-box page to copy/paste the access token from the sample app form into temporarily.
1) Use the access token to list your Webex rooms.
Navigate to the Webex interactive documentation page for List Rooms.
Make sure you are logged in, and have the Try it button enabled .
In the Headers section, view the
Authorization
field. This field contains the stringBearer
, a space, and then an access token. By default, the field is pre-populated with your personal developer token based on your login. In this case, we want to replace that default token with the access token generated using the OAuth sample app.Toggle Use personal access token to clear the pre-populated access token.
Paste the access token from Step 4 after the word
Bearer
, followed by a space (be sure and preserve capitalization and the space afterBearer
).Click
Results: If all went well, in the response output window you should see a
Response 200/OK
result, and a JSON-format array of room details:
2) Try to access data from the Webex /people/me
resource
Visit the Webex interactive documentation page for Get My Own Details for 'me', i.e. the user associated with the access token
As above, toggle Use personal access token to clear the pre-populated access token, and paste the access token obtained via the sample app.
Click
Results: In this test, the expected result is actually a failure response, i.e. a
Response 403/Forbidden
message:
Note: A 'Forbidden' result is expected here, because when the sample app obtained its access token from the Webex service, it only requested the spark:rooms_read
authorization scope. This means that the access token returned by Webex will only allow read (GET) requests from the /rooms
API resource. As the test above attempts to read info from the /people
resource, the request is rejected.
If desired, the sample app could be updated to also include the spark:people_read
scope to allow making API requests for the /people
resource by updating this line of code:
'scope='+ encodeURIComponent('spark:rooms_read spark:people_read') + '&' +