Esta questão foi abordada, de uma forma ligeiramente diferente, detalhadamente aqui:
Autenticação RESTful
Mas isso aborda do lado do servidor. Vejamos isso do lado do cliente. Antes de fazer isso, porém, há um prelúdio importante:
O Javascript Crypto é impossível
O artigo de Matasano sobre isso é famoso, mas as lições nele contidas são muito importantes:
https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/
Para resumir:
- Um ataque man-in-the-middle pode substituir trivialmente seu código criptográfico por
<script>
function hash_algorithm(password){ lol_nope_send_it_to_me_instead(password); }</script>
- Um ataque man-in-the-middle é trivial contra uma página que serve qualquer recurso através de uma conexão não SSL.
- Depois de ter SSL, você estará usando criptografia real de qualquer maneira.
E para adicionar um corolário meu:
- Um ataque XSS bem-sucedido pode resultar em um invasor executando o código no navegador do seu cliente, mesmo se você estiver usando SSL - mesmo se você tiver todas as hachuras desativadas, a criptografia do navegador ainda poderá falhar se o invasor encontrar uma maneira de executar qualquer código javascript no navegador de outra pessoa.
Isso torna muitos esquemas de autenticação RESTful impossíveis ou tolos se você pretende usar um cliente JavaScript. Vamos olhar!
Autenticação básica HTTP
Em primeiro lugar, o HTTP Basic Auth. O mais simples dos esquemas: basta passar um nome e senha a cada solicitação.
Obviamente, isso exige absolutamente SSL, porque você passa um nome e uma senha codificados em Base64 (reversivelmente) a cada solicitação. Qualquer pessoa que escute na linha poderá extrair nome de usuário e senha trivialmente. A maioria dos argumentos "A autenticação básica é insegura" vem de um local "A autenticação básica sobre HTTP", que é uma péssima idéia.
O navegador fornece suporte básico à autenticação HTTP básica, mas é feio como o pecado e você provavelmente não deve usá-lo no seu aplicativo. A alternativa, porém, é esconder o nome de usuário e a senha em JavaScript.
Esta é a solução mais RESTful. O servidor não requer nenhum conhecimento do estado e autentica todas as interações individuais com o usuário. Alguns entusiastas do REST (principalmente homens de palha) insistem que manter qualquer tipo de estado é uma heresia e se espalhará pela boca se você pensar em outro método de autenticação. Existem benefícios teóricos para esse tipo de conformidade com os padrões - com o Apache pronto para uso - você pode armazenar seus objetos como arquivos em pastas protegidas por arquivos .htaccess, se desejar.
O problema ? Você está armazenando em cache no lado do cliente um nome de usuário e senha. Isso dá ao evil.ru uma solução melhor - mesmo as vulnerabilidades mais básicas do XSS podem resultar no cliente transferir seu nome de usuário e senha para um servidor inválido. Você pode tentar aliviar esse risco usando hash e salgando a senha, mas lembre-se: o JavaScript Crypto é impossível . Você pode aliviar esse risco deixando-o para o suporte de autenticação básica do navegador, mas feio como o pecado, como mencionado anteriormente.
Autenticação de resumo HTTP
A autenticação Digest é possível com o jQuery?
Uma autenticação mais "segura", este é um desafio de hash de solicitação / resposta. Exceto que o JavaScript Crypto é impossível , portanto, ele funciona apenas com SSL e você ainda precisa armazenar em cache o nome de usuário e a senha no lado do cliente, tornando-o mais complicado que o HTTP Basic Auth, mas não mais seguro .
Autenticação de consulta com parâmetros de assinatura adicionais.
Outra autenticação mais "segura", na qual você criptografa seus parâmetros com dados não temporários e de tempo (para proteger contra ataques de repetição e tempo) e envia o arquivo. Um dos melhores exemplos disso é o protocolo OAuth 1.0, que é, até onde eu sei, uma maneira bastante difícil de implementar a autenticação em um servidor REST.
http://tools.ietf.org/html/rfc5849
Ah, mas não há clientes OAuth 1.0 para JavaScript. Por quê?
JavaScript Crypto é impossível , lembre-se. O JavaScript não pode participar do OAuth 1.0 sem SSL, e você ainda precisa armazenar o nome de usuário e a senha do cliente localmente - o que o coloca na mesma categoria que o Digest Auth - é mais complicado que o HTTP Basic Auth, mas não é mais seguro .
Símbolo
O usuário envia um nome de usuário e senha e, em troca, recebe um token que pode ser usado para autenticar solicitações.
Isso é marginalmente mais seguro que o HTTP Basic Auth, porque assim que a transação de nome de usuário / senha é concluída, você pode descartar os dados confidenciais. Também é menos RESTful, pois os tokens constituem "estado" e tornam a implementação do servidor mais complicada.
Ainda SSL
O problema, porém, é que você ainda precisa enviar esse nome de usuário e senha iniciais para obter um token. Informações confidenciais ainda tocam no seu JavaScript comprometível.
Para proteger as credenciais do usuário, você ainda precisa manter os invasores fora do seu JavaScript e ainda precisa enviar um nome de usuário e senha pelo telefone. SSL obrigatório.
Expiração de token
É comum impor políticas de token como "ei, quando esse token já existe há muito tempo, descarte-o e faça o usuário se autenticar novamente". ou "Tenho certeza de que o único endereço IP permitido para usar esse token é XXX.XXX.XXX.XXX
". Muitas dessas políticas são boas idéias.
Firesheeping
No entanto, o uso de um token Without SSL ainda é vulnerável a um ataque chamado 'sidejacking': http://codebutler.github.io/firesheep/
O invasor não obtém as credenciais do usuário, mas ainda pode fingir ser seu usuário, o que pode ser muito ruim.
tl; dr: O envio de tokens não criptografados por cabo significa que os invasores podem facilmente pegá-los e fingir ser seu usuário. O FireSheep é um programa que facilita muito isso.
Uma zona separada e mais segura
Quanto maior o aplicativo em execução, mais difícil é garantir absolutamente que eles não possam injetar algum código que mude a maneira como você processa dados confidenciais. Você confia absolutamente no seu CDN? Seus anunciantes? Sua própria base de código?
Comum para detalhes de cartão de crédito e menos comum para nome de usuário e senha - alguns implementadores mantêm 'entrada de dados confidenciais' em uma página separada do restante do aplicativo, uma página que pode ser rigidamente controlada e bloqueada da melhor forma possível, de preferência uma que é difícil phishing usuários com.
Cookie (apenas significa Token)
É possível (e comum) colocar o token de autenticação em um cookie. Isso não altera nenhuma das propriedades de auth com o token, é mais uma coisa de conveniência. Todos os argumentos anteriores ainda se aplicam.
Sessão (ainda significa apenas token)
A autenticação de sessão é apenas autenticação de token, mas com algumas diferenças que fazem parecer uma coisa um pouco diferente:
- Os usuários começam com um token não autenticado.
- O back-end mantém um objeto 'state' vinculado ao token de um usuário.
- O token é fornecido em um cookie.
- O ambiente do aplicativo abstrai os detalhes de você.
Além disso, porém, não é diferente do Token Auth, na verdade.
Isso se afasta ainda mais de uma implementação RESTful - com objetos de estado, você está indo cada vez mais longe do caminho da RPC simples em um servidor com estado.
OAuth 2.0
O OAuth 2.0 analisa o problema de "Como o Software A concede ao Software B acesso aos dados do Usuário X sem que o Software B tenha acesso às credenciais de login do Usuário X".
A implementação é apenas uma maneira padrão de um usuário obter um token e, em seguida, de um serviço de terceiros "sim, esse usuário e esse token correspondem, e você pode obter alguns dos dados deles agora".
Fundamentalmente, porém, o OAuth 2.0 é apenas um protocolo de token. Ele exibe as mesmas propriedades que outros protocolos de token - você ainda precisa de SSL para proteger esses tokens - apenas altera a forma como esses tokens são gerados.
Há duas maneiras pelas quais o OAuth 2.0 pode ajudá-lo:
- Fornecendo autenticação / informações a terceiros
- Obtendo autenticação / informações de outras pessoas
Mas quando se trata disso, você está apenas ... usando tokens.
Voltar à sua pergunta
Portanto, a pergunta que você está perguntando é "devo armazenar meu token em um cookie e fazer com que o gerenciamento automático de sessões do meu ambiente cuide dos detalhes ou devo armazenar meu token em Javascript e lidar com esses detalhes sozinho?"
E a resposta é: faça o que te faz feliz .
O problema do gerenciamento automático de sessões é que há muita mágica acontecendo nos bastidores para você. Muitas vezes, é melhor controlar você mesmo esses detalhes.
Tenho 21 anos, então o SSL é sim
A outra resposta é: use https para tudo ou bandidos roubam as senhas e os tokens dos usuários.