Cannot use magic link endpoint with PKCE

I am writing an iOS Health App and using URLSession and SwiftUI. I am not using any external libraries as I would need to audit them first and I don’t have the time/budget for that. I know this would probably be easier with Auth0 SDK, but I figure anything that the SDK can do, I should also be able to do with the APIs.

Unfortunately I cannot get the magic link and the PKCE flow working together. I am following this doc:


The first thing I notice is that this authorize endpoint is not in the POSTMAN collection I downloaded from Auth0 website. So maybe that is telling me something.

I can get the oauth/token (Non PKCE) endpoint to work if I use passwordless/start endpoint and get a OTP code back in the email.
I can then call this oauth/token(Non PKCE) with the parameters:
grant_type: http://auth0.com/oauth/grant-type/passwordless/otp
client_id: XXXXXXXXXXXXXXX
redirect_uri:com.health.auth0://health.auth0.com/ios/com.health.auth0/callback
otp:123456
realm:email
username: brett@mail.com
audience: https://myapi.health.com
scope: email openid profile
This gives me back a JWT which I can use to successfully call http://myapi.health.com

However at no time do I provide client_secret (which I don’t want to), code_challenge, or code_verifier. To me this does not feel secure enough.

What i would prefer to do is use the magic link and the PKCE flow, but after days of trying I am not getting anywhere.
Currently I am doing:

  • User clicks login and enters email
  • I call passwordless/start with:
    client_id: XXXXXXXXXXXXXXX
    email: brett@mail.com
    send: code
    connection: email
    scope: email openid profile
  • I get an email with the magic link
  • I click on the link (and I believe it calls verify_link) and it then opens my iOS App using deep linking
  • I extract the access_token YYYYYYYYYY (scope, token_type etc) from the deeplink
  • Using this access_token I then call the PKCE authorize endpoint with the following parameters:
    URL: GET https://auth.healthapp.com/authorize?
    client_id: XXXXXXXXXXXXXXX
    audience: myapi.health.com
    scope: email openid profile
    code_challenge: JqF9jgnwm5M6S7Rn1VOk75NNFWa6WFSmdERdZN5H8ns
    code_challenge_method: S256
    access_code: YYYYYYYYYY
    redirect_uri: com.health.auth0://health.auth0.com/ios/com.health.auth0/callback
    response_type: code
  • I get back a 200 with the payload in HTML \n\n\n \n \n Sign In with Auth0\n \n\n\n\n \n\n \n\n \n \n // Decode utf8 characters properly\n var config = JSON.parse(decodeURIComponent(escape(window.ato …

According to the documentation I should get a 302:
"If all goes well, you’ll receive an HTTP 302 response. The authorization code is included at the end of the URL:

HTTP/1.1 302 Found
Location: YOUR_CALLBACK_URL?code=AUTHORIZATION_CODE&state=xyzABC123"

And in the Dashboard logs I can see “Success Login” event and a payload:
{
“date”: “2020-10-13T06:35:41.369Z”,
“type”: “s”,
“connection”: “email”,
“connection_id”: “con_73vIZq82oeyksdJU”,
“client_id”: “XXXXXXXXXX”,
“client_name”: “Health App iOS”,
“ip”: “X.X.X.X”,
“user_agent”: “Mobile Safari 14.0.0 / iOS 14.0.0”,
… deleted middle section
“user_name”: “brett@mail.com”,
“strategy”: “email”,
“strategy_type”: “passwordless”,
“isMobile”: true,
“description”: “Successful login”
}

I have been working on this for days and am not sure where to go from here. How do I get an authorisation token to send to oauth/token ?

Thanks for any help anyone can provide.