Skip to main content
Ctrl+K
Logo image
  • edx-platform Documentation
  • “How-To” Guides
    • How to write a celery task
    • How To Use the REST API
  • References
    • Authentication Related Code Samples
    • Feature Toggles
    • LMS APIs
    • Settings
    • Python Docstrings
      • cms
      • common
      • lms
        • lms
      • openedx
        • openedx package
  • Concepts and Guides
    • Options for Extending the edX Platform
    • Testing
    • JavaScript in edx-platform
    • Styling in edx-platform
    • Working with Bootstrap
    • edx-platform Static Asset Pipeline Plan
    • edx-platform REST API Concepts
  • Repository
  • Suggest edit
  • Open issue
  • .rst

Authentication Related Code Samples

Contents

  • Get a JWT with a Username and Password
  • Get a JWT with a client_id and client_secret
  • Check to see if a JWT is Expired
  • Refresh a JWT Using a Refresh Token
  • Use a JWT Header to call an API

Authentication Related Code Samples#

Warning

Access Tokens, Refresh Tokens and Client Secrets are generally considered secret and should not live in your code. We print them here so that these examples are useful but you should generally not expose any of these tokens to systems or clients you don’t trust.

Get a JWT with a Username and Password#

import requests
from pprint import pprint

token_request = requests.post(
    f"http://lms.example.com/oauth2/access_token",
    data={
        "client_id": "login-service-client-id",
        "grant_type": "password",
        "username": "test_user",
        "password": "test_password",
        "token_type": "JWT",
    },
)
pprint(token_request.json())
Output#
{'access_token': 'eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiAibG1zLWtleSIsICJleHAiOiAxNjkyMjExNjM4LCAiZ3JhbnRfdHlwZSI6ICJwYXNzd29yZCIsICJpYXQiOiAxNjkyMjA4MDM4LCAiaXNzIjogImh0dHA6Ly9sb2NhbGhvc3Q6MTgwMDAvb2F1dGgyIiwgInByZWZlcnJlZF91c2VybmFtZSI6ICJmZWFuaWwiLCAic2NvcGVzIjogWyJyZWFkIiwgIndyaXRlIiwgImVtYWlsIiwgInByb2ZpbGUiXSwgInZlcnNpb24iOiAiMS4yLjAiLCAic3ViIjogIjVjMTBmNjZmMmQ2MzkwYjcwNjYyYzkxNGFhZTdlZjc5IiwgImZpbHRlcnMiOiBbInVzZXI6bWUiXSwgImlzX3Jlc3RyaWN0ZWQiOiBmYWxzZSwgImVtYWlsX3ZlcmlmaWVkIjogdHJ1ZSwgImVtYWlsIjogImZlYW5pbEBheGltLm9yZyIsICJuYW1lIjogIkZlYW5pbCBQYXRlbCIsICJmYW1pbHlfbmFtZSI6ICIiLCAiZ2l2ZW5fbmFtZSI6ICIiLCAiYWRtaW5pc3RyYXRvciI6IHRydWUsICJzdXBlcnVzZXIiOiB0cnVlfQ.iGFl7qsAUau0-40oq8Of0f72kguq2Hc_drijCnI2I-M',
 'expires_in': 3600,
 'refresh_token': 'm8iXhVlGABu52xFxVFj5rAz8xSjsRq',
 'scope': 'read write email profile',
 'token_type': 'JWT'}

Note

The client type must be public for this to work.

Get a JWT with a client_id and client_secret#

import base64
import requests

from pprint import pprint

client_id = "ukbclQB8aPh7hgsy8ifPXkPf7fRqgUq1w21f2YZa"
# Note this should actually be secret and probably not in your code but
# provided here in the example
client_secret = "xkN0BJ19q9Jk8UPUppEtC1xe4764c81ioFtlegvokbmnAC7CFCT5gG1Og5nnFmCNc3NHNhUwWWDRVcBfnLSZ4xAlEmSePzfkFtLE06cwR1MuSc0gx9LUEjRrTs3j2vgK"

credential = f"{client_id}:{client_secret}"
encoded_credential = base64.b64encode(credential.encode("utf-8")).decode("utf-8")

headers = {"Authorization": f"Basic {encoded_credential}", "Cache-Control": "no-cache"}
data = {"grant_type": "client_credentials", "token_type": "jwt"}

token_request = requests.post(
    "http://lms.example.com/oauth2/access_token", headers=headers, data=data
)

pprint(token_request.json())
Output#
{'access_token': 'eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiAibG1zLWtleSIsICJleHAiOiAxNjkyMjExNjM4LCAiZ3JhbnRfdHlwZSI6ICJjbGllbnQtY3JlZGVudGlhbHMiLCAiaWF0IjogMTY5MjIwODAzOCwgImlzcyI6ICJodHRwOi8vbG9jYWxob3N0OjE4MDAwL29hdXRoMiIsICJwcmVmZXJyZWRfdXNlcm5hbWUiOiAiZmVhbmlsIiwgInNjb3BlcyI6IFsicmVhZCIsICJ3cml0ZSIsICJlbWFpbCIsICJwcm9maWxlIl0sICJ2ZXJzaW9uIjogIjEuMi4wIiwgInN1YiI6ICI1YzEwZjY2ZjJkNjM5MGI3MDY2MmM5MTRhYWU3ZWY3OSIsICJmaWx0ZXJzIjogW10sICJpc19yZXN0cmljdGVkIjogZmFsc2UsICJlbWFpbF92ZXJpZmllZCI6IHRydWUsICJlbWFpbCI6ICJmZWFuaWxAYXhpbS5vcmciLCAibmFtZSI6ICJGZWFuaWwgUGF0ZWwiLCAiZmFtaWx5X25hbWUiOiAiIiwgImdpdmVuX25hbWUiOiAiIiwgImFkbWluaXN0cmF0b3IiOiB0cnVlLCAic3VwZXJ1c2VyIjogdHJ1ZX0.CX1S0QGrWKEPOHC8kUzGcvW8Ky04RCA8vU8WJrZURSw',
 'expires_in': 3600,
 'scope': 'read write email profile',
 'token_type': 'JWT'}

Note

When you get a JWT using client_credentials you don’t get a refresh token. You’re just expected to make a new call with your client credentials.

Check to see if a JWT is Expired#

import jwt

# See above examples for how to get a JWT token
jwt_token = token_request.json()['access_token']

try:
    jwt.decode(jwt_token, "secret", audience="lms-key", algorithms=['HS256'])
except jwt.ExpiredSignatureError:
    # Signature has expired

Refresh a JWT Using a Refresh Token#

import requests

# See "Get a JWT with a Username and Password" for how to get a refresh token.
# The response from that request will include a `refresh_token` attribute.
refresh_token = token_request.json()['refresh_token']

refreshed_token_request = requests.post(
    f"http://lms.example.com/oauth2/access_token",
    data={
        "client_id": "login-service-client-id",
        "grant_type": "refresh_token",
        "refresh_token": token_request.json()['refresh_token'],
        "token_type": "JWT",
    },
)

pprint(refreshed_token_request.json())
Output#
{'access_token': 'eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiAibG1zLWtleSIsICJleHAiOiAxNjkyMjE1MTgwLCAiZ3JhbnRfdHlwZSI6ICJwYXNzd29yZCIsICJpYXQiOiAxNjkyMjExNTgwLCAiaXNzIjogImh0dHA6Ly9sb2NhbGhvc3Q6MTgwMDAvb2F1dGgyIiwgInByZWZlcnJlZF91c2VybmFtZSI6ICJmZWFuaWwiLCAic2NvcGVzIjogWyJyZWFkIiwgIndyaXRlIiwgImVtYWlsIiwgInByb2ZpbGUiXSwgInZlcnNpb24iOiAiMS4yLjAiLCAic3ViIjogIjVjMTBmNjZmMmQ2MzkwYjcwNjYyYzkxNGFhZTdlZjc5IiwgImZpbHRlcnMiOiBbInVzZXI6bWUiXSwgImlzX3Jlc3RyaWN0ZWQiOiBmYWxzZSwgImVtYWlsX3ZlcmlmaWVkIjogdHJ1ZSwgImVtYWlsIjogImZlYW5pbEBheGltLm9yZyIsICJuYW1lIjogIkZlYW5pbCBQYXRlbCIsICJmYW1pbHlfbmFtZSI6ICIiLCAiZ2l2ZW5fbmFtZSI6ICIiLCAiYWRtaW5pc3RyYXRvciI6IHRydWUsICJzdXBlcnVzZXIiOiB0cnVlfQ.oNTEk7aMFSjvEbvH_-Gu2QZE93w-CpXSIIuN-IC6BSU',
 'expires_in': 3600,
 'token_type': 'JWT',
 'scope': 'read write email profile',
 'refresh_token': 'V5fbgDt2RPVnmI6Q3c6cJ3OjVriGii'}

Use a JWT Header to call an API#

# See above examples for how to get a JWT token
access_token = token_request.json()["access_token"]

enrollment_request = requests.get(
    "http://lms.example.com/api/enrollment/v1/enrollment",
    headers={"Authorization": f"JWT {access_token}"},
)

pprint(enrollment_request.json())
Output#
[{'course_details': {'course_end': None,
                     'course_id': 'course-v1:TestX+Course+1',
                     'course_modes': [{'bulk_sku': None,
                                       'currency': 'usd',
                                       'description': None,
                                       'expiration_datetime': None,
                                       'min_price': 0,
                                       'name': 'Audit',
                                       'sku': None,
                                       'slug': 'audit',
                                       'suggested_prices': ''}],
                     'course_name': 'Open edX Test Course',
                     'course_start': '2022-04-09T00:00:00Z',
                     'enrollment_end': None,
                     'enrollment_start': None,
                     'invite_only': False,
                     'pacing_type': 'Instructor Paced'},
  'created': '2023-08-17T14:10:48.476967Z',
  'is_active': True,
  'mode': 'audit',
  'user': 'test_user'}]

previous

References

next

Feature Toggles

Contents
  • Get a JWT with a Username and Password
  • Get a JWT with a client_id and client_secret
  • Check to see if a JWT is Expired
  • Refresh a JWT Using a Refresh Token
  • Use a JWT Header to call an API

By Axim Collaborative, Inc

© Copyright 2024, Axim Collaborative, Inc.

Creative Commons License
These works by Axim Collaborative, Inc are licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.