10. Dealing with Django CSRF Protection in Frontend Apps#
Status#
Accepted
Context#
For background, please see:
Transport JWT in HTTP Cookies, where we decided the mechanism that frontend apps will use to authenticate with backend API services.
Django CSRF Protection, which contains a description of Django’s CSRF protection.
Frontend apps need a way to obtain a CSRF token when making POST, PUT, and DELETE requests to backend API services implemented as Django applications with CSRF protection enabled. Each backend service is generally deployed with a CSRF token cookie scoped to the domain of the given service (ecommerce.edx.org) and named accordingly (ecommerce_csrftoken). Each backend service uses a unique SECRET_KEY to produce the CSRF token, so a CSRF token created by one service will not be valid for another service. Therefore, frontend apps served by different subdomains will not have access to these CSRF token cookies.
Decisions#
CSRF Token API Endpoint We will implement an API view that constructs a valid CSRF token and returns it in a JSON response. This API view will be added to the edx-drf-extensions python library under a new “csrf” Django app which will be added to INSTALLED_APPS in each backend service as we encounter frontend apps that need to make POST, PUT, and DELETE API requests to a given backend service. The CSRF token API endpoint will be protected from cross-domain XHR requests using our standard CORS protections (only requests originating from pages loaded from one of the domains listed in the CORS_ORIGIN_WHITELIST setting will be allowed).
Shared HTTP Client CSRF Token Management Code We will add code to the @edx/frontend-auth npm package that applies a request interceptor to the Axios HTTP client which will ensure that any POST, PUT, and DELETE requests are made with the appropriate CSRF token header. This code will make use of the the CSRF token API Endpoint described above to obtain a valid CSRF token for the given backend service for which a request is being made.