Temos um site onde a única forma de fazer o login e autenticar-se no site é com o Facebook (não foi minha escolha). Na primeira vez que você faz login no Facebook, uma conta é criada automaticamente para você.
Agora queremos criar um aplicativo para iPhone para nosso site e também uma API pública para que outros usem nosso serviço.
Esta questão é sobre como autenticar nosso site a partir do aplicativo / API e está dividida em 2 partes:
Qual é a maneira correta de lidar com a autenticação REST de uma API para um site que usa apenas Facebook OAuth como método de autenticação?
Eu li e pesquisei muito sobre métodos padrão de autenticação para API REST. Não podemos usar métodos como autenticação básica sobre HTTPS , pois não há credenciais para um usuário como tal. Algo como este parece ser apenas para a autenticação de aplicações usando a API.
Atualmente, a melhor maneira que posso pensar é que você atinge um ponto final / autorizar em nossa API, ele redireciona para o OAuth do Facebook, depois redireciona de volta para o site e fornece um 'token' que o usuário da API pode usar para autenticar subsequentemente solicitações de.
Para um aplicativo oficial que criamos, não precisaríamos necessariamente usar a API pública da mesma maneira. Qual seria a melhor maneira de falar com nosso site e autenticar usuários?
Eu entendo (eu acho) como autenticar aplicativos de terceiros que estão usando nossa API, usando chaves API (públicas) e chaves secretas (privadas). No entanto, quando se trata de autenticar o usuário que está usando o aplicativo, estou ficando um tanto confuso sobre como fazer isso, quando a única maneira de autenticar um usuário é o Facebook.
Sinto que estou perdendo algo muito óbvio ou não entendo totalmente como as APIs REST públicas devem funcionar, então qualquer conselho e ajuda seriam muito apreciados.
Respostas:
ATUALIZAÇÃO: veja abaixo
Também tenho pensado muito sobre essa questão. Ainda não está totalmente claro para mim, mas aqui está o caminho que estou pensando em seguir. Estou criando uma API REST com autenticação apenas para meus usuários no Facebook Connect.
No CLIENTE:
Na API (para cada método que requer autenticação do usuário):
Eu ainda tenho que testar isso. Como isso soa?
--- Atualização: 27 de julho de 2014 para responder à pergunta ---
Eu só uso a troca acima uma vez no login. Depois de determinar qual usuário está fazendo login, crio meu próprio token de acesso, e esse token é usado desse ponto em diante. Então, o novo fluxo se parece com este ...
No CLIENTE:
Na API
fonte
Esta é minha implementação usando JWTs (JSON Web Tokens), basicamente semelhante à resposta atualizada de Chris. Usei o SDK JS do Facebook e JWT.
Aqui está minha implementação.
Cliente: Use o SDK JS do Facebook para fazer login e obter o token de acesso.
Cliente: Solicite JWT da minha API chamando o
/verify-access-token
endpoint.MyAPI: Recebe o token de acesso, verifique-o chamando o
/me
endpoint da API do Facebook.MyAPI: se o token de acesso for válido, encontra o usuário no banco de dados e efetua login no usuário, se existir Crie um JWT com os campos obrigatórios como carga útil, defina uma validade, assine com a chave secreta e envie de volta ao cliente.
Cliente: armazena o JWT no armazenamento local.
Cliente: envia o token (o JWT da etapa 5) junto com a solicitação para a próxima chamada de API.
MyAPI: valide o token com a chave secreta, se o token for válido, troque o token por um novo, envie de volta para o cliente junto com a resposta da API. (Nenhuma chamada de API externa para verificação do token aqui depois) [se o token for inválido / expirado, solicitar ao cliente para autenticar novamente e repetir a partir de 1]
Cliente Substitui o token armazenado pelo novo e use-o na próxima chamada de API. Uma vez que a expiração do token é atendida, o token expira revogando o acesso à API.
Cada token é usado uma vez.
Leia mais respostas sobre segurança e JWT
Quão seguro é o JWT
Se você pode decodificar o JWT, como eles são seguros?
JSON Web Tokens (JWT) como tokens de autenticação e identificação do usuário
fonte
/debug_token
, portanto, você pode verificar se o token é realmente para o seu aplicativo.access_token
no Cliente. Use "fluxo de trabalho de código". Passecode
para MyAPI e fazer outra viagem de volta para o Facebook para trocacode
comaccess_token
. Isso é explicado com mais detalhes aqui: developers.facebook.com/docs/facebook-login/securityEstou tentando responder a mesma pergunta e tenho lido muito recentemente ...
Não terei "a" resposta, mas as coisas estão ficando um pouco mais claras para mim. Você leu os comentários no artigo que mencionou ? Eu os achei muito interessantes e úteis.
Como resultado, e à luz de como as coisas evoluíram desde que o primeiro artigo foi escrito, eis o que acho que farei:
HTTPS em todos os lugares - isso permite que você esqueça HMAC, assinatura, nonce, ...
Use OAuth2:
Quando as solicitações de autenticação vêm de meus próprios aplicativos / site, use este 'truque' (ou uma variação dele) descrito em uma resposta ao artigo mencionado antes.
No meu caso, tenho dois tipos de usuários: aqueles com credenciais de login / senha clássicas e aqueles que se inscreveram no Facebook Connect.
Então, eu forneceria um formulário de login regular com um botão "Login com Facebook". Se o usuário fizer login com suas credenciais "clássicas", eu simplesmente as enviaria para meu ponto de extremidade OAuth2 com um
grant_type=password
.Se ele decidir fazer login pelo Facebook, acho que seria um processo de duas etapas:
Por favor, note que eu ainda estou pesquisando muito sobre todas essas coisas, então essa pode não ser uma resposta perfeita ... talvez nem mesmo a correta! Mas acho que seria um bom ponto de partida. A ideia de usar uma "concessão de extensão" para a autenticação do Facebook pode envolver ter que registrá-lo para fazer as coisas corretamente? Não tenho muita certeza.
De qualquer forma, espero ter podido ajudá-lo ainda um pouco, e que pelo menos possa iniciar uma discussão para encontrar a melhor solução para este problema :)
Atualizar
O login do Facebook não é uma solução conforme apontado nos comentários: qualquer pessoa pode enviar um ID de usuário arbitrário e fazer login como esse usuário na API.
Que tal fazer assim:
Parece melhor?
fonte