Pergunta

Diga, você está enviando um formulário, que afeta seu banco de dados (adicionar registros / excluí-los / atualizá-los) e é assim que sua solicitação parece com:

POST / application / action = atualização

Agora, digamos, você é feito com a sua atualização, para que você gostaria de levar o usuário para a página inicial.

response.sendRedirect / application / action = home

Isso funciona maravilhosamente bem. Usuário é enviado um redirecionamento após o POST, por isso mesmo se o usuário tenta para atualizar a página pressionando F5, você é bom. No entanto, isso não vai funcionar se você fez isso:

RequestDispatcher.forward (/ application / action = casa)

Tendo em conta que há um cenário onde você tem que mostrar diferentes tipos de mensagens de erro / sucesso depois que você é feito com a sua atualização, você provavelmente está fazendo um atacante após o POST. No cenário tal, como você evitar ações de atualização de acontecer duas vezes?

Acho que é bastante divertido que muitos sites seguros (bancos) / gateways de pagamento tendem a informar o usuário, colocando texto na tela, como "Por favor, não pressione Voltar botões / Atualizar".

Não há nenhuma maneira melhor de lidar com isso? Outro de solicitar o usuário não pressionar esses botões? Quando eu última verificação, havia algo chamado de 'Vertical Response Cache'. Um filtro que identificaria singularidade de sua solicitação em uma sessão e tenta enviar uma resposta em cache se o pedido é duplicado. Há alguma maneira mais simples para resolver este problema clássico?

Aqui está um link para a solução de cache de resposta vertical, eu estava falando: http: / /www.fingo.info/en/articles/_1.html . Estou, no entanto, não tenho certeza quanto à forma como isso realmente funciona.

Foi útil?

Solução

Um pensamento que eu tive é incorporar uma identificação única (provavelmente uma seqüência aleatória) como um campo de formulário oculto no formulário que está sendo POST-submetido. A seqüência de ID pode ser colocado no banco de dados como um "ID da transação". Agora, quando você vai para atualizar o banco de dados, verifique primeiro se há um registro existente com o ID da transação submetido, e se assim for, assumir que é uma duplicata e não alterar o banco de dados.

Claro que, como eu disse, este é apenas um pensamento. Eu não sei o que os métodos são realmente utilizados na prática. (Eu suspeito que um monte de sites menos críticos simplesmente ignorar o problema e esperam que seus usuários vão ser inteligente ... uma proposta perdedora se eu já vi um; -)

Editar : como apontado nos comentários, armazenar IDs de transação no banco de dados pode levar até um monte de espaço, mas se isso é um problema, você pode manter um cache em memória de todas as transações IDs processados ??nos últimos 5 minutos / 1 hora / 1 dia / o que quer. Isso deve funcionar a menos que você está contra um hacker determinado ...

Outras dicas

Sim, eu acredito que você deve redirecionar após um POST, com exceção de solicitações de API. Sem isso você não só tem que se preocupar sobre a obtenção de POSTs duplicados quando o usuário usa o botão de volta, mas o navegador irá também dar os diálogos irritantes usuário quando eles tentam usar o botão de volta.

response.sendRedirect funciona na prática, mas tecnically falando, isso é enviar o código de resposta HTTP errada para esta finalidade. sendRedirect envia um 302, mas o código correto a ser usado para transformar um POST em um GET é 303. (a maioria dos navegadores irá tratar um 302 como um 303 se obtê-lo em resposta a um post, no entanto)

Em geral, você quer que o redirecionamento para enviar o usuário para qualquer irá apresentar o efeito da sua mudança. Por exemplo, se editar um widget, eles devem ser redirecionada para o ponto de vista de que widget. Se excluir um widget, eles devem ser redirecionados para a visão de que o widget teria aparecido em quando existiu (talvez a lista de widget).

Às vezes é bom ter uma mensagem de status para mais unidade casa o fato de que uma ação ocorreu. Uma simples maneira de fazer isso é ter um parâmetro comum a seus pontos de vista que, quando definido, vai mostrar uma ação mensagem concluída. por exemplo:

/widget?id=12345&msg=Widget+modified.

Aqui, o parâmetro "msg" contém a mensagem "Widget modificado". A única desvantagem para esta abordagem é que ele pode ser possível para sites maliciosos para dar aos seus usuários confundindo / enganosa mensagens. por exemplo:

/account?msg=Foo+Corp.+hates+you.

Se você está realmente preocupado com isso, você pode incluir uma assinatura expirar para a mensagem como um parâmetro adicional. Se a assinatura é inválido ou expirou, simplesmente não exibir a mensagem.

A melhor solução para resolver o problema de mostrar mensagens de status para os usuários após um POST para GET redirecionamento é usar as sessões de usuário.

Como

atributos Add a sessão do usuário com valor como conjunto de mensagens que serão mostradas. por exemplo.

userSession.put("success_messages", new HashSet<String>(){"Success", "Check your account balance"});
userSession.put("warning_messages", new HashSet<String>(){"Your account balance is low. Recharge immediately"});

E tem um filtro que verifica a sessão do usuário para esses atributos específicos e gera as mensagens. O filtro deve excluir os atributos depois de ler uma vez, como as mensagens de estado são geralmente exibido apenas uma vez.

Acho que é bastante divertido que muitos sites seguros (bancos) / gateways de pagamento tendem a informar o usuário, colocando texto na tela, como "Por favor, não pressione Voltar botões / Atualizar".

algumas pessoas acham o seu melhor para "desativar todos os eventos Back, em Atualizar a partir desta páginas críticas"; Eu não tenho certeza se isso é bom ou não.

Mas a sua solução dirigida " resposta verticais de cache " sons agradáveis ??

É um pouco não-óbvias, mas:

  • criar um objeto com chave na sessão do usuário.
  • o valor é uma solicitação + Futuro java para o resultado
  • retornar imediatamente com um redirecionamento do lado do cliente.
  • enquanto o redirecionamento do lado do cliente está sendo tratado, ter um trabalho segmento de trabalho em produzir a resposta.

Assim, quando o navegador do cliente completa o redirecionamento, recebendo imagens da nova página, etc ... os resultados estão à espera para o usuário.

A alternativa é fazer com que o usuário dolorosamente ciente de quanto tempo o banco de dados está tomando.

Atualização de Segurança (2011 Jan 24):

A chave é vulnerável a ataques, pois é parte da resposta ao cliente, por isso

  1. Gerar uma chave aleatória
  2. id de sessão de uso do usuário como um sal para criar um SHA-1
  3. loja tanto a chave aleatória ea SHA-1 na base de dados com (,) como a chave primária. (Sem indexação separada no randomkey.
  4. Use tanto randomkey eo SHA-1 como o lookup db.
  5. Não conservar o ID da sessão (questões evitar privacidade com a possibilidade de corollate muitas entradas para o mesmo usuário)
  6. expirar os resultados após 2-3 dias. (Permite que um trabalho em lotes diariamente para fazer a limpeza e evita criar problemas para as sessões de usuário que são semi-longa duração)

Este método exige que qualquer hacker para conhecer tanto o ID de sessão e a chave aleatória.

Esta abordagem pode parecer um exagero, mas um mecanismo endureceu-redirect pode ser usado para situações como redefinições de senha.

Se você está trabalhando com o servidor java script lado e também usando Struts 2, em seguida, você se refere este link que fala sobre sobre o uso de token.

http://www.xinotes.org/notes/note/369/

Um token devem ser gerados e mantidos em sessão para a página inicial render, quando o pedido for apresentado juntamente com o token, pela primeira vez, em ação struts funcionar uma linha com nome segmento como o ID de token e executar a lógica seja qual for o cliente pediu para, quando o cliente enviar novamente o mesmo pedido, verifique se o segmento ainda está em execução (thread.getcurrentthread (). interrompido) se ainda em execução, em seguida, enviar um redirecionamento cliente 503.

Por favor, olhe o ExecuteAndWaitInterceptor de escoras 2code, a lógica desta combinado com o token vai ajudar rápido clique

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top