facebook-graph-apifacebook-javascript-sdk

Facebook Graph api access tokens don't include permissions from scope argument (account with Tester Role, before app review approval)


When asking adding extra permissions to the scope argument of my FB login button, those permissions aren't added to the access token.

I'm building an app (with Next.js) that let's you schedule posts to a users profile page.

The user I'm testing with has the Role of Tester in my app, so app permissions shouldn't be a problem.

This is my code:

facebook async init code

useEffect(() => {
        window.fbAsyncInit = function () {
            // @ts-ignore
            FB.init({
                appId: process.env.NEXT_PUBLIC_FACEBOOK_APP_ID,
                cookie: true,
                xfbml: true,
                version: process.env.NEXT_PUBLIC_FACEBOOK_API_VERSION, // v20.0
            });

            // @ts-ignore
            FB.AppEvents.logPageView();

            // @ts-ignore
            FB.getLoginStatus(function (response) {
                console.log('login status:', response)
            });
        };

        (function (d, s, id) {
            var js, fjs = d.getElementsByTagName(s)[0];
            if (d.getElementById(id)) { return; }
            js = d.createElement(s); js.id = id;
            // @ts-ignore
            js.src = "https://connect.facebook.net/en_US/sdk.js";
            // @ts-ignore
            fjs.parentNode.insertBefore(js, fjs);
        }(document, 'script', 'facebook-jssdk'));
    }, []);

the login button onClick handler:

const loginWithShowListPerm = () => {
        // @ts-ignore
        FB.login(function (response) {
            (async () => {
                console.log('login response:', response)
                if (response.status === 'connected') {
                    const params: GraphApiParams = {
                        accessToken: response.authResponse.accessToken,
                        platformUserId: response.authResponse.userID,
                    }

                    await saveAccessToken(params);

                    const accessTokenData = await getAccessTokenData(params);

                    console.log('accessTokenData:', accessTokenData);


                    // User is logged in and authorized
                    // Execute your function here
                }
            })();
        }, { scope: 'pages_show_list' });

the convertToLongLivedAccessToken backend method this method is called by the server action saveAccessToken

export async function convertToLongLivedAccessToken({
    userAccessToken,
}: {
    userAccessToken: string,
}) {
    try {
        const response = await fetch(`https://graph.facebook.com/${process.env.NEXT_PUBLIC_FACEBOOK_API_VERSION}/oauth/access_token`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                grant_type: 'fb_exchange_token',
                client_id: process.env.NEXT_PUBLIC_FACEBOOK_APP_ID,
                client_secret: process.env.FACEBOOK_APP_SECRET,
                fb_exchange_token: userAccessToken,
            }),
        });

        const data = await response.json();
        console.log('data:', data);
        return data.access_token;
    } catch (error) {
        console.error('Error converting to Long Lived Access Token:', error);
        return null;
    }
}

node.js script to check token permissions:


async function main() {
try {
const response = await fetch(`https://graph.facebook.com/v20.0/me/permissions?access_token=${accessToken}`);

        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
    
        const data = await response.json();
    
        console.log('Data:', data);
    
    } catch (error) {
        console.error('Error fetching user permissions:', error);
    }

}

main();

Even when adding { scope: 'pages_show_list' } attribute to the login button code, both the short lived and the long lived tokens return this when testing with the check permissions script:


Data: { data: \[ { permission: 'public_profile', status: 'granted' } \] }

as you can see, only the default granted 'public_profile' permission is included, the 'pages_show_list' is missing. I would expect there to at least be a mention of the permission, either with status 'granted' or something else.

Help would be greatly apreciated.


Solution

  • The problem turned out to be that I created the wrong app type, I needed a business app, but I made a user app.

    This is my My Apps menu: My Apps menu example