CORS Issue with `frontend-app-learning` accessing LMS API endpoint

Environment

  • devstack (open-release/maple.1)

I’m getting the following error on the frontend-app-learning when trying to access LMS api endpoint created for badging. This looks like a CORS issue.

Access to XMLHttpRequest at ‘http://localhost:18000/api/badges/v1/progress/courses/course-v1:CUCWD+SB101+SANDBOX’ from origin ‘http://localhost:2000’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: Redirect is not allowed for a preflight request.

I can resolve the endpoint in the browser and get results.

I tried updating my edx-platform/lms/envs/private.py file with CORS whitelist but not such luck. I also noticed that the Dates tab makes LMS API endpoint calls but that this frontend-app-learning wasn’t added to the CORS_ORIGIN_WHITELIST for edx-platform/lms/envs/devstack.py file.

############# CORS headers for cross-domain requests #################

ALLOWED_HOSTS = [
    '*',
    ]

CORS_ORIGIN_WHITELIST = (
    'http://localhost',
    'http://48dc79f998c7',
    'http://localhost:2000',
    'http://edx.devstack.frontend-app-learning',
)

cc: @jill @djoy @becdavid @Chris_Gaber

Hi @Zachary_Trabookis :wave:

The lms.envs.devstack has CORS_ORIGIN_ALLOW_ALL = True, which should mean CORS_ORIGIN_WHITELIST gets ignored, so I don’t think that’s the issue.

Sometimes I get CORS errors in the browser when the underlying cause is really an error on the request that’s being made – say the request threw an authentication error, but the 403 response doesn’t contain the usual CORS headers, so the browser shouts CORS.

You’ve checked that the page renders fine on its own, which is cool. But have you checked your nginx/lms logs to make sure the request isn’t erroring out in this situation due to something else, like JWT authentication, or Bad Request method, or something like that?

<aside>
Both of these settings have been renamed, but the old aliases should still work, see docs for CORS_ALLOWED_ORIGINS, CORS_ALLOW_ALL_ORIGINS.
</aside>

1 Like

@jill I think you’re right about not having to setup CORS whitelist due to devstack settings that you mentioned above.

So accessing this API endpoint directly via the browser produces a successful HTTP 200 response and her are the logs.

http://localhost:18000/api/badges/v1/progress/courses/course-v1:CUCWD+SB101+SANDBOX/
[23/Feb/2022 23:59:47] “GET /api/badges/v1/progress/courses/course-v1:CUCWD+SB101+SANDBOX/ HTTP/1.1” 200 21865

Here is the request headers for that api endpoint call from the frontend-app-learning microfrontend for the CORS error above.

Looking at the LMS logs it appears that I’m getting a 301 redirect response. I’ll look further into the authentication for the API endpoint.

[24/Feb/2022 00:06:50] “OPTIONS /api/badges/v1/progress/courses/course-v1:CUCWD+SB101+SANDBOX HTTP/1.1” 301 0

@jill I figured it out.

The REST URL had an extra /$ at the end of the Django URL path. When I removed that the CORS error and that HTTP 301 Redirect went away. Now I’m seeing HTTP 200.

I created a sample heartbeat endpoint like so by removing the extra /$ at the end of the URL path.

# edx-platform/lms/djangoapps/badges/api/urls.py
urlpatterns += [
    re_path(
        fr'^heartbeat/{settings.COURSE_ID_PATTERN}',
        HeartbeatTabView.as_view(),
        name='badges-heartbeat'
    ),
]
# edx-platform/lms/djangoapps/badges/api/views.py
from rest_framework.generics import RetrieveAPIView

class HeartbeatTabView(RetrieveAPIView):
    """
    **Use Cases**

        Returns heartbeat status of Badges API

    **Example Requests**

        GET /api/badges/v1/heartbeat/

    **Response Values**

        Body comprised of a list of objects with the following fields:

        * status: Value to indicate that a successful response is okay for the badges api.
    """
    def get(self, request, *args, **kwargs):
        """
        """
        return Response({
            'status': 'ok'
        })

Now I’m see this for the LMS logs when called from the frontend-app-learning microfrontend.

[24/Feb/2022 00:35:00] “GET /api/badges/v1/heartbeat/course-v1:CUCWD+SB101+SANDBOX HTTP/1.1” 200 15

Also verified this in the browser.

I think we’re good now. Thanks for the help!

Excellent work @Zachary_Trabookis ! So glad you worked this out.

1 Like