Apple's MusicKit JS library example runs fine when rendered by Node.js, fails with Django

496 Views Asked by At

For three hours, I've been scratching my head over this.

Apple's MusicKit uses JWT tokens to authenticate.

When I npm start this Node.js example project, I can generate the JWT token, and then authorize Apple Music and collect the user token in response. This works when executing from localhost:8080. Here is a successful pop-up window.

When I launch my Django server locally which also generates valid JWT tokens, running the same exact HTML code with a fresh JWT token, I receive this from Apple: "Problem Connecting: There may be a network issue."

The only error on Apple.com's authorization page, is this: vendor-2c0b12a9762d9af673e21ccd8faf615e.js:2325 Error while processing route: woa Failed to construct 'URL': Invalid URL TypeError: Failed to construct 'URL': Invalid URL

I have confirmed that both applications are generating valid JWT tokens. I can use the tokens generated in my Django application with Postman directly with Apple API, as well as my token from the Node.js app.

I have tried:

  1. Using JWT token from Django in the Node.js app -- works
  2. Using JWT token from Node.js app in Django -- fails still
  3. Allowing all hosts to Django
  4. Allowing all CORS traffic to Django
  5. Hosting page on an HTTPS valid cert. domain vs. locally
  6. Different browser / computer
  7. Accessing the authorization URL directly from Node.js in a new tab -- FAILS
  8. Accessing the authorization URL directly from Django in a new tab -- FAILS
  9. Breaking the JWT token and using that with Django -- FAILS and does not even open the authorization window (console says invalid token, so this further proves the token I use is valid with Django)

From steps 7 / 8, it would appear something in the referral process between when the JS script runs and the pop-up window for authorization appears is failing, as the token is clearly valid.

So what could Django (dev server) be doing that's disrupting this authorization flow? Or am I missing something else?

1

There are 1 best solutions below

0
On

Okay, so I was right, it had to do with what Node.js server exposed to Apple.com when the request was made, versus what Django did.

It boiled down to the 'Referrer-Policy' policy of the Django server.

By default it is "same site" on Django, which means the referral information is not distributed to Apple.com, so Apple cannot verify the source of the request.

I added the following header to my Django view render:

# Create the render variable
response = render(request, 'apple.html'.format(settings.BASE_DIR), {'apple_developer_token': apple.get_token()})

# Attach the header
response['Referrer-Policy'] = 'origin-when-cross-origin'

# Return the render
return response

It then worked.