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 os dois têm estado). Uma abordagem melhor é usar tokens, sem estado, porque nada é armazenado no servidor.
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?
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)?
Respostas:
"aplicativos da web devem ser sem estado" devem ser entendidos como "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 completamente do lado do cliente, recupera informações do produto com chamadas AJAX e as envia ao 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 preserva o estado quando fecha a guia acidentalmente. 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 seu ID de 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.
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.
fonte
É 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:
Isso poderia funcionar para o 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 bati,
Post your Answer
meu navegador o envia para o servidor da 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 alocará 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 lanosa: o servidor Web sem estado e que impõe regras.
fonte
Absurdo. As solicitações da Web devem ser sem estado. Ou, mais precisamente, as solicitações da Web são sem estado.
Mas dizer que um aplicativo inteiro deve ser sem estado é um absurdo completo.
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.
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!
Bem, é isso. É disso que se trata realmente 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 melhor que seja armazenado no servidor! Mas, não é estado de sessão .
Portanto, em vez de ter um servidor que pode pegar um pequeno identificador e descobrir quem você é e assim por diante, os aplicativos sem estado desejam ser lembrados de quem você é e o que está fazendo com cada solicitação sangrenta. 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 ...
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
Cart
objeto, com algum tipo de ID que o servidor usa para puxá-lo para solicitações subsequentes. Mais ou menos como uma .. uhh ... ... erra ... sessão.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 seu 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 busque. Se o contexto for necessário, é melhor tê-lo por perto!
Provavelmente ambos. Mas, de um modo geral, eles fazem exatamente o que você faz: configuram cookies para identificar registros de "estado" em grandes bancos de dados de "sessões".
Quando possível, desconfio que eles inserem reivindicaçõ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 .
fonte
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 alguma forma 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 gravado pode ser transacional, por exemplo, em qual link o usuário clicou e que pode ser gravado por o 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. 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.
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 mantém, de fato, 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 v. 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, por exemplo, você publica uma atualização em sua conta de mídia social, o cliente retransmite 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, você normalmente 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 para o 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 veja-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.
fonte
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 on Rails. Os aplicativos Java 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 é que você pode bater em 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.
fonte
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:
fonte
Ao se referir a um estado sem estado - por exemplo, 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.
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. Por exemplo, dê uma olhada no JWT .
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.
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.
fonte
OK, a regra que você cita é tecnicamente incorreta. Todas as camadas de um aplicativo Web têm estado.
A intenção da regra é "não manter o servidor de estado por sessão".
Ou seja, variáveis de sessão no ASP , que eram comumente usadas para fazer coisas como itens na cesta / nome de usuário etc.
O motivo é que você ficará sem memória no servidor à medida que seu aplicativo ganhar mais usuários. Mover o armazenamento para um banco de dados ou cache compartilhado não resolve o problema, pois você ainda possui um gargalo.
Para manter o estado do aplicativo por usuário sem atingir esse problema, mova o estado para o lado do cliente. Por exemplo, coloque os itens da cesta em um cookie ou em um armazenamento mais avançado do lado do cliente.
Como o número de clientes é escalável com o número de usuários, seu aplicativo como um todo não terá um gargalo e será bem dimensionado.
fonte