O uso de sessões em uma API RESTful realmente viola o RESTfulness? Tenho visto muitas opiniões indo em qualquer direção, mas não estou convencido de que as sessões sejam RESTless . Do meu ponto de vista:
- a autenticação não é proibida para RESTfulness (caso contrário, haveria pouco uso nos serviços RESTful)
- a autenticação é feita enviando um token de autenticação na solicitação, geralmente o cabeçalho
- esse token de autenticação precisa ser obtido de alguma forma e pode ser revogado; nesse caso, ele precisa ser renovado
- o token de autenticação precisa ser validado pelo servidor (caso contrário, não seria autenticação)
Então, como as sessões violam isso?
- do lado do cliente, as sessões são realizadas usando cookies
- cookies são simplesmente um cabeçalho HTTP extra
- um cookie de sessão pode ser obtido e revogado a qualquer momento
- os cookies de sessão podem ter uma vida útil infinita, se necessário
- o ID da sessão (token de autenticação) é validado no servidor
Como tal, para o cliente, um cookie de sessão é exatamente o mesmo que qualquer outro mecanismo de autenticação baseado em cabeçalho HTTP, exceto pelo uso do Cookie
cabeçalho em vez do Authorization
cabeçalho proprietário ou de algum outro cabeçalho proprietário. Se não havia nenhuma sessão anexada ao valor do cookie do lado do servidor, por que isso faria diferença? A implementação do lado do servidor não precisa preocupar o cliente, desde que o servidor se comporte com RESTful. Como tal, os cookies por si só não devem tornar uma API RESTless , e as sessões são simplesmente cookies para o cliente.
Minhas suposições estão erradas? O que torna os cookies de sessão RESTless ?
Respostas:
Primeiro, vamos definir alguns termos:
Repousante:
de acordo com a wikipedia .
restrição apátrida:
de acordo com a dissertação de Fielding .
Portanto, as sessões do servidor violam a restrição sem estado do REST e também o RESTfulness.
Por cookies de sessão, você armazena o estado do cliente no servidor e, portanto, sua solicitação tem um contexto. Vamos tentar adicionar um balanceador de carga e outra instância de serviço ao seu sistema. Nesse caso, você precisa compartilhar as sessões entre as instâncias de serviço. É difícil manter e estender esse sistema, por isso é muito ruim ...
Na minha opinião, não há nada errado com os cookies. A tecnologia de cookies é um mecanismo de armazenamento do lado do cliente, no qual os dados armazenados são anexados automaticamente aos cabeçalhos de cookies a cada solicitação. Não conheço uma restrição REST que tenha problemas com esse tipo de tecnologia. Portanto, não há problema com a própria tecnologia, o problema é com seu uso. Fielding escreveu uma subseção sobre por que ele acha que os cookies HTTP são ruins.
Seu ponto de vista foi bastante sólido. O único problema foi com o conceito de criação de token de autenticação no servidor. Você não precisa dessa parte. O que você precisa é armazenar nome de usuário e senha no cliente e enviá-lo com todas as solicitações. Você não precisa fazer mais do que autenticação básica HTTP e uma conexão criptografada:
Você provavelmente precisará de um cache de autenticação na memória no servidor para agilizar as coisas, pois é necessário autenticar todas as solicitações.
Agora, isso funciona muito bem por clientes confiáveis escritos por você, mas e quanto a clientes de terceiros? Eles não podem ter o nome de usuário e senha e todas as permissões dos usuários. Portanto, você deve armazenar separadamente quais permissões um cliente de terceiros pode ter por um usuário específico. Assim, os desenvolvedores do cliente podem registrar clientes de terceiros e obter uma chave de API exclusiva e os usuários podem permitir que clientes de terceiros acessem parte de suas permissões. Como ler o nome e endereço de e-mail ou listar seus amigos, etc ... Depois de permitir um cliente de terceiros, o servidor gerará um token de acesso. Esses tokens de acesso podem ser usados pelo cliente de terceiros para acessar as permissões concedidas pelo usuário, como:
Portanto, o cliente de terceiros pode obter o token de acesso de um cliente confiável (ou diretamente do usuário). Depois disso, ele pode enviar uma solicitação válida com a chave da API e o token de acesso. Esse é o mecanismo de autenticação de terceiros mais básico. Você pode ler mais sobre os detalhes da implementação na documentação de todos os sistemas de autenticação de terceiros, por exemplo, OAuth. É claro que isso pode ser mais complexo e mais seguro, por exemplo, você pode assinar os detalhes de cada solicitação no lado do servidor e enviar a assinatura junto com a solicitação, e assim por diante ... A solução real depende da necessidade do seu aplicativo.
fonte
Primeiro de tudo, o REST não é uma religião e não deve ser abordado como tal. Embora existam vantagens nos serviços RESTful, você deve seguir apenas os princípios do REST, na medida em que façam sentido para o seu aplicativo.
Dito isto, autenticação e estado do lado do cliente não violam os princípios REST. Embora o REST exija que as transições de estado sejam sem estado, isso se refere ao próprio servidor. No coração, todo o REST é sobre documentos. A idéia por trás da apatridia é que o SERVIDOR é apátrida, não os clientes. Qualquer cliente que emita uma solicitação idêntica (mesmos cabeçalhos, cookies, URI, etc.) deve ser levado para o mesmo local no aplicativo. Se o site armazenasse o local atual do usuário e a navegação gerenciada atualizando essa variável de navegação no servidor, o REST seria violado. Outro cliente com informações de solicitação idênticas seria levado para um local diferente, dependendo do estado do servidor.
Os serviços web do Google são um exemplo fantástico de um sistema RESTful. Eles exigem que um cabeçalho de autenticação com a chave de autenticação do usuário seja passado a cada solicitação. Isso viola ligeiramente os princípios REST, porque o servidor está rastreando o estado da chave de autenticação. O estado dessa chave deve ser mantido e possui algum tipo de data / hora de vencimento após o qual não concede mais acesso. No entanto, como mencionei na parte superior da minha postagem, sacrifícios devem ser feitos para permitir que um aplicativo realmente funcione. Dito isso, os tokens de autenticação devem ser armazenados de forma a permitir que todos os clientes possíveis continuem concedendo acesso durante seus períodos válidos. Se um servidor estiver gerenciando o estado da chave de autenticação até o ponto em que outro servidor com balanceamento de carga não puder assumir as solicitações com base nessa chave, você começou realmente a violar os princípios do REST. Os serviços do Google garantem que, a qualquer momento, você possa pegar um token de autenticação que estava usando no telefone no servidor de equilíbrio de carga A e acessar o servidor de equilíbrio de carga B na área de trabalho e ainda ter acesso ao sistema e ser direcionado aos mesmos recursos se os pedidos eram idênticos.
O que tudo se resume é que você precisa garantir que seus tokens de autenticação sejam validados em um armazenamento de backup de algum tipo (banco de dados, cache, o que for) para garantir a preservação do maior número possível de propriedades REST.
Espero que tudo isso faça sentido. Você também deve verificar a seção Restrições do artigo da wikipedia sobre Representational State Transfer, se ainda não o tiver feito. É particularmente esclarecedor sobre o que os princípios do REST estão realmente argumentando e por quê.
fonte
Os cookies não são para autenticação. Por que reinventar uma roda? O HTTP possui mecanismos de autenticação bem projetados. Se usarmos cookies, passamos a usar o HTTP apenas como protocolo de transporte; portanto, precisamos criar nosso próprio sistema de sinalização, por exemplo, para informar aos usuários que eles forneceram autenticação incorreta (o HTTP 401 estaria incorreto, como provavelmente não fornecer
Www-Authenticate
a um cliente, pois as especificações HTTP requerem :)). Note-se também queSet-Cookie
é apenas uma recomendação para o cliente. Seu conteúdo pode ou não ser salvo (por exemplo, se os cookies estiverem desabilitados), enquanto oAuthorization
cabeçalho é enviado automaticamente a cada solicitação.Outro ponto é que, para obter um cookie de autorização, você provavelmente desejará fornecer suas credenciais em algum lugar primeiro? Se sim, não seria RESTless? Exemplo simples:
GET /a
sem cookiePOST /auth
Set-Cookie
GET /a
com cookie. Mas seGET /a
comporta idempotentemente neste caso?Para resumir, acredito que, se acessarmos algum recurso e precisarmos autenticar, devemos autenticar nesse mesmo recurso , e não em nenhum outro lugar.
fonte
Authorization: Basic
ouDigest
. Se você deseja fazer algo mais avançado do que autenticação básica ou resumida (e deve) em um contexto de navegador, precisará de algo diferente doAuthorization
cabeçalho.GET /a
sem cookie e com cookie são claramente duas solicitações diferentes e é aceitável que elas se comportem de maneira diferente.GET /a
cabeçalho de autenticação também é o mesmo queGET /a
o cabeçalho de autenticação, tornando-o igualmente inutilizável para o REST. Se você vai tratar um cabeçalho http de maneira diferente de outro, abordará isso no mínimo.Na verdade, RESTfulness se aplica apenas a RECURSOS, conforme indicado por um Universal Resource Identifier. Portanto, falar sobre coisas como cabeçalhos, cookies etc. em relação ao REST não é realmente apropriado. O REST pode funcionar com qualquer protocolo, mesmo que isso seja feito rotineiramente por HTTP.
O principal determinante é o seguinte: se você enviar uma chamada REST, que é um URI, depois que a chamada chegar com êxito ao servidor, esse URI retornará o mesmo conteúdo, assumindo que nenhuma transição tenha sido executada (PUT, POST, DELETE) ? Esse teste excluiria o retorno de erros ou solicitações de autenticação, pois, nesse caso, a solicitação ainda não foi enviada ao servidor, ou seja, o servlet ou aplicativo que retornará o documento correspondente ao URI fornecido.
Da mesma forma, no caso de um POST ou PUT, você pode enviar um determinado URI / carga útil e, independentemente de quantas vezes você envia a mensagem, ela sempre atualiza os mesmos dados, para que os GETs subsequentes retornem um resultado consistente?
O REST é sobre os dados do aplicativo, não sobre as informações de baixo nível necessárias para transferir esses dados.
Na seguinte postagem no blog, Roy Fielding deu um bom resumo de toda a ideia REST:
http://groups.yahoo.com/neo/groups/rest-discuss/conversations/topics/5841
"Um sistema RESTful progride de um estado estacionário para o próximo, e cada um desses estados estáveis é um estado inicial potencial e um estado final potencial. Ou seja, um sistema RESTful é um número desconhecido de componentes que obedecem a um conjunto simples de regras de modo que elas sempre estejam no REST ou em transição de um estado RESTful para outro estado RESTful Cada estado pode ser completamente compreendido pela (s) representação (ões) que ele contém e pelo conjunto de transições que ele fornece, com as transições limitadas a um uniforme conjunto de ações para ser compreensível.O sistema pode ser um diagrama de estados complexo, mas cada agente do usuário só pode ver um estado de cada vez (o estado estacionário atual) e, portanto, cada estado é simples e pode ser analisado independentemente. usuário, OTOH, pode criar suas próprias transições a qualquer momento (por exemplo, digite um URL, selecione um marcador,abra um editor, etc.) ".
Indo para a questão da autenticação, seja ela realizada por meio de cookies ou cabeçalhos, desde que as informações não façam parte da carga útil do URI e POST, ela realmente não tem nada a ver com o REST. Portanto, em relação ao estado sem estado, estamos falando apenas dos dados do aplicativo.
Por exemplo, quando o usuário digita dados em uma tela da GUI, o cliente mantém o controle de quais campos foram inseridos, quais não, campos obrigatórios ausentes etc. Isso é tudo CONTEXTO DO CLIENTE e não deve ser enviado ou rastreado pelo servidor. O que é enviado ao servidor é o conjunto completo de campos que precisam ser modificados no recurso IDENTIFIED (pelo URI), de modo que ocorra uma transição nesse recurso de um estado RESTful para outro.
Portanto, o cliente acompanha o que o usuário está fazendo e envia apenas transições de estado logicamente completas para o servidor.
fonte
A transação HTTP, autenticação de acesso básico, não é adequada para o RBAC, porque a autenticação de acesso básico usa sempre o nome de usuário criptografado: password para identificar, enquanto o que é necessário no RBAC é a função que o usuário deseja usar para uma chamada específica. O RBAC não valida permissões no nome de usuário, mas nas funções.
Você pode tentar concatenar assim: usernameRole: password, mas isso é uma prática ruim e também é ineficiente porque, quando um usuário tem mais funções, o mecanismo de autenticação precisaria testar todas as funções na concatenação e todas as chamadas novamente. Isso destruiria uma das maiores vantagens técnicas do RBAC, a saber, um teste de autorização muito rápido.
Portanto, esse problema não pode ser resolvido usando a autenticação de acesso básica.
Para resolver esse problema, a manutenção da sessão é necessária e isso parece, de acordo com algumas respostas, em contradição com o REST.
É disso que eu gosto na resposta de que o REST não deve ser tratado como religião. Em casos comerciais complexos, na área da saúde, por exemplo, o RBAC é absolutamente comum e necessário. E seria uma pena se eles não pudessem usar o REST porque todos os designers de ferramentas REST tratariam o REST como uma religião.
Para mim, não há muitas maneiras de manter uma sessão por HTTP. Pode-se usar cookies, com um sessionId, ou um cabeçalho com um sessionId.
Se alguém tiver outra idéia, ficarei feliz em ouvi-la.
fonte
Acho que o token deve incluir todas as informações necessárias codificadas dentro dele, o que faz a autenticação validando o token e decodificando as informações https://www.oauth.com/oauth2-servers/access-tokens/self-encoded-access-tokens/
fonte
fonte