Back-End

1 jul, 2015

Como verificar se um token OAuth é válido?

Publicidade

Alguns aplicativos Web precisam mostrar informações diferentes para usuários dependendo se tiverem autorizado o acesso a uma API usando OAuth (por exemplo do Facebook ou Google) e se o token de acesso OAuth ainda é válido, como por exemplo mostrando um botão de login ou não.

Leia este artigo para aprender algumas soluções para esse problema.

Verificando se um token de acesso é válido

De vez em quando eu recebo pedidos de usuários desta classe de PHP cliente de OAuth para poder verificar se a class já obteve o token de acesso OAuth, e nesse caso, se o token ainda é válido.

No início, a classe oauth_client_class tinha apenas a função Process() para executar essa verificação. A ideia era que a classe fosse simples, por isso tinha apenas uma função (além de Initialize e Finalize) que faria tudo é necessário, sem exigir que os usuários conhecessem tanto sobre o protocolo OAuth mais do que precisam.

Quando a função Process() determina que não há um token de acesso válido, ela irá redirecionar o usuário para a página de autorização do servidor Oauth.

No entanto, como esses usuários da classe não queriam que o redirecionamento acontecesse, a minha primeira abordagem foi a de permitir a substitução da função de redirecionamento em uma subclasse. Essa ideia não resolveu bem o problema. Funcionaria, mas essa não é uma solução boa, uma vez que exige que os usuários de classe criem subclasses.

Verificando se um token de acesso é válido sem redirecionar o usuário

Uma vez que a solução anterior não ficou óbvia para todos os usuários, eu continuei recebendo pedidos para ter uma solução que fosse mais evidente.

O que muitos usuários querem é fazer algo assim: se o token ainda não tiver sido recuperado, mostram um botão de login. Caso contrário, que sejam mostradas algumas informações sobre a conta do usuário logado obtidas do servidor OAuth. Então, deveria haver uma maneira de mostrar um botão de login sem obrigar a redirecionar imediatamente o usuário para a página de autorização do servidor OAuth.

A função de Process() faz duas coisas: 1) Verifica se já foi obtido um token válido e 2) redireciona o usuário se não houver nenhum token válido. Portanto, a solução mais óbvia é a de separar as duas coisas.

A função de Process() foi dividida em duas partes. A função CheckAccessToken() foi introduzida só para implementar a primeira parte. A função Process() chama a função CheckAccessToken() e, se necessário, redireciona o usuário para a página de autorização do servidor OAuth.

A função CheckAccessToken retorna o redirecionamento da URL no parâmetro variável passado por referência. Portanto, cabe ao código de chamada decidir o que fazer com essa URL. O usuário pode ser redirecionado para a autorização ou apenas mostrar o botão de login, com um link para a página de autorização.

Então, agora você pode chamar a função CheckAccessToken() no lugar da função de Process() se você não quiser redirecionar o usuário imediatamente quando não foi obtido um token válido. Seu código login típico com servidor OAuth deve agora se parecer mais com o código abaixo. Dê uma olhada no script de exemplo login_check_with_facebook.php para ver uma solução mais completa.

 $client = new oauth_client_class;
 $client->server = 'Facebook';
 $client->redirect_uri = 'http://' . $_SERVER['HTTP_HOST'].
  dirname( strtok( $_SERVER['REQUEST_URI'], '?' ) ).
  '/login_check_with_facebook.php';

  /* Other class settings may go here
   * like the application client id and secret
   */

 /* The initial page to redirect is not set;
  */
 $redirect_url = null;
 
 if(($success = $client->Initialize()))
 {
  if(($success = $client->CheckAccessToken( $redirect_url )))
  {

   /*
    * Is there a valid access token or shall we need to 
    * redirect the user to the OAuth server authorization page?
    */

   if(IsSet($redirect_url))
   {

    /*
     * It seems the access token was not yet retrieved
     * or it was expired and could not be renewed
     */

   }
   elseif(strlen($client->access_token))
   {

    // Call the API or do something else with the access token

   }
  }
  $success = $client->Finalize($success);
 }

 if($success)
 {

  /*
   * Check if the redirect URL is set, so the user needs to authorize
   * to obtain the access token
   */

  if(IsSet($redirect_url))
  {

   // Show the redirect URL as a link button

   echo '<h1><a href="',
    HtmlSpecialChars( $redirect_url ).
    '">Login with Facebook</a></h1>';
  }
  else
  {

    // Show something useful to the user

  }
 }
 else
 {
   // Show the error message
 }

E se o token que foi obtido antes já não for mais válido?

A função CheckAccessToken() verifica se o token já foi obtido antes. No entanto, por algum motivo, esse token pode ter expirado ou foi revogado pelo servidor OAuth.

Se o token expirou, a função CheckAccessToken() tentará renová-lo recuperando um token novo. Isso acontece se o servidor tiver fornecido, inicialmente, um token de atualização (refresh token).

Alguns servidores OAuth como o Facebook configuram os tokens para expirar depois de um tempo (60 dias?), mas não fornecem meios para atualizá-lo. Nesse caso, o usuário precisa ser redirecionado para a página de autorização novamente para reiniciar o processo para obter um novo token.

Algumas APIs fornecem meios para verificar se um token ainda é válido. No entanto, se um token foi revogado, em geral, a única maneira de saber que ele não é mais válido é a realização de uma chamada de API usando a função CallAPI(). Se essa chamada falhar, você precisa solicitar ao usuário para ir até o site do seu aplicativo Web e reiniciar o processo de autorização.

Conclusão

OAuth não é um protocolo trivial para entender e implementar. Há várias situações em que você precisa tomar cuidado. Esta classe tenta tornar tudo bem mais simples para todos os desenvolvedores que não têm tempo nem paciência para aprender sobre todo o protocolo OAuth, em todas as versões do protocolo OAuth que a classe suporta (1.0, 1.0a 2.0).

Este novo recurso para verificar o token de acesso sem redirecionar os usuários para a página de autorização OAuth é mais um passo para simplificar as situações que muitos desenvolvedores lidam com seus aplicativos baseados em OAuth.

Se você tiver dúvidas ou outros comentários, por favor, poste um comentário aqui. Com isso, mais explicações podem ser dadas ou a classe pode ser melhorada ainda mais.

***

Manuel Lemos faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: http://www.phpclasses.org/blog/package/7700/post/7-How-to-Check-if-an-OAuth-Token-is-Valid.html