ti-enxame.com

Como manter os aplicativos sem estado

Essa pode ser uma pergunta complicada, mas estou tentando entender melhor a apatridia.

Com base no que li, os aplicativos da web devem ser sem estado, o que significa que cada solicitação é tratada como uma transação independente. Como resultado, a sessão e os cookies devem ser evitados (pois ambos são válidos). Uma abordagem melhor é usar tokens, sem estado, porque nada é armazenado no servidor.

Então, estou tentando entender como os aplicativos da Web podem ser sem estado quando há dados que estão sendo mantidos para minha sessão (como itens em um carrinho de compras)? Eles estão realmente sendo armazenados em um banco de dados em algum lugar e, em seguida, são eliminados periodicamente? Como isso funciona quando você usa um token em vez de cookies?

E então, como uma pergunta relacionada, os principais sites (Amazon, Google, Facebook, Twitter etc.) são realmente sem estado? Eles usam tokens ou cookies (ou ambos)?

100
user253058

"os aplicativos da web devem ser sem estado" devem ser entendidos como "os aplicativos da web devem ser sem estado, a menos que haja um motivo muito bom para ter estado". Um "carrinho de compras" é um recurso importante por design, e negar isso é contraproducente. O objetivo principal do padrão de carrinho de compras é preservar o estado do aplicativo entre solicitações.

Uma alternativa que eu poderia imaginar como um site sem estado que implementa um carrinho de compras seria um aplicativo de página única que mantém o carrinho de compras completamente do lado do cliente, recupera as informações do produto com AJAX chama e envia para o servidor de uma só vez quando o usuário faz um checkout, mas duvido que já tenha visto alguém fazer isso, porque não permite que o usuário use várias guias do navegador e não ' preservar o estado ao fechar acidentalmente a guia.Claro, existem soluções alternativas, como usar armazenamento local, mas você terá o estado novamente, apenas no cliente e não no servidor.

Sempre que você tiver um aplicativo Web que exija a persistência de dados entre exibições de página, você geralmente fará isso apresentando sessões. A sessão à qual uma solicitação pertence pode ser identificada por um cookie ou por um parâmetro de URL que você adiciona a cada link. Os cookies devem ser preferidos, pois mantêm seus URLs mais acessíveis e impedem que o usuário compartilhe acidentalmente um URL com o ID da sessão. Mas ter tokens de URL como substituto também é vital para usuários que desativam cookies. A maioria das estruturas de desenvolvimento da web possui um sistema de manipulação de sessões que pode fazer isso imediatamente.

No lado do servidor, as informações da sessão geralmente são armazenadas em um banco de dados. O cache na memória do servidor é opcional. Isso pode melhorar bastante o tempo de resposta, mas não permitirá a transferência de sessões entre diferentes servidores. Portanto, você precisará de um banco de dados persistente como substituto.

os principais sites (Amazon, Google, Facebook, Twitter etc.) são realmente apátridas? Eles usam tokens ou cookies (ou ambos)?

Eles permitem que você faça login? Quando você fecha a guia e revisita o site, você ainda está logado? Se estiver, eles estão usando cookies para preservar sua identidade entre as sessões.

97
Philipp

É verdade que os aplicativos da web devem ser sem estado. No entanto, variáveis ​​de sessão, cookies e tokens não violam isso quando estão todos armazenados no cliente (navegador da web). Eles podem ser parâmetros na solicitação.

Aqui está um modelo simplificado:

Web Browser (has state) <-> Web Server (stateless) <-> Database (has state)

Isso pode funcionar para Software Engineering Stack Exchange. Esta resposta que estou digitando faz parte do estado do meu navegador. Contanto que esse seja o único lugar onde está, não estará acessível a ninguém além de mim. Mas assim que eu apertei Post your Answer meu navegador envia para o servidor web. O servidor da Web processa a postagem sem nenhum estado próprio. Ele aprende quem eu sou do meu navegador e do banco de dados. Depois de verificar minha postagem e adicioná-la ao banco de dados, o servidor da Web se esquece imediatamente de mim.

Isso é o que significa apátrida. O servidor não é responsável por lembrar de nada disso. Esse não é o seu trabalho.

Fazer isso tem muitas vantagens. Se o servidor da Web tiver um vazamento de memória, é detectável, pois seu espaço de memória não deve aumentar. Se o servidor da web travar, minha identidade não o acompanha. Se alguém tentar fazer um ataque de negação de serviço, não poderá usar os recursos de estado do servidor da Web para fazê-lo, porque o servidor da Web não aloca nenhum estado para ele entre as sessões. Tudo isso visa tornar o servidor da web estável. Dessa forma, quando começa a correr, continua a correr.

Agora, com certeza, estou consumindo recursos no banco de dados, mas esses recursos foram verificados pela minha permissão por algo estável, com o qual podemos contar para proteger o banco de dados da Web selvagem e confusa: o servidor Web sem estado e que impõe regras de negócios.

59
candied_orange

aplicativos da web devem ser sem estado

Bobagem. Solicitações da Web devem ser sem estado. Ou, mais precisamente, solicitações da Web são sem estado.

Mas dizer que um aplicativo inteiro deve ser sem estado é um absurdo completo.

cada solicitação é tratada como uma transação independente.

Sim, exatamente . Ou com mais precisão, sim, necessariamente . Sobre HTTP, cada solicitação é inerentemente independente de todas as outras solicitações. Adicionar "statefulness" ao HTTP requer que você identifique, armazene e recupere explicitamente "state" para cada solicitação "stateful". E isso exige esforço, diminui o desempenho e aumenta a complexidade.

E, por esses motivos, cada solicitação que pode ser apátrida "deve" ser apátrida.

Como resultado, a sessão e os cookies devem ser evitados (pois os dois têm estado). Uma abordagem melhor é usar tokens

Algumas coisas: os tokens também podem ser vinculados ao armazenamento da sessão. Os cookies não precisam estar vinculados ao armazenamento da sessão. Os tokens geralmente são armazenados em cookies. E, às vezes, uma sessão é simplesmente a ferramenta certa para o trabalho.

Isso significa que pelo menos às vezes , sessões e cookies são tão "melhores" quanto os tokens!

[Tokens] são sem estado porque nada é armazenado no servidor.

Bem, é isso. É disso que se trata o dogma da "apatridia". Embora, para ficar claro, não se trata de armazenar "nada" no servidor, trata-se de não armazenar o estado da sessão no servidor.

Minha caixa de entrada do Gmail está em um estado, por exemplo. E muito bem melhor ser armazenado no servidor! Mas, não é o estado da sessão .

Portanto, em vez de ter servidores que podem pegar um pequeno identificador e descobrir quem você é e assim por diante, os aplicativos sem estado desejam ser lembrados com quem você é e com o que está fazendo a cada sangrento request. O estado do aplicativo ainda existe, o cliente é apenas responsável por mantê-lo.

Agora, se esse estado é pequeno, provavelmente está bom. Em alguns casos, é muito bom.

E então, é claro, há coisas que simplesmente esperamos ser com estado ...

como os aplicativos da web podem ser apátridas quando existem dados que estão sendo mantidos para minha sessão (como itens em um carrinho de compras)? Eles estão realmente sendo armazenados em um banco de dados em algum lugar e depois são periodicamente limpos?

Duas opções. Ou você tem uma sessão ou está em negação!

... Mas seriamente. Você normalmente não armazenaria um carrinho em um cookie. Algo como um carrinho de compras será armazenado em uma sessão "tradicional" ou será armazenado como um objeto Cart, com algum tipo de ID que o servidor usa para puxá-lo para solicitações subsequentes. Como uma sessão .. uhh ... ... err ... .

A sério: existe um grande grau em que "estado" é exatamente o que chamamos quando dois agentes de comunicação podem contextualizar mensagens em uma conversa. E uma sessão, tradicionalmente entendida, é exatamente o que normalmente chamamos de mecanismo pelo qual isso ocorre.

Eu argumentaria que, independentemente de você usar tokens ou "sessões" para cada solicitação que o servidor manipula, você precisa contextualizar essa solicitação para atendê-la ou não. Se o contexto não for necessário, não o obtenha. Se o contexto é necessário, é melhor você tê-lo por perto!

E então, como uma pergunta relacionada, os principais sites (Amazon, Google, Facebook, Twitter etc.) são realmente sem estado? Eles usam tokens ou cookies (ou ambos)?

Provavelmente ambos. Mas, de um modo geral, eles fazem exatamente o que você faz: configuram cookies para identificar registros de "estado" em bancos de dados maciços de "sessões".

Quando possível, desconfio que eles inserem declarações básicas de identidade em "tokens" de vida curta para evitar disputas desnecessárias no armazenamento centralizado. Porém, o fato de muitos desses serviços me permitirem "sair de todos os outros locais" é um bom indicador de que, se eles estão usando tokens, eles são pelo menos "suportados" por um modelo de sessão semi-tradicional .

30
svidgen

O estado não é necessariamente uma coisa ruim, mas é preciso entender a diferença entre aplicativos com estado e sem estado. Em resumo, os aplicativos com estado mantêm informações sobre a sessão atual, e os sem estado não. As informações armazenadas permanentemente como parte de uma conta de usuário podem ou não ser armazenadas em uma sessão, mas o armazenamento de informações relacionadas a uma conta de usuário não torna o aplicativo por si só. A condição de estado exige que o servidor mantenha informações sobre a sessão do usuário atual além do que o navegador do cliente está mantendo. Por exemplo, um cliente pode autenticar e receber um cookie JSESSIONID, que é enviado ao servidor a cada solicitação. Se o servidor começar a armazenar itens no escopo da sessão do aplicativo com base neste JSESSIONID, ele se tornará com estado.

Apatridia

Por apátrida, queremos dizer que o servidor e o cliente não estão mantendo informações atuais sobre a sessão do usuário. O cliente e o servidor podem usar algum tipo de token para fornecer autenticação entre solicitações, mas nenhuma outra informação atual é armazenada. Um caso de uso típico para essa solução pode ser um site de notícias em que a maioria dos usuários (novos consumidores) consome informações, mas não produz informações que retornam ao site. Nesses casos, o site não precisa manter nenhuma informação sobre a sessão atual do usuário. Observe que o site ainda pode usar cookies para identificar o usuário e armazenar informações sobre o uso desse site pelo usuário, mas isso ainda pode ser considerado sem estado, pois tudo o que foi registrado pode ser transacional, por exemplo. qual link o usuário clicou, que pode ser gravado pelo servidor, mas não mantido em uma sessão do usuário.

Statefulness no servidor

No servidor, um aplicativo com estado salva as informações de estado sobre os usuários atuais. Essa abordagem geralmente envolve o uso de cookies para identificar o sistema do usuário, para que o estado possa ser mantido no servidor entre solicitações. As sessões podem ou não ser autenticadas, dependendo do contexto do aplicativo. Os aplicativos de servidor com estado oferecem a vantagem de armazenar em cache as informações de estado do usuário no servidor, acelerando as pesquisas e o tempo de resposta da página. No lado negativo, armazenar informações no escopo da sessão é caro e, em escala, torna-se muito intensivo em recursos. Ele também cria um vetor de ataque em potencial para os hackers tentarem seqüestrar identificadores de sessão e roubar sessões do usuário. Os aplicativos de servidor com estado também têm o desafio de proteger as sessões do usuário contra interrupções inesperadas de serviço, por exemplo, uma falha no servidor. Uma solução comum para esse problema é agrupar sessões em um cluster de máquinas servidores, mas, novamente, em escala, rapidamente se torna impraticável agrupar todas as sessões em todas as máquinas.

Statefulness no cliente

Usando JavaScript e tecnologias modernas de navegador como o sessionStorage, o aplicativo agora pode armazenar facilmente informações de estado sobre uma sessão do usuário no dispositivo desse usuário. No geral, o aplicativo ainda pode ser considerado com estado, mas o trabalho de manter o estado foi movido para o cliente. Essa abordagem tem uma grande vantagem (para o mantenedor do aplicativo Web) sobre a manutenção do estado no servidor, pois cada usuário está, de fato, mantendo seu próprio estado e não há ônus na infraestrutura do servidor. Em escala web, esse tipo de escolha arquitetônica tem enormes repercussões nos custos de hardware e eletricidade. Poderia literalmente custar milhões de dólares por ano para manter o estado no servidor. Mudar para um sistema que mantém o estado no cliente pode economizar milhões de dólares por ano.

Tokens vs. cookies

Os cookies atuam como identificadores para dispositivos/navegadores clientes. Eles podem ser usados ​​para armazenar todo tipo de coisas, mas geralmente armazenam algum tipo de identificador, como CFID/CFTOKEN em aplicativos CFML. Os cookies podem ser configurados para permanecer no navegador do usuário por um longo período de tempo, possibilitando ações como manter a autenticação em um aplicativo entre as sessões do navegador. Os cookies também podem ser configurados para somente memória, para que expirem quando um usuário fecha o navegador.

Os tokens geralmente são algum tipo de informação de identificação sobre o usuário que é gerada no servidor (usando criptografia para embaralhar as informações), transmitida ao cliente e retornada ao servidor com a solicitação subsequente. Eles podem ser passados ​​no cabeçalho da solicitação e resposta, que é um padrão comum em aplicativos de página única. Idealmente, cada solicitação/resposta resulta na geração de um novo token, para que os tokens não possam ser interceptados e usados ​​posteriormente por um invasor.

Aplicativos de página única e estado do cliente

Com os SPAs, as informações de estado são carregadas no navegador do cliente e mantidas lá. Quando o estado muda, p. Se você postar uma atualização em sua conta de mídia social, o cliente retransmitirá essa nova transação para o servidor. Nesse caso, o servidor salva essa atualização em um armazenamento de dados persistente, como um banco de dados, e retransmite para o cliente todas as informações necessárias para sincronizar com o servidor com base na atualização (por exemplo, um ID para a atualização).

Observe que esse padrão de estado de armazenamento no cliente oferece vantagens para experiências online/offline, pois você pode ser desconectado do servidor enquanto ainda possui um aplicativo que pode ser utilizado. O Twitter é um bom exemplo desse caso, no qual você pode revisar qualquer coisa carregada do lado do cliente em seu feed do Twitter, mesmo se estiver desconectado do aplicativo do servidor do Twitter. Esse padrão também cria complexidade na sincronização entre servidor e cliente, que é todo um assunto próprio. As complexidades da solução são uma desvantagem por poder manter o estado no cliente.

O estado do cliente faz com que os aplicativos da Web se sintam e se comportem mais como os aplicativos de desktop tradicionais. Ao contrário dos aplicativos de desktop, normalmente você não terá todas as informações da sua conta carregadas na sessão do cliente em um navegador. Fazer isso seria, em muitos casos, impraticável e produziria más experiências. Você pode imaginar tentar carregar uma caixa inteira do Gmail no navegador? Em vez disso, o cliente mantém informações como o rótulo/pasta que você está visualizando e onde está na lista de e-mails dessa pasta. O equilíbrio de quais informações de estado manter e o que solicitar, conforme necessário, é outro desafio de engenharia desse padrão e, novamente, representa uma troca entre praticidade e fornecimento de boas experiências do usuário.

Carrinhos de compras e similares

Quanto a detalhes como carrinhos de compras, isso realmente depende da solução. Um carrinho de compras pode ser armazenado em um banco de dados no servidor, pode ser armazenado apenas no escopo da sessão no servidor ou pode até ser armazenado no cliente. A Amazon possui carrinhos de compras persistentes para usuários conectados e carrinhos "temporários" para usuários anônimos, embora esses carrinhos sejam persistentes até certo ponto.

Quando você fala sobre algo como o Google, que é realmente um monte de aplicativos diferentes que vivem sob a mesma marca, eles provavelmente não compartilham uma arquitetura comum, e cada um é construído da maneira que melhor atenda às necessidades de seus usuários. Se você quiser saber como um site é criado, abra as ferramentas do desenvolvedor no seu navegador e observe-o. Verifique se há cookies, observe o tráfego de rede e veja como ele funciona.

Desculpe se essa resposta divaga um pouco, mas o estado é um assunto complexo.

16
Robert Munn

Sessões e cookies não precisam ser evitados. Você ainda pode tê-los com aplicativos da web sem estado.

Há uma grande diferença entre Java e Ruby no Rails. Java apps armazenam a sessão na memória usando uma chave de sessão armazenada em um cookie. É rápido para recuperar o estado do usuário e o carrinho de compras. No entanto, você sempre deve acessar o mesmo servidor com sua sessão.

Os aplicativos Rails armazenam o ID do usuário em um cookie criptografado e assinado. Não pode ser adulterado. Quando você carrega uma página, o aplicativo Web busca seu estado, usuário e carrinho de compras em um banco de dados. Isso é mais lento, mas a chave é: você pode pressionar qualquer instância! Isso permite reiniciar, dimensionar e encerrar instâncias à vontade. Muito conveniente. Também pode ser acelerado com um banco de dados de cache compartilhado na memória, como o Redis. Ou você pode armazenar o carrinho de compras no cookie, desde que seja pequeno o suficiente.

Assim, você pode obter apatridia por meio de técnicas inteligentes e adicionar a capacidade de escalar à vontade.

6
Chloe

Ao se referir a apátridas - p. em um serviço HTTP RESTful - está prestes a evitar o estado de armazenamento no lado do servidor. Na melhor das hipóteses, isso inclui também evitar o armazenamento de qualquer estado em um banco de dados ou outros armazenamentos persistentes no back-end. Para deixar claro, estou falando de um estado, não de dados em geral. Parece que alguns caras estão misturando as coisas.

Uma comunicação sem estado possui vários benefícios, especialmente em relação à escalabilidade e disponibilidade.

Uma abordagem melhor é usar tokens, sem estado, porque nada é armazenado no servidor.

Isso é verdade (para certos protocolos de autenticação e autorização). Os tokens podem (mas não por si só) fornecer todas as informações da solicitação necessárias para autenticar um usuário ou autorizar uma ação. Para um exemplo, dê uma olhada em JWT .

Por isso, estou tentando entender como os aplicativos da Web podem ser sem estado quando há dados que estão sendo mantidos para minha sessão (como itens em um carrinho de compras)? Eles estão realmente sendo armazenados em um banco de dados em algum lugar e depois são periodicamente limpos? Como isso funciona quando você usa um token em vez de cookies?

Em relação ao exemplo do carrinho de compras. Não há problema em armazenar todos os itens do carrinho no lado do cliente sem usar uma sessão ou cookies. Você pode encontrar um exemplo em smashingmagazine.com . Mas também é possível realizar um carrinho de compras sem estado com cookies (pelo menos se o seu sortimento não for tão grande e o armazenamento de 4kb for suficiente para você).

Não me interpretem mal, isso não significa que você deve implementar um carrinho de compras sem estado a qualquer preço. A Amazon ou outras grandes plataformas de compras online estão usando implementações de carrinho de compras com estado, porque a experiência e a usabilidade do usuário são mais importantes para elas do que atender a requisitos técnicos não funcionais, como escalabilidade.

Geralmente, os tokens não são usados ​​para armazenar informações como itens do carrinho. Eles são usados ​​para autenticação e autorização sem estado.

E então, como uma pergunta relacionada, os principais sites (Amazon, Google, Facebook, Twitter etc.) são realmente sem estado? Eles usam tokens ou cookies (ou ambos)?

Se você está perguntando se eles estão usando cookies ou tokens para autenticação, a resposta é que eles usam os dois. Para os usuários, principalmente cookies para clientes técnicos são usados ​​principalmente tokens.

5
Paul Wasilewski

O protocolo é sem estado.

Mas, a partir disso, não é necessariamente necessário que os aplicativos que usam o protocolo sejam sem estado.

Aqui estão algumas respostas relacionadas ao StackOverflow que explicam bem a diferença:

5
sideshowbarker