oauth_client_example - adlnet/experienceapi_client_examples GitHub Wiki

OAuth Client Example

Python Client Script

The client.py file shows how to use the python oauth library to access protected resources in the ADL LRS. This file was originally pulled from another project python-oauth.

Set up

Python Libraries

This script requires the python oauth library and requests library.

pip install oauth
pip install requests

URLs

Adjust the url values to match your LRS OAuth endpoints. This is configured to connect to the development Django server if LOCAL = True and the hosted ADL_LRS if LOCAL = False.

LOCAL = True
SCHEME = 'http' if LOCAL else 'https' #'http'
SERVER = '127.0.0.1' if LOCAL else 'lrs.adlnet.gov' #'127.0.0.1'
PORT = '8000' if LOCAL else '443' #8000

# fake urls for the test server (matches ones in server.py)
REQUEST_TOKEN_URL = '%s://%s:%s%s' % (SCHEME,SERVER,PORT,'/XAPI/OAuth/initiate')
ACCESS_TOKEN_URL = '%s://%s:%s%s' % (SCHEME,SERVER,PORT,'/XAPI/OAuth/token')
AUTHORIZATION_URL = '%s://%s:%s%s' % (SCHEME,SERVER,PORT,'/XAPI/OAuth/authorize')
CALLBACK_URL = 'oob'
RESOURCE_URL = '%s://%s:%s%s' % (SCHEME,SERVER,PORT,'/XAPI/statements')

The last value is the url to the resources you want to access. In this example it is set to request all the statements in the LRS.

Consumer Key

OAuth uses a consumer key and secret to identify a consumer (client app). Register an app in the LRS to obtain a consumer key and secret, and replace the placeholder values in client.py. The client registration form is located in the ADL LRS at <lrs base url>/regclient/. (ex. Hosted ADL LRS: https://lrs.adlnet.gov/xapi/regclient/)

CONSUMER_KEY = '<consumer key>' # <<replace with key
CONSUMER_SECRET = '<consumer secret>' # <<replace with secret

User Registration

The last piece is registering the user who will be the resource owner. This will be the person that is using the client app. This user will be asked to log in to the LRS and grant permissions on the client app. Register a user on the LRS. (ex. Hosted ADL LRS: https://lrs.adlnet.gov/xapi/register/)

Running the Script

After installing the python library dependencies, and setting the urls and consumer key/secret, the example should be ready to run.

python client.py

Authorization PIN

The script prints messages about the OAuth process as it runs the example. It will stop during the authorize step to allow you, the resource owner, to log in to the LRS and authorize the script, the consumer, to access your resources.

go to ['/XAPI/OAuth/authorize?oauth_token=KHEVmHjRuekQXs'], verify, enter PIN here:

Copy that path and add it to your path to the LRS (ex. http://localhost:8000/), for instance 'http://localhost:8000/XAPI/OAuth/authorize?oauth_token=KHEVmHjRuekQXs'. After logging in, you will be presented with a form describing the client app as it was registered and options for changing the scope (access) it has in the LRS. Note that currently the LRS will only allow the user to further limit the scope.

After submitting the form authorizing the client, a page will present a PIN that the client example needs to continue with the OAuth process. This out of band method of getting a PIN for the client is because the client isn't a hosted app with public urls. As such, the LRS has no way of reporting back to the client that the authorization process is complete and it should continue with the OAuth process. The LRS knows this because during the initiate portion of the OAuth process the client sent a CALLBACK_URL of 'oob'. If the client is able of accepting HTTP requests, it would have set the CALLBACK_URL to the url where the client is listening for the authorization PIN.

Anyway, take the PIN (ex. AVJBNWjwT) from the page after authorizing the client and enter it.

go to ['/XAPI/OAuth/authorize?oauth_token=KHEVmHjRuekQXs'], verify, enter PIN here: AVJBNWjwT

Accessing the Resource

After hitting enter, the client example will continue the OAuth process of getting an access token and retrieving the resource based on the RESOURCE_URL you configured at the top of the client example.

The resources will be printed to the terminal.

resource = client.access_resource(oauth_request)    
print 'GOT'
print 'resource:\n %s' % resource

And that's it.

Using the Client for Real

This script is just highlighting how the OAuth process is working. The run_example() function uses the SimpleOAuthClient in the client scipt to go through the process of initiating, authorizing and obtainin an access token to access protected resources.

Things that would need implemented to use in a real client could include:

  • Saving the access token for later requests. The access token provides access to resources at every endpoint within the Experience API. Saving the access token allows the client to skip the OAuth process for subsequent resource requests for as long as the user, resource owner, or the LRS doesn't revoke the access token.
  • Handling limited scopes. Since the user and the LRS has the ability to narrow down or limit scope permissions, the client should be programmed to handle permission limits more restrictive than the scopes inititally registered.
  • Better error and HTTP response handling. This example expects a very specific workflow, for example the redirects in the authorization process. OAuth is more flexible in how these processes happen and a client app should be aware of these potential differences in workflow.