Autenticação da API REST

181

Estou criando um aplicativo que será hospedado em um servidor. Quero criar uma API para o aplicativo para facilitar a interação com qualquer plataforma (aplicativo Web, aplicativo móvel). O que eu não entendo é que, ao usar a API REST, como autenticamos o usuário.

Por exemplo, quando um usuário efetuou login e deseja criar um tópico no fórum. Como saberei que o usuário já está logado?

Noor
fonte
4
Você provavelmente deve procurar "autenticação REST" aqui. Já foi abordado em muitas outras perguntas.
Brian Kelly
10
Em poucas palavras, deixe o cliente enviar um nome de usuário e senha com cada solicitação usando HTTP Basic Auth (sobre SSL!) Ou autenticar uma vez para que o cliente tenha uma sessão autenticada que expirará após algum período de inatividade (ou, no entanto, você optar por substituir manipulação de sessão da sua estrutura da Web). A referida sessão pode ser armazenada em um cookie ou ser um parâmetro transmitido a cada solicitação (por exemplo, JSESSIONID em Java land).
Opionate
@opyate do ponto de vista de segurança, não é realmente uma boa ideia manipular a sessão usando cookies em um caso de API REST, pois os invasores podem enviar solicitações sem o consentimento do usuário. É melhor incluir um hash ou token de sessão em um cabeçalho HTTP (como Autorização).
S3v3n 26/03
1
@ s3v3n Corrija-me se estiver errado, mas as suas sugestões e as minhas são apenas maneiras diferentes de usar um cabeçalho + combinação de armazenamento local para efetuar a mesma coisa. É Authorizationcabeçalho + por exemplo, navegador localStorage VS Cookiecabeçalho + armazenamento padrão de cookies do navegador.
usar o seguinte comando

Respostas:

72

Você pode usar HTTP Basic ou Digest Authentication. Você pode autenticar com segurança usuários usando SSL na parte superior, no entanto, isso diminui um pouco a API.

  • Autenticação básica - usa codificação Base64 no nome de usuário e senha
  • Autenticação Digest - mistura o nome de usuário e a senha antes de enviá-los pela rede.

OAuth é o melhor que pode obter. As vantagens que o Auth oferece é um token revogável ou expirável. Consulte a seguir como implementar: Link de trabalho dos comentários: https://www.ida.liu.se/~TDP024/labs/hmacarticle.pdf

ankitjaininfo
fonte
4
Por favor, leia esta pergunta e a resposta fornecida por Les Hazelwood (autor de Apache Shiro).
precisa saber é o seguinte
1
Link útil como o Twitter protege sua API REST: Segurança da API REST do Twitter
WildDev 27/16
Como esta é a resposta aceita, acho importante mencionar que você também pode usar a autenticação Digest. Leia sobre as diferenças entre as autenticações Basic e Digest aqui: stackoverflow.com/questions/9534602/…
Rayee Roded
116

Por exemplo, quando um usuário faz login. Agora, digamos que o usuário deseja criar um tópico no fórum, como vou saber se o usuário já está logado?

Pense nisso - deve haver um aperto de mão que informe à API "Criar fórum" que essa solicitação atual é de um usuário autenticado. Como as APIs REST normalmente são sem estado, o estado deve ser persistido algum lugar . Seu cliente que consome as APIs REST é responsável por manter esse estado. Geralmente, é na forma de algum token que é transmitido desde o momento em que o usuário fez login. Se o token for bom, sua solicitação será boa.

Verifique como o Amazon AWS faz autenticações. Esse é um exemplo perfeito de "passar a bola" de uma API para outra.

* Pensei em adicionar alguma resposta prática à minha resposta anterior. Experimente o Apache Shiro (ou qualquer biblioteca de autenticação / autorização). Resumindo, tente evitar a codificação personalizada. Depois de integrar sua biblioteca favorita (eu uso o Apache Shiro, btw), você pode fazer o seguinte:

  1. Crie uma API de logon / logout como: /api/v1/logineapi/v1/logout
  2. Nessas APIs de logon e logout, execute a autenticação com seu repositório de usuários
  3. O resultado é um token (geralmente, JSESSIONID ) que é enviado de volta ao cliente (Web, celular, qualquer que seja)
  4. A partir deste momento, todas as chamadas subsequentes feitas pelo seu cliente incluirão esse token
  5. Digamos que sua próxima ligação seja feita para uma API chamada /api/v1/findUser
  6. A primeira coisa que esse código de API fará é verificar o token ("este usuário está autenticado?")
  7. Se a resposta voltar como NÃO, você retornará um status HTTP 401 ao cliente. Deixe-os lidar com isso.
  8. Se a resposta for SIM, continue com o retorno do Usuário solicitado.

Isso é tudo. Espero que isto ajude.

Kingz
fonte
Então, o que você está descrevendo é essencialmente um cookie de sessão, certo?
LordOfThePigs
sim, mas a sessão é "mantida" em 2 locais diferentes. Um no servidor da API, outro no navegador. A resposta JSON (ou o que for) de volta ao navegador após o login bem-sucedido deve comunicar o ID da sessão no servidor da API de volta ao navegador. Essas sessões são gerenciadas independentemente por seus respectivos agentes.
Kingz
11
Acredito que Kingz estava tentando transmitir a idéia de que o mecanismo para manter a sessão é intencionalmente vago. Um cookie de sessão é apenas uma implementação desse mecanismo.
justin.hughey
2
@Kingz, e a segurança nesta solução, por exemplo, se algum hacker detectar o link com session_id e começar a enviar solicitações com o conteúdo correto session_id? Podemos resolvê-lo adicionando ssl à conexão do servidor, mas e os clientes?
Ahmad Samilo
1
como evitar o seqüestro de sessão no caso de man-in-the-middle-atrair?
M0z4rt
38
  1. Use HTTP Basic Auth para autenticar clientes, mas trate o nome de usuário / senha apenas como um token de sessão temporário .

    O token da sessão é apenas um cabeçalho anexado a toda solicitação HTTP, por exemplo: Authorization: Basic Ym9ic2Vzc2lvbjE6czNjcmV0

    A cadeia Ym9ic2Vzc2lvbjE6czNjcmV0 acima é apenas a cadeia "bobsession1: s3cret" (que é um nome de usuário / senha) codificada no Base64.

  2. Para obter o token de sessão temporário acima, forneça uma função de API (por exemplo http://mycompany.com/apiv1/login:) que use o nome de usuário mestre e a senha mestre como uma entrada, crie um nome de usuário / senha temporários de autenticação básica HTTP no lado do servidor e retorne o token (por exemplo: Ym9ic2Vzc2lvbjE6czNjcmV0). Esse nome de usuário / senha deve ser temporário e expirar após 20 minutos.

  3. Para segurança adicional, verifique se o serviço REST é servido por HTTPS, para que as informações não sejam transferidas em texto sem formatação

Se você estiver em Java, a biblioteca Spring Security fornece um bom suporte para implementar o método acima

gerrytan
fonte
1
Por que deveria expirar após 20 min? e se for um site como o facebook que o login seja até que o usuário efetue logout?
DeJell #
1
@dejel Eu estava sob o pressuposto de que "sessão" é de natureza temporária. É comum para que expirará se o usuário está em marcha lenta
gerrytan
Para que serve o Base64? Você pode simplesmente retornar a senha temporária. Nos dois casos, o que realmente importa é que essa senha temporária seja forte. Verifique security.stackexchange.com/a/19686/72945
e18r
7

Eu acho que a melhor abordagem é usar o OAuth2. Pesquise no Google e você encontrará muitas postagens úteis para ajudá-lo a configurá-lo.

Facilitará o desenvolvimento de aplicativos clientes para sua API a partir de um aplicativo da web ou móvel.

Espero que ajude você.

Paulo Henrique
fonte
2
Por favor, leia esta pergunta e a resposta de Les Hazelwood (autor de Apache Shiro).
Justin.hughey #
0

Eu tenho usado a autenticação JWT. Funciona muito bem no meu aplicativo.

Existe um método de autenticação que exigirá as credenciais do usuário. Este método valida as credenciais e retorna um token de acesso em caso de êxito.

Esse token deve ser enviado para todos os outros métodos da minha API da Web no cabeçalho da solicitação.

É muito fácil de implementar e muito fácil de testar.

Arthur Medeiros
fonte