podludek
podludek

Reputation: 279

Facebook app: server-side access token verification

Simple facebook application communicate with a database server (with wrapper). For security reasons there is needed to check if an user asking server for some action is really an owner of his id (sent in request).

For this purpose request to server contains access_token and id of user from a web application based on javascript SDK. I want to check if id of owner of access token and id of user is the same. First step is to getting id of owner of access token from Facebook. Using code:

class SessionValidator {
    private $userId;            //id of user
    private $accessToken;       //facebook user's access token
    private $fb;
    public function __construct($userId, $accessToken){
        $this->userId = $userId;
        $this->accessToken = $accessToken;
        $app_id = @appId; 
        $app_secret = @secret;

        $fb = new Facebook(array('appId' => $app_id, 'secret' => $app_secret));
        $fb->setAccessToken($accessToken);

        $this->fb = $fb;
    }
    public function authUserSession(){
        $url = 'https://graph.facebook.com/';
        $data['fields'] = $this->userId;
        $data['access_token'] = $this->accessToken;

        $response = $this->post_request($url, $data);

        return $response;
    }
    private function post_request($url, $data){
        return $this->fb->api('/me', 'POST', $data);
    }
}

Facebook has been giving response:

Uncaught OAuthException: (#10) Application does not have permission for this action

The same response is if I have removed line: $fb->setAccessToken($accessToken);. I'm sure that appId and appSecure are correct. Client-side app and server-side app are placing on different hosts, but both domains are added as domain of app, on facebook developers site. Any idea why I received this error?

Upvotes: 3

Views: 3901

Answers (1)

Syed I.R.
Syed I.R.

Reputation: 6230

The problem is with your call you're making there!

You should do a GET request and not POST request.

Also your fields key should be id as its value and not user's ID.

Here's a fixed version:

class SessionValidator {
private $userId;            //id of user
private $accessToken;       //facebook user's access token
private $fb;
public function __construct($userId, $accessToken){
    $this->userId = $userId;
    $this->accessToken = $accessToken;
    $app_id = @appId; 
    $app_secret = @secret;

    $fb = new Facebook(array('appId' => $app_id, 'secret' => $app_secret));
    $fb->setAccessToken($accessToken);

    $this->fb = $fb;
}
public function authUserSession(){
    $url = 'https://graph.facebook.com/';
    $data['fields'] = 'id';
    $data['access_token'] = $this->accessToken;

    $response = $this->get_request($url, $data);

    return $response;
}
private function get_request($url, $data){
    return $this->fb->api('/me', 'GET', $data);
}
}

If you do a GET request with fields value as your User's ID i.e $this->userId then it'll return an error saying:

(#100) Unknown fields: [User ID you Pass]

EDIT: Here's another version which you could use to verify the user ID. If the user id matches with the user id returned by facebook, then the method will return true or false. If you're doing something else with the returned response, then this might not be the right version for you and you can use the above version.

class SessionValidator {
    private $userId;            //id of user
    private $accessToken;       //facebook user's access token
    private $fb;
    public function __construct($userId, $accessToken){
        $this->userId = $userId;
        $this->accessToken = $accessToken;
        $app_id = @appId; 
        $app_secret = @secret;

        $fb = new Facebook(array('appId' => $app_id, 'secret' => $app_secret));
        $fb->setAccessToken($accessToken);

        $this->fb = $fb;
    }

    public function authUserSession(){
        $url = 'https://graph.facebook.com/';
        $data['fields'] = 'id';
        $data['access_token'] = $this->accessToken;

        $response = $this->get_request($url, $data);

        if($this->userId == $response['id']) {
            return true;
        }
        return false;
    }

    private function get_request($url, $data){
        return $this->fb->api('/me', 'GET', $data);
    }
}

Upvotes: 8

Related Questions