React Native Auth
# support
c
I have looked through the server and have seen a couple of questions that relate to RN but nothing that quite answers my question. I am unable to use the medplum functions such as
startLogin
providing email/pwd as we get an error that it is missing property
crypto
. I have looked at the example app and do note that iOS and Android are not supported in that example and only web based which is not helpful for a mobile app. I did find a conversation that asked about
missing grant_type
in the oauth2/token request but no response to that. I have done a medplum.post to
auth/login
which has given me a code Attempting to do medplum.post to
oauth2/token
providing a content type and params and although I have provided grant_type it is failing. I found a link to
https://docs.medplum.com/api/oauth/token
which is a broken link as are the other links on this repo https://github.com/medplum/medplum-oauth-demo This may be a moot point as we plan to implement our current indetity provider BUT for our POC we are trying to avoid that integration. Hoping this isn't a heavy lift to test the patient facing app on mobile.
r
Hi @codejenn , sorry for the inconvenience. I just fixed those broken links!
Please let me know if you're able to get the demo working.
Also, if you have a stack trace of where you're running into errors importing
crypto
, I'd be happy to look in more detail
c
@rahul1 I'm working on implementing the SDK into an existing mobile application fully react-native and builds to iOS and Android, not web. I have been unsuccessful in exchanging the code from call9ing login endpoint to get the accessToken. If I can get the accessToken then I'm able to make requests. I ran the "react-native" example via web and looked at network requests to get my accessToken to verify this but I am unable to get that far in my codebase using rest endpoints. I get
invalid request missing grant_type
The steps I have taken via code:
Copy code
medplum
      .post('auth/login', { email, password })
      .then(handleAuthResponse);

//attempt to exchange code for accessToken- results in missing grant_type
   medplum
        .post(
            'oauth2/token',
            {
                code: response.code,
                grant_type: 'authorization_code',
                client_id: 'MY_CLIENT_ID',
            },
            'application/x-www-form-urlencoded',
            { headers: { Authorization: `Basic ${authHeader}` } },
        )
        .then(setProfile);

//using fetch example for token get same results as medplum.post
 const body = {
                grant_type: 'authorization_code',
                client_id: 'MY_CLIENT_ID',
                code: response.code,
            };
const authHeader = base64.encode(`${clientId}:${clientSecret}`);


fetch('https://api.medplum.com/oauth2/token', {
    method: 'POST',
    body: JSON.stringify(body),
    headers: {
        // "Content-Type": "application/json",
        'Content-Type': 'application/x-www-form-urlencoded',
        Authorization: 'Basic ' + authHeader,
    },
})
    .then((res) => res.json())
    // .then(showOutput)
    .then((res) => console.log(res.access_token));
Attaching a screen grab of the network traffic to show the request body/response where you can see I do include the grant_type as shown in the code above.
r
Hi @codejenn , thanks for all the details! I totally understand that you're building for React Native. The main reason we share that web demo is that it's completely bare-bones (dones't use the client), so it's a no-frills way of debugging the OAuth handshake. But using CURL / fetch also accomplishes the same goal. I believe the issue is that we expect the request body to be URL-encoded form data, but you are sending a json string in the fetch call. This SO post offers some guidance on how to create the URL-encoded formdata string: https://stackoverflow.com/questions/35325370/how-do-i-post-a-x-www-form-urlencoded-request-using-fetch
Would you be willing to try that with the fetch?
Also, you should not need to keep the client_secret in your app, for the oauth2 flow. This auth header is for "Basic Auth" login (https://www.medplum.com/docs/sdk/classes/MedplumClient#setbasicauth), but that is really only for server-to-server communication (or for the CLI) > const authHeader = base64.encode(
${clientId}:${clientSecret}
);
c
I was looking at a few different examples, did not start with adding the authHeader to that request 🙂 I did follow that SO you sent but now I get Invalid Client error , so closer but not quite there
Once I have this working I plan to submit a PR for that example repo 🙂
r
Looking forward to it
We're also happy to update the example on our end if you let us know that the issues are ! you can just file a ticket on our repo: https://github.com/medplum/medplum/issues
Wrt to that error message, can I confirm one thing - when you called the "authorize" endpoint, did you use the same clientId?
c
Yes it is the same clientId
r
Sorry for the silly qustions, I just want to make sure we trace through step by step to debug. This error message typically means that the code that was passed back after
/authorize
doesn't match the code sent during
/token
1. When you call
/authorize
, were you getting a successful redirect to the medplum authentication screen? 2. After the user logged in, were you getting a successfull redirect back to your
redirect_uri
, with a
code
? 3. You sent that
code
to the
/token
, but got an "invalid client" error
If that's all correct, would you mind DM'ing me the code you get back from
/authorize
? I can try to run some diagnostics on my end
c
Not silly questions! I really appreciate your help! This actually got me to really think again about what you are asking and what I'm doing. tl;dr attempting to login as PATIENT, have the medplum client instance setup which had the clientId prop and I made assumption that when calling medplum.post it was passing that clientid which is actually not the case. I just went into an incognito window and logged in on medplum.com to see what was being passed and noted an empty string for client id 🤦‍♀️ So yeah, I guess I wasn't using same client id. When I did that, all is right in the world. I plan to put up a PR to the react native example to share what I've learned for react native specifics. THANK YOU SO MUCH!
r
My pleasure! yeah, medplum.post() is a low level command, so it takes exactly what you give it. The
start**
commands will forward along the all the clientId info
out of curiousity, did you have trouble wiht the
signInWithRedirect
method?
c
Got it, yeah, unfortunately the start** don't work with the react native mobile apps that I'm finding thus far. I will try the signInWithRedirect tomorrow morning, going to finally put this down for the day but I will let you know.
r
Would also love all the feedback about RN - we're still hardening our examples
c
It will be my pleasure to help with that, it's def my passion
r
@codejenn thank's so much for the PR! I took a look and realized that this example was on a VERY OLD version of our SDK. I think we actually have fixed the underlying issue with
boa
I've just updated the package.json. Would you be willing to try the example again, and see if there's any improvement?
c
@rahul1 I got boa on latest SDK when I implemented it within our app. I did not start with this example app, but I did port over my changes to the example. Would still LOVE to see them updated in the SDK as it would be much cleaner for sure.
r
Totially understand. We're trying to debug why the SDK didn't just work out of the box. With that example app, we were worried it was the outdated version. Any other pointers to why the SDK errored would be appreciated 🙏
c
Sorry @rahul1 I don't have any other specifics at the moment, we moved our focus elsewhere as you know 😉
168 Views