Validação do lado do servidor do token de acesso do Facebook para aplicativo do iPhone

112

Estou desenvolvendo um aplicativo para iPhone, que é baseado na comunicação com o servidor, e quero usar mecanismos de autenticação do Facebook.

Basicamente, acho que deveria funcionar assim:

  1. No meu aplicativo para iPhone, o usuário faz login no Facebook, usando seu e-mail e senha.
  2. O usuário permite o acesso aos seus dados para o aplicativo do Facebook relacionado.
  3. Meu aplicativo para iPhone recebe o token de acesso, após efetuar login com sucesso.
  4. Em outras comunicações com meu servidor, meu aplicativo para iPhone deve usar o token de acesso do Facebook recebido (por exemplo: em consultas).
  5. Quando meu servidor receber alguma consulta do aplicativo do iPhone, com token de acesso, ele deve perguntar ao Facebook que esse token é válido (e para quem) e, em caso afirmativo, o servidor deve assumir que o usuário está autenticado no Facebook.

Minha pergunta é: como o servidor deve perguntar ao Facebook se o token de acesso fornecido é válido? Acho que devo verificar de alguma forma se o token é válido para meu aplicativo do Facebook.

Eu tentei muitas consultas do Facebook para representar graficamente a API, que encontrei, mas nada funcionou como eu esperava. Você pode me dar algum exemplo?

Marcin
fonte
5
A menos que o usuário tenha se desconectado do aplicativo no FB, você pode simplesmente enviar o token de autenticação para o servidor (esperançosamente SSL). Uma consulta simples de "/ me" por meio da API do gráfico é bem-sucedida ou falha?
The Mad Gamer
você receberá uma mensagem em resposta do Facebook de que seu token não é válido :)
Jean-Luc Godard
1
Estou tentando fazer algo muito semelhante ao que você está fazendo. Você nunca marcou esta pergunta como respondida, você já conseguiu fazer isso funcionar?
tempestuoso de
O que acontece quando o access_token expira? devemos pedir ao usuário para fazer o login novamente? eu quero entender como validar novamente após o token expirar
debianmaster
@debianmaster isso depende da arquitetura do seu aplicativo. Se você considerar o caso "nenhum token FB - nenhum acesso ao aplicativo", então sim, faça logout do usuário. Caso contrário, você pode considerar uma lógica de "desvinculação", em que o usuário permanece logado, mas as informações recebidas do Facebook são desanexadas de sua conta no servidor / cliente.
Yevhen Dubinin

Respostas:

115

Este é um processo de duas etapas que você pode usar para validar se um token de acesso do usuário pertence ao seu aplicativo:

1) Gerar um token de acesso de aplicativo

( https://developers.facebook.com/docs/howtos/login/login-as-app/ )

https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID
&client_secret=YOUR_APP_SECRET
&grant_type=client_credentials

2) Depurar o token de acesso do usuário

( https://developers.facebook.com/docs/howtos/login/debugging-access-tokens/ )

https://graph.facebook.com/debug_token?
input_token=INPUT_TOKEN
&access_token=ACCESS_TOKEN

Onde INPUT_TOKEN é o token de acesso do usuário que você deseja verificar e ACCESS_TOKEN é o token do seu aplicativo obtido na etapa 1.

O endpoint de depuração basicamente despeja todas as informações sobre um token, então ele responderá com algo assim:

{
    data: {
        app_id: YOUR_APP_ID,
        is_valid: true,
        metadata: {
            sso: "iphone-safari"
        },
        application: YOUR_APP_NAMESPACE,
        user_id: USER_ID,
        issued_at: 1366236791,
        expires_at: 1371420791,
        scopes: [ ]
    }
}

Se esse token não for de "seu aplicativo", ele retornará uma resposta de erro.

sebastian o caranguejo
fonte
13
De acordo com o Facebook , essa é a maneira correta de inspecionar tokens. No entanto, a primeira parte é opcional, pois você pode usar o ID e o segredo do aplicativo em vez de um token de administrador ou aplicativo.
Brandon Zacharie
@BrandonZacharie Não vejo como você faz isso, eu apenas tentei com o ID do aplicativo e segredo e me deu um erro para "parâmetro input_token necessário"
Johnny Z
@JohnnyZ o token de entrada é obrigatório. O token de acesso é onde está a flexibilidade.
Brandon Zacharie,
8
@BrandonZacharie Você está certo, eu estava recebendo uma confusão de tokens de entrada e acesso. Para usar o ID e o segredo do aplicativo, passei isso como um parâmetro com a barra vertical como delimitador: & access_token = APP_ID | APP_SECRET
Johnny Z
115

Atualização: esta resposta parece insegura, pois não valida o token primeiro como pertencente ao seu aplicativo, consulte os comentários, a resposta original da seguinte forma:

Presumo que você já tenha o token de acesso em mãos. Nesse caso, a maneira mais simples de validar um token de acesso é emitir a seguinte solicitação

https://graph.facebook.com/me?fields=id&access_token=@accesstoken

Substitua aqui @accesstoken pelo token de acesso que você possui. Vou detalhar o url e explicar cada um.

Estamos emitindo uma solicitação de API de gráfico aqui que retornará o ID do usuário do Facebook do proprietário do token de acesso como uma string JSON. A palavra-chave 'eu' representa o usuário atualmente conectado ou o proprietário do token de acesso. Para esta solicitação, o token de acesso é um parâmetro obrigatório.

Se o token de acesso fornecido não for válido ou expirado, o Facebook retornará apenas uma mensagem de erro de algum tipo.

Para um token de acesso válido, o resultado será de alguma forma parecido com este

{
   "id": "ID_VALUE"
}
Robin
fonte
14
Essa solicitação não seria bem-sucedida se o usuário fornecesse um access_token que pertence a um aplicativo diferente?
Yuriy Nemtsov
2
Qualquer token de acesso de usuário válido pode ser usado (independentemente do aplicativo ao qual pertença)
Robin
12
@Xiquid esta postagem não é a solução para o problema, pois não valida se o token de acesso pertence ao seu aplicativo.
Kolyunya
12
Não entendo por que essa resposta tem mais votos! OBVIAMENTE não é a solução certa. Na verdade, a abordagem correta é a que "o caranguejo sebastian" sugeria. O ponto de extremidade debug_token é usado para consultar informações sobre o próprio token e, dessa forma, você pode verificar se o token pertence a um ID de usuário específico para um ID de aplicativo específico!
Alex Ntousias
4
Sim, esta resposta não está correta. Se você verificar o token de acesso dessa maneira, alguém pode obter um token de acesso de um aplicativo diferente e usá-lo para autenticar com o seu.
Jonathan,
11

Outra solução seria usar https://graph.facebook.com/app/?access_token=[user_access_token]conforme descrito em Obter id do aplicativo do token de acesso do usuário (ou verificar o aplicativo de origem de um token) .

Este parece ser um recurso não documentado, mas retorna JSON contendo a id do aplicativo para o qual o token foi gerado. Se o token não fosse para seu aplicativo, ele retornará 400.

Helen Williamson
fonte
Como posso obter as classificações de outras empresas do Facebook. O que preciso fazer para isso?
Maneesh Rao
6

Na última versão do Facebook (2.2), você pode fazer isso desta forma:

https://developers.facebook.com/docs/graph-api/reference/v2.2/debug_token

Saída de amostra:

{
    "data": {
        "app_id": "THE APP ID", 
        "application": "APP NAME", 
        "expires_at": 1427245200, 
        "is_valid": true, 
        "scopes": [
        "public_profile", 
        "basic_info", 
        "read_stream", 
        "email", 
        "publish_actions", 
        "read_friendlists", 
        "user_birthday", 
        "user_hometown", 
        "user_location", 
        "user_likes", 
        "user_photos", 
        "user_videos", 
        "user_friends", 
        "user_posts"
        ], 
        "user_id": "THE USER ID"
    }
}
Shoeb Ahmed Mogal
fonte
Isso significa que você terá que chamar este endpoint fb em cada solicitação? Não existe uma maneira melhor?
Jdruwe,
Isso funciona, mas requer o token de acesso. O token de acesso pode ser gerado usando a resposta 'sebastian the crab' ou podemos simplesmente usar appid | appsecret. Para mais informações developers.facebook.com/docs/facebook-login/…
krishnan
Aqui está um exemplo de uso disso: stackoverflow.com/a/16947027/32453
rogerdpack
2
private function facebookRequestMe($access_token)
{
    include_once "facebook.php";

    $facebook = new Facebook(array(
        "appId" => "your_application_id",
        "secret" => "your_application_secret"
    ));
    $facebook->setAccessToken($access_token);
    return $facebook->api("/me", "GET");
}

Você pode baixar o SDK do Facebook para PHP no GitHub .

Baptiste Costa
fonte
1

Se um usuário passou para você um UID do Facebook que ele afirma ser dele e você deseja verificar se é legítimo, esta é uma função Python que o verificará em relação ao token de acesso (uma implementação da resposta de Robin Jome):

def verify_facebook_id(id, access_token):
    import requests
    import simplejson
    params = {'fields': 'id', 'access_token': access_token}
    text = requests.get("https://graph.facebook.com/me", params=params).text
    json = simplejson.loads(text)
    response_id = json["id"]
    return response_id == id
Andrew Magee
fonte
Isso não valida que o token foi gerado "para seu aplicativo", infelizmente ...
rogerdpack
1

Este é o único método seguro para verificar o token do usuário usando apenas uma solicitação:

https://graph.facebook.com/debug_token?input_token={token-to-inspect}&access_token={app_id}|{app_secret}

Observe que um sinal "|" no URL acima não é usado como OU, mas como separador e deve estar lá após preencher os outros campos.

A resposta será JSON semelhante a:

{
    data: {
        app_id: {app_id},
        application: {app_name},
        expires_at: {some_number},
        is_valid: {true|false}
        scopes: {array_of_permissions},
        user_id: {user_id}
    }
}

Referência: https://developers.facebook.com/docs/facebook-login/access-tokens/#apptokens (o método acima é mencionado no final desta seção)

Kamoris
fonte
Há outra maneira segura com uma solicitação: stackoverflow.com/a/36555287/32453
rogerdpack
-1

Junto com um token de acesso, o Facebook também envia um parâmetro "expires_in", que é um valor de deslocamento. Use isso para calcular quando o token de acesso expirará como um NSDate. Então, quando você precisar fazer uma solicitação, compare a data atual com a data de vencimento.

Além disso, tente inspecionar os códigos de status e as strings de resposta que o Facebook envia de volta.

jcm
fonte