Você pode me ajudar a entender isso? “Erros comuns do REST: as sessões são irrelevantes”

159

Isenção de responsabilidade: sou novo na escola de pensamento REST e estou tentando entender isso.

Portanto, estou lendo esta página, Common REST Mistakes , e descobri que estou completamente confuso com a seção sobre as sessões que são irrelevantes. É o que a página diz:

Não deve haver necessidade de um cliente "fazer login" ou "iniciar uma conexão". A autenticação HTTP é feita automaticamente em todas as mensagens. Os aplicativos clientes são consumidores de recursos, não de serviços. Portanto, não há nada para fazer login! Digamos que você esteja reservando um voo em um serviço da web REST. Você não cria uma nova conexão de "sessão" com o serviço. Em vez disso, você pede ao "objeto criador do itinerário" para criar um novo itinerário para você. Você pode começar a preencher os espaços em branco, mas depois obter um componente totalmente diferente em outro lugar na Web para preencher outros espaços em branco. Não há sessão, portanto não há problema em migrar o estado da sessão entre clientes. Também não há problema de "afinidade de sessão"

Ok, entendi que a autenticação HTTP é feita automaticamente em todas as mensagens - mas como? O nome de usuário / senha é enviado a cada solicitação? Isso não apenas aumenta a área de ataque? Sinto que estou perdendo parte do quebra-cabeça.

Seria ruim ter um serviço REST, por exemplo, /sessionque aceite uma solicitação GET, onde você passaria um nome de usuário / senha como parte da solicitação e retornaria um token de sessão se a autenticação fosse bem-sucedida, que poderia ser passado junto com solicitações subsequentes? Isso faz sentido do ponto de vista do REST ou está faltando esse ponto?

Roubar
fonte
toda solicitação é sempre autenticada, o seqüestro de sessão é uma coisa. repousante torna isso mais óbvio, mas não mais exposto.
Jasen

Respostas:

79

Para ser RESTful, cada solicitação HTTP deve conter informações suficientes por si só para que seu destinatário a processe para estar em completa harmonia com a natureza sem estado do HTTP.

Ok, entendi que a autenticação HTTP é feita automaticamente em todas as mensagens - mas como?

Sim, o nome de usuário e a senha são enviados a cada solicitação. Os métodos comuns para fazer isso são autenticação básica de acesso e autenticação de acesso digest . E sim, um bisbilhoteiro pode capturar as credenciais do usuário. Assim, criptografaria todos os dados enviados e recebidos usando o TLS (Transport Layer Security) .

Seria ruim ter um serviço REST, por exemplo, / session, que aceite uma solicitação GET, na qual você passaria um nome de usuário / senha como parte da solicitação e retornaria um token de sessão se a autenticação fosse bem-sucedida. ser passado junto com solicitações subsequentes? Isso faz sentido do ponto de vista do REST ou está faltando esse ponto?

Isso não seria RESTful, pois carrega estado, mas é bastante comum, pois é uma conveniência para os usuários; um usuário não precisa fazer login sempre.

O que você descreve em um "token de sessão" é geralmente chamado de cookie de login . Por exemplo, se você tentar fazer login no seu Yahoo! conta, há uma caixa de seleção que diz "mantenha-me conectado por 2 semanas". Isto é essencialmente dizer (em suas palavras) "mantenha meu token de sessão ativo por 2 semanas se eu fizer login com êxito". Os navegadores da Web enviarão esses cookies de login (e possivelmente outros) a cada solicitação HTTP solicitada.

z8000
fonte
5
Esta resposta não faz sentido para mim. Primeiro, ele diz que não há problema em passar o login e a senha a cada vez e, portanto, também uma vez, o que faz sentido. Em seguida, é sugerida a idéia de retornar ao cliente o estado de login bem-sucedido na forma de um token. Se necessário, o token pode codificar o horário da criação. Certamente, podemos devolver informações ao cliente. Então, essa sugestão me parece boa. A resposta diz que não está bem porque "carrega estado", mas não é a idéia de "ST" em "REST" que esse estado pode ser transferido entre o cliente e o servidor?
33

Não é incomum que um serviço REST exija autenticação para cada solicitação HTTP. Por exemplo, o Amazon S3 exige que cada solicitação tenha uma assinatura derivada das credenciais do usuário, da solicitação exata a ser executada e da hora atual. Essa assinatura é fácil de calcular no lado do cliente, pode ser verificada rapidamente pelo servidor e é de uso limitado para um invasor que a intercepta (já que se baseia no horário atual).

Greg Hewgill
fonte
3
+1, você pode especificar: é de uso limitado para um invasor que o intercepta (já que é baseado no horário atual) ? você não está falando de um cookie que contém nome de usuário e senha criptografados? assim faz? (IMHO)
Royi Namir
2
@RoyiNamir: Eu não estou falando de um cookie. A assinatura usada pelo S3 é um parâmetro para a solicitação HTTP, mas não é um cookie, é recalculada para cada solicitação.
amigos estão dizendo sobre greg hewgill
Então, se eu precisar salvar algumas informações sobre um usuário, onde eu as salvaria? em db? Eu não quero ir cada pedido para db .... e ainda quero usar o resto .... você pode por favor ajudar?
Royi Namir
@RoyiNamir: Se você tiver perguntas específicas sobre como atingir algum objetivo, faça uma nova pergunta . Não posso responder a perguntas adicionais aqui nos comentários.
precisa saber é o seguinte
10

Muitas pessoas não entendem os princípios do REST de maneira muito clara, o uso de um token de sessão nem sempre significa que você tem estado, o motivo para enviar nome de usuário / senha com cada solicitação é apenas para autenticação e o mesmo para o envio de um token (gerado pelo login processo) apenas para decidir se o cliente tem permissão para solicitar dados ou não, você só viola as convenções REST quando usa tokens de nome de usuário / senha ou sessão para decidir quais dados serão exibidos! em vez disso, você deve usá-los apenas para autenticação (para mostrar dados ou não)

no seu caso, digo SIM, isso é RESTy, mas tente evitar o uso de sessões nativas de php na API REST e comece a gerar seus próprios tokens de hash que expiram em determinado período de tempo!

EvilThinker
fonte
1
obrigado. por que evitar uma sessão php nativa e usar tokens de hash próprios?
Matthew
não por qualquer motivo brilhante, digo, apenas por mais segurança e mais controle.
EvilThinker
Isso é melhor que a resposta aceita. No mínimo, aceita a sugestão como RESTy, o que faz sentido. No entanto, não vejo por que as informações passadas não podem ser usadas para autorizar dependentes do usuário. Alguns usuários podem ter acesso a alguns dados e outros não. Isso não torna o protocolo não RESTful.
8

Não, não está errado. O ClientLogin do Google funciona exatamente dessa maneira, com a notável exceção de que o cliente é instruído a ir para a "/ sessão" usando uma resposta HTTP 401. Mas isso não cria uma sessão, apenas cria uma maneira de os clientes se autenticarem (temporariamente) sem passar as credenciais de forma clara e de o servidor controlar a validade dessas credenciais temporárias, conforme entender.

mogsie
fonte
11
@ unlgiven3 Desde que o token retornado seja usado apenas para autenticar o usuário e não usado pelo servidor para associá-lo a outro estado armazenado no servidor, não vejo nenhuma restrição REST sendo violada.
Darrel Miller
4
@ Ungiven3 O token retornado pelo servidor é, na verdade, uma prova de que o usuário é quem ele diz ser. Portanto, em vez de cada solicitação, incluindo nome de usuário e senha, cada solicitação inclui o token construído de forma que o servidor possa ter certeza de sua veracidade.
Darrel Miller
1
@ unfgiven3, Darrel está certo. O token ecoado de volta teria que ser enviado pelo cliente em todas as solicitações HTTP, assim como na autenticação básica, digerir, até que o token expire. Quando isso acontece, o cliente pode repetir o logon, solicitando opcionalmente credenciais ao usuário ou o que for. Eu poderia elaborar a resposta, se você quiser. edit: (E obrigado por mantendo-se com as respostas às perguntas de idade!)
mogsie
1
Sem problemas, mogsie, sempre interessante discutir esses tipos de coisas :-) Acho que vejo aonde vocês estão indo com isso, infelizmente eu simplesmente não entendo o suficiente sobre autenticação Digest para realmente entender isso (na maioria das vezes eu simplesmente não entendo). entender como o token é enviado de volta a cada solicitação HTTP, mas isso parece ser um detalhe de implementação). No entanto, agora vejo por que esse método não viola os princípios REST. Obrigado pelas respostas!
Rob
6
@ Ungiven3, Isso pode ajudar: o token é uma informação assinada. Portanto, é independente. O servidor pode validar o token sem verificar um estado armazenado anteriormente. Portanto, é apenas um estado que é armazenado no cliente e transferido para frente e para trás.
Iravanchi
5

Ok, entendi que a autenticação HTTP é feita automaticamente em todas as mensagens - mas como?

"Autorização:" cabeçalho HTTP enviado pelo cliente. Básico (texto simples) ou resumo.

Seria ruim ter um serviço REST, por exemplo, / session, que aceite uma solicitação GET, na qual você passaria um nome de usuário / senha como parte da solicitação e retornaria um token de sessão se a autenticação fosse bem-sucedida. ser passado junto com solicitações subsequentes? Isso faz sentido do ponto de vista do REST ou está faltando esse ponto?

Toda a idéia de sessão é fazer com estado aplicações utilizando protocolo sem estado (HTTP) e cliente mudo (web browser), mantendo o estado no lado do servidor. Um dos princípios do REST é "Todo recurso é endereçável exclusivamente usando uma sintaxe universal para uso em links hipermídia" . Variáveis ​​de sessão são algo que não pode ser acessado via URI. O aplicativo verdadeiramente RESTful manteria o estado no lado do cliente, enviando todas as variáveis ​​necessárias por HTTP, preferencialmente no URI.

Exemplo: pesquise com paginação. Você teria URL no formulário

http://server/search/urlencoded-search-terms/page_num

Tem muito em comum com URLs que podem ser marcados como favoritos

vartec
fonte
4
As informações de autenticação também não podem ser acessadas via URI - todo mundo está falando sobre o envio de informações de autenticação como parte do cabeçalho da solicitação. Qual é a diferença de incluir um token de sessão com a solicitação? Não estou dizendo para usar o token de sessão no URI, mas nos dados passados ​​na solicitação.
1300 Rob
A autenticação estabelece se você está autorizado a executar essa ação e no aplicativo RESTful não afetaria seu resultado.
22139 vartec
4
Um token de sessão também estabelece se você está autorizado a executar essa ação. Como assim, não afetaria o resultado? Se o chamador não estiver autorizado, ele receberá um erro Não autorizado. A mesma coisa com um token de sessão. Eu realmente não vejo a diferença?
1300 Rob
3
Não, o token de sessão é um identificador para indicar o estado salvo no servidor. Isso simplesmente não é RESTful. Quanto aos não autorizados, não vejo isso como resultado. Prefiro considerar isso uma exceção (como em try / catch).
vartec
Justo, vartec - isso faz sentido. Obrigado pelo seguimento!
1700 Rob
3

Acho que sua sugestão está correta, se você deseja controlar o tempo de vida da sessão do cliente. Eu acho que a arquitetura RESTful incentiva você a desenvolver aplicativos sem estado. Como o @ 2pence escreveu "cada solicitação HTTP deve conter informações suficientes por si só para que seu destinatário a processe para estar em completa harmonia com a natureza sem estado do HTTP" .

No entanto, nem sempre é esse o caso, às vezes o aplicativo precisa informar quando o cliente faz logon ou logout e manter recursos como bloqueios ou licenças com base nessas informações. Veja minha pergunta de acompanhamento para um exemplo desse caso.

LiorH
fonte