Autenticação com o Twitter em várias etapas

OAuth

Comecei a estudar sobre a autenticação OAuth para utilizá-la com o Twitter. Protocolo utilizado em muitos serviços web e é a forma mais segura de permitir que uma terceira aplicação acesse um serviço  (o Twitter no caso) de maneira segura e prática.

Uma forma de utilizar o Twitter seria solicitando aos usuários que informassem seu usuário e senha para a aplicação intermediária (vou chamá-la de Hub). Um exemplo pode ser visto na  figura abaixo.

Twitter

Esse modelo apresenta diversos problemas ligados à segurança. Informando o usuário e senha para o Hub, esta aplicação pode realizar qualquer operação no Twitter em nome do usuário, inclusive realizar alterações no perfil.

Justamente para resolver esse problema, foi criado o OAuth que restringe o acesso a operações determinadas sem o fornecimento de senhas para o Hub. O processo pode ser visto na figura abaixo.

OAuth

A autenticação acontece da seguinte forma:

O Hub realiza uma solicitação ao Twitter pedindo um endereço, para que um usuário se vincule a ele. Quando o usuário final visualiza a página, é solicitada para confirmar ao Twitter se perfil de usuário e concordar ou não com a vinculação de seu perfil com o Hub. A página já estamos acostumados a ver.

Twiiter

Após essa confirmação, o Twitter chama o Hub, informando uma nova chave gerada sem vinculação com o usuário e senha reais. Isso garante que o Hub desconhece os dados do usuário.

Continuar lendo

Escutando o Twitter

 Um bom ouvinte não só é popular em qualquer lugar, mas também fica sabendo das coisas depois de algum tempo.

O programa importador de Tweets, designado Marvin, necessita da API fornecida pelo Twitter. Num primeiro momento foi utilizada a REST API, mas a maneira mais correta é utilizando a Streaming API.

A Streaming API fornece um acesso de baixa latência ao fluxo global de Tweets. O streaming funciona através do envio de mensagens indicando novos Tweets. São fornecidos 3 endereços de acordo com a necessidade:

  • Public Streams: utilizado para seguir específicos usuários ou tópicos e para mineração de dados;
  • User Sreams: retorna os dados de apenas um usuário, utilizado para apresentar uma visão;
  • Site Streams: utilizado por servidores que necessitam conectar ou Twitter em nome de muitos usuários.

Para o desenvolvimento do Marvin, foi utilizado a Public Streams que suporta uma série de parâmetros passados através de POST. Para obter as mensagens desejadas, foi utilizado o parâmetro track. Esse parâmetro é uma lista de frases separadas por vírgulas, cada frase pode ter entre 1 e 60 caracteres e um ou mais termos separados por espaço. O  Tweet será retornado se ao menos uma das frases possuir todos os seus termos (em ordem e ignorando a caixa alta ou baixa). As frases são comparadas através de UTF-8, levando em consideração até a acentuação.

Para a conexão com a API, é necessário a autenticação que pode ser feita de duas formas: Básica e OAuth. No Marvin, optei por utilizar a autenticação básica que necessita um usuário e senha válidos do Twitter. Uma conexão pode ser desconectada pelo servidor quando uma outra conexão é realizada com as mesmas credenciais.

Para evitar super-congestionamento, as conexões podem receber o código HTTP 420 (Rate Limited). Essa situação pode acontecer através de sucessivas desconexões e reconexões (para troca de parâmetros por exemplo). Para evitar que o IP seja bloqueado por um período de tempo é importante que ao receber uma notificação 420, as tentativas de novas conexões sejam suspensas por alguns minutos.

A diferença básica entre o Streaming API e REST API é que no Streaming a conexão HTTP é mantida aberta, o que envolve uma utilização diferente pela aplicação.

Enquanto no REST, cada requisição de mensagens abre e fecha uma conexão HTTP (Figura 1), no Streaming API, a conexão HTTP é mantida por um processo paralelo e os Tweets são atualizados por notificações (Figura 2)

Figura 1

Mesmo o Streaming API sendo mais complexo que a REST, possui como benefício a utilização em uma infinidade de aplicativos.

Figura 2

Fonte: Twitter

Isso não é um banco de dados relacional

A ordem dos fatores altera o produto

Como já comentei, estou fazendo o TCC baseado em um banco de dados não relacional, neste caso o DynamoDB.

Nestas duas últimas semanas venho desenvolvendo os aplicativos para gravar e ler no DynamoDB (Marvin e Telescreen, respectivamente).

Para gravar, o processo é extremamente simples; basta montar o registro e mandar salvar no dado. Mas tive alguns problemas na hora de retornar o dado. Primeiramente, com o fato de não haver relacionamento entre tabelas. Imaginando as tabelas abaixo, onde cada mensagem pertence a um usuário.

Durante a apresentação, para cada mensagem é necessário fazer uma nova requisição ao servidor, solicitando o Usuário através de seu username. Então para carregar 200 mensagens são necessárias 201 requisições (1 para pegar a lista de mensagens e mais 200 para cada usuário). Todo esse processo se mostrou muito lento, quase 30 segundos para carregar 50 mensagens.

A primeira tentativa para otimizar esse processo foi criando um buffer de usuários, onde ao invés de realizar diretamente a requisição de usuário, era verificado se o registro já estava armazenado na memória local. Este processo não trouxe efeito por causa do tipo de dado que está sendo armazenado. Como são Tweets capturados de acordo com uma taxonomia, a chance de um usuário mandar 2 mensagens próximas é pequena, sendo assim o buffer não se mostrou útil e foi retirado.

A solução para esse problema foi colocar os campos da tabela de usuários junto à tabela de mensagens, não sendo mais necessária a tabela de usuários. Isso produziu uma desnormalização na tabela de usuários, mas o ganho de velocidade em consultas foi interessante. Para retornar 50 mensagens, é necessário 1 segundo.

O outro problema que tive foi com relação à ordem de retorno dos registros. Como o banco de dados realiza sharding, ou seja, os dados são replicados e particionados entre diversos servidores, ao solicitar diversos registros, eles não retorna em uma ordem que eu tenha identificado, nem na ordem de inclusão. É outro problema pois não consigo apresentar as mensagens mais recentes primeiro. A solução para isso foi apresentar cada página de 50 registros ordenada. Mas não sei se é a melhor solução.

Até o presente momento estou gravando e lendo corretamente todos os dados, o retorno das consultas está rápido e tudo está bem.

A difícil e reconfortante arte de aprender

It is a very sad thing that nowadays is so litle useless information

– Oscar Wilde

Como já comentei estou fazendo o meu TCC sobre armazenamento de dados em banco de dados NoSQL.

O banco que escolhi utilizar foi o DyamoDB. Ele é um banco proprietário da Amazon e é da categoria chave-valor, ou seja  é uma grande tabela identificada por uma chave única. É um paradigma não muito diferente dos utilizados nos dicionários em memória, a grande diferença é a escalabilidade suportando milhões de registros.

Ontem comecei a estudar como armazenar os dados no Dynamo, e uma boa fonte de partida foi o material da própria Amazon. Escolhi desenvolver o programa na linguagem .NET (pois tenho mais facilidade)  e existe um SDK muito bom para o Visual Studio.

Demorei algum tempo para entender os exemplos disponíveis e realizar algumas alterações básicas. Mas a lógica é bem simples.

  • Após concluir o cadastro na Amazon,
  • Vá no console da ferramenta
  • E crie uma tabela
  • Informe o nome
  • Informe o tipo de chave que será utilizada, Hash que é uma chave simples ou Hash and Range que é uma chave composta de dois campos
  • Pronto a sua tabela está pronta.
  • As operações disponíveis para as tabelas são: Load (para carregar uma chave), Save (para salvar uma chave), Delete (para excluir uma chave), Scan (para listar todas as chaves) e Query (para consultar)

Como as tabelas não possuem uma estrutura rígida, cada registro pode ter campos diferentes o que facilita bastante a estrutura. Não existe relacionamento entre diferentes tabelas, isso é realizado diretamente durante a programação.

Ao final da minha secção de trabalho eu tinha as tabelas criadas, conforme “DER” abaixo

E realizei a codificação o Marvin gravar nas tabelas Usuário e Mensagem.

Durante os testes de execução do programa, com uma taxonomia limitada, encontrei uma postagem de @lespider publicando uma comparação entre diversos bancos NoSQL (acesse aqui).

O Marvin começou a criar forma, espero que ele não seja muito deprimido.

TCC

Para terminar o meu dia, voltei a fazer o meu TCC. Ele é sobre Arquitetura de Dados NoSQL para Indexação de Tweets. o material pode ser acessado através de Texto e a Apresentação.

Estou nesse momento implementando 2 programas:

  • o Marvin (referência a O Guia da Mochileiro das Galáxias) que é um programa de importação de Tweets para uma base no NoSQL
  • o Telescreern (referência a 1984) que é um website para visualização desses Tweets.

Batizei com duas grandes referências Nerds, dois livros que são ótimos.

O Marvin já está lendo o Twitter e falta gravar no banco de dados, o Telescreen está apresentando e só falta ler do banco de dados. Ou seja eu não fiz nada de importante ainda.

Não estou seguindo os principio ágeis (SCRUM, XP) e entregar rápido valor. Vou me focar isso.