Implementar login social com Twitter é uma ótima maneira de integrar a experiência do usuário da sua aplicação, ou produto, com a plataforma do Twitter. Além disso, você possibilita que os usuários compartilhem conteúdo produzido pela sua aplicação.
Uma característica importante ao implementar o login social com o Twitter é o uso de OAuth, um padrão largamente adotado e que permite o acesso à recursos do usuário sem a necessidade de compartilhar as suas senhas. Porém, mesmo quando as especificações de como implementar OAuth são super detalhadas e claras, essa tarefa pode se transformar em algo complexo e frustrante.
Por isso resolvemos construir um código em Ruby e Python que exemplifica bem como funciona esse fluxo. Dessa forma, você pode começar a sua implementação de forma bem mais rápida e confiante. Os exemplos são bem fáceis de instalar e testar.
Nós vamos fazer um tour pela implementação em Ruby, que é uma aplicação feita usando o framework Sinatra. Perceba que esse código acompanha o procedimento documentado no site de desenvolvedores do Twitter.
Passo 1: Obtendo o request token
Quando o usuário clica em “Login” na sua aplicação, o primeiro passo é obter um request token do Twitter:
Listagem 1:
https://github.com/lfcipriani/sign_in_with_twitter_sample/blob/master/app.rb#L48
get '/signin' do # After hitting Sign in link, first thing your app must do # is to get a request token. # See https://dev.twitter.com/docs/auth/implementing-sign-twitter (Step 1) token = TwitterSignIn.request_token # With request token in hands, you will just redirect # the user to authenticate at Twitter # See https://dev.twitter.com/docs/auth/implementing-sign-twitter (Step 2) redirect TwitterSignIn.authenticate_url(token) end
O método request_token está implementado na classe TwitterSignIn:
Listagem 2:
https://github.com/lfcipriani/sign_in_with_twitter_sample/blob/master/lib/twitter_sign_in.rb#L15
def request_token # The request to get request tokens should only # use consumer key and consumer secret, no token # is necessary response = TwitterSignIn.request( :post, "https://api.twitter.com/oauth/request_token", {}, @oauth ) obj = {} vars = response.body.split("&").each do |v| obj[v.split("=").first] = v.split("=").last end # oauth_token and oauth_token_secret should # be stored in a database and will be used # to retrieve user access tokens in next requests db = Daybreak::DB.new DATABASE db.lock { db[obj["oauth_token"]] = obj } db.close return obj["oauth_token"] end
Basicamente, essa requisição feita à API do Twitter irá retornar dois valores: oauth_token e oauth_token_secret. Essa será sua credencial temporária fornecida pelo Twitter para que você consiga requisitar um token de acesso à conta do usuário.
Passo 2: Redirecionando o usuário
Com essa credencial em mãos, você pode redirecionar o usuário para /oauth/authenticate passando o oauth_token obtido no passo anterior.
Listagem 3:
https://github.com/lfcipriani/sign_in_with_twitter_sample/blob/master/lib/twitter_sign_in.rb#L43
def authenticate_url(query) # The redirection need to be done with oauth_token # obtained in request_token request "https://api.twitter.com/oauth/authenticate?oauth_token=" + query end
Nesse momento, o usuário será redirecionado para o Twitter e será perguntado se ele deseja liberar o acesso da sua aplicação para acessar os seus recursos. Se o usuário autorizar o acesso, o Twitter vai redirecioná-lo de volta para a URL de callback que você configurou na sua aplicação registrada em apps.twitter.com.
Listagem 4:
https://github.com/lfcipriani/sign_in_with_twitter_sample/blob/master/app.rb#L60
# This callback will be called by user browser after # being redirect by Twitter with successful authentication # See https://dev.twitter.com/docs/auth/implementing-sign-twitter (end of Step 2) get '/callback' do # Given that the user authorized us, we now # need to get its Access Token. # See https://dev.twitter.com/docs/auth/implementing-sign-twitter (Step 3) token = TwitterSignIn.access_token(params["oauth_token"], params["oauth_verifier"])
A redireção possui um parâmetro chamado oauth_verifier, que é a confirmação que o usuário autorizou a sua aplicação. O parâmetro oauth_token também retornado permite você identificar qual usuário você está autenticando e você deve verificar se ele bate com o valor que foi retornado no primeiro passo.
Passo 3: Converter o request token em um access token
Agora você irá utilizar todos os tokens obtidos em passos anteriores para requisitar o token de acesso. É com o token de acesso que você irá, assim como o nome sugere, acessar o Twitter em nome do usuário que acabou de te autorizar. Vamos dar uma olhada na implementação desse passo.
Listagen 5:
https://github.com/lfcipriani/sign_in_with_twitter_sample/blob/master/lib/twitter_sign_in.rb#L49
# See https://dev.twitter.com/docs/auth/implementing-sign-twitter (Step 3) def access_token(oauth_token, oauth_verifier) # To request access token, you need to retrieve # oauth_token and oauth_token_secret stored in # database db = Daybreak::DB.new DATABASE if dbtoken = db[oauth_token] # now the oauth signature variables should be # your app consumer keys and secrets and also # token key and token secret obtained in request_token oauth = @oauth.dup oauth[:token] = oauth_token oauth[:token_secret] = dbtoken["oauth_token_secret"] # oauth_verifier got in callback must # to be passed as body param response = TwitterSignIn.request( :post, "https://api.twitter.com/oauth/access_token", {:oauth_verifier => oauth_verifier}, oauth ) obj = {} vars = response.body.split("&").each do |v| obj[v.split("=").first] = v.split("=").last end # now the we got the access tokens, store it safely # in database, you're going to use it later to # access Twitter API in behalf of logged user dbtoken["access_token"] = obj["oauth_token"] dbtoken["access_token_secret"] = obj["oauth_token_secret"] db.lock { db[oauth_token] = dbtoken } else oauth_token = nil end db.close return oauth_token end
O método TwitterSignIn.access_token realiza uma requisição para POST /oauth/access_token passando a consumer_key e secret, bem como oauth_token e oauth_token_secret dentro da assinatura de OAuth; já o oauth_verifier, obtido no passo 2, será passado no corpo da requisição.
Com esse conjunto de informação, o Twitter pode validar que essa requisição de um token de acesso é legítima e vai retornar os tokens de acesso do usuário. Dessa forma você agora poderá realizar requisições à API do Twitter em nome desse usuário. Você deve também armazenar esses tokens de acesso de maneira segura na sua base de dados.
Passo 4: Usando o token de acesso
Essa aplicação de exemplo implementa uma funcionalidade que permite que você siga uma conta configurada previamente. Isso é apenas um exemplo do que pode ser feito uma vez que você obtém autorização do usuário.
Listagem 6:
https://github.com/lfcipriani/sign_in_with_twitter_sample/blob/master/app.rb#L118
# Building oauth signature vars to use in this request # Basically, it's our app consumer vars combined # with user access tokens oauth = @oauth.dup oauth[:token] = dbtoken["access_token"] oauth[:token_secret] = dbtoken["access_token_secret"] # A POST request in https://dev.twitter.com/docs/api/1.1/post/friendships/create # to make the logged user follow the ACCOUNT_TO_FOLLOW response = TwitterSignIn.request( :post, "https://api.twitter.com/1.1/friendships/create.json", {:screen_name => ACCOUNT_TO_FOLLOW}, oauth )
Conclusão
Agora que você já sabe como implementar o login social com o Twitter, dê uma olhada também no código completo deste exemplo para ter uma visão geral de como a aplicação funciona. Se você é um pythonista, dê uma olhada na implementação em Python feita pelo @jaakkosf.
Da mesma forma, se você já construiu uma integração que implementa o login social com o Twitter e ela pode ser extraída para uma aplicação stand-alone, compartilhe com a gente tweetando o link para a conta @TwitterDevBr. Nós iremos atualizar esse artigo a medida que mais exemplos de linguagens forem compartilhadas.