React Native Expo Cli Facebook Authentication - unable to exchange Response type code for access token on server API

644 Views Asked by At

I am creating React Native app using Expo and used its inbuilt Facebook.useAuthRequest to generate a response when a user logs in. When I create a response type of Token I am able to take this token and send it to my backend API that successfully uses it to get the user details.

However I had hoped to implement a response type of code and use this on the backend API generate the access Token and then request the user details - as I believe this is the most secure option when sending the code to my server.

The issue that I'm facing is that I keep getting an error when trying to formulate the requst to Graph API and I dont understand why:

error: {
    message: 'Missing client_id parameter.',
    type: 'OAuthException',
    code: 101,
    fbtrace_id: 'ARHcoh260kBwj7l9yDHjU-n'
  }

I just want to confirm that I believe I have inserted all the correct information into the request, so I am unsure of why this error is saying its missing the cliend_id. Here is my request from my API server:

const { data } = await axios({
        url: https://graph.facebook.com/v12.0/oauth/access_token? client_id=${appId} &redirect_uri=${redirectUri} &client_secret=${appSecret} &code=${code},
        method: 'get',
    });

I just want to confirm that the client_id I have taken from app id I created on the facebook developer page, as well as the client_secret, redirect is the https:// used in the initial request and the code is the code initially received in my client side request.

Thanks in advance for any suggestions :)

3

There are 3 best solutions below

0
David Metcalfe On

Just a quick update on this, I was ablel to reformat the request as I believe it had some errors in the spacing and I moved to using the .env files so now my request looks like this:

const redirectUri = {MY_REDIRECT URL};
    const appId = process.env.FACEBOOK_CLIENT_ID;
    const appSecret = process.env.FACEBOOK_CLIENT_SECRET;

    const { data } = await axios({
        url: `https://graph.facebook.com/v12.0/oauth/access_token?client_id=${appId}&redirect_uri=${redirectUri}&client_secret=${appSecret}&code=${code}`,
        method: 'get',
    });

It seems I have moved onto a new error with the following:

 error: {
        message: 'Invalid code verifier. Code verifier should be a cryptographically random string using the characters A-Z, a-z, 0-9, and the punctuation characters -._~ (hyphen, period, underscore, and tilde), between 43 and 128 characters long.',
        type: 'OAuthException',
        code: 1,
        fbtrace_id: 'AQKIUad5RRCitb6m977fnFW'
      }

I'm a bit stumped for what this means as I have checked and all my values appear correct. My only thought is if I need to do something with the code initially received on the client side?

1
David Metcalfe On

Ok so I finally figures it out - the issue was the I wasn't sending the code_verifier along with my request to exchange the Auth Code for a token. I ended up sending this code_verifier to my API server then adding this to the request so it looked something like this:

FB.api(
        'oauth/access_token',
        {
            client_id: appId,
            client_secret: appSecret,
            redirect_uri: redirectUri,
            code_verifier: code_verifier,
            code: code,
        },
        function (response) {
            if (!response || response.error) {
                console.log(!response ? 'error occurred' : response.error);
                return;
            }

            var accessToken = response.access_token;

This then finally gave me the accessToken I was looking for that I can then use to exchange for user details server side.

0
Yosmany Garcia On

... and the code_verifier is obtained from request.codeVerifier.

const [request, response, promptAsync] = Facebook.useAuthRequest(...