Java-web再生の繰り返し提出、動的検証コード
10150 ワード
一、項目に重複して提出する場合があります.
サーバーが遅い、またはネットワークが遅れているため、提出ボタンを繰り返しクリックします.
2,すでに提出しました.成功ページを更新しました.
3、すでに提出しました.キャンセルして、再度提出ボタンをクリックします.
注意:
1,返却後、フォームページを更新し、再度提出する場合は重複提出ではなく、新たな要求を送信します.
2,Firefoxで、同じアドレスに繰り返し提出するのは無効です.
二、ソリューションの繰り返し提出:
1、方案1、javaScriptを利用する:
繰り返しボタンをクリックした繰り返しの提出要求を解決しましたが、更新ページの繰り返し提出が解決されませんでした.
使用する 2、唯一のランダム文字列を利用する(sessionを使用する)
(1)UUID:
FORMフォームが含まれているページは一つのサーバプログラムによって動的に生成されなければならず、サーバプログラムは各ページのFORMフォームに固有のランダム識別番号を割り当て、FORMフォームの隠しフィールドにこの識別番号を設定し、現在のユーザのSessionドメインにこの識別番号を保存する.
ユーザがFORMフォームを提出すると、この要求を受信したサーバプログラムは、FORMフォーム非表示フィールドの識別番号と現在のユーザのSessionドメインに記憶されている識別番号とが同じかどうかを比較し、同じであればフォームデータを処理し、処理後に現在のユーザのSessionドメインに格納されている識別番号をクリアする.下記の場合、サーバプログラムは提出されたフォーム要求を無視します.
現在のユーザのセッションにはフォーム識別番号がありません.
ユーザが提出したフォームデータには識別番号フィールドがありません.
現在のユーザのSessionドメインに格納されているフォーム識別番号とフォームデータの識別番号が異なる.
ブラウザは、FORMフォームを含むページをWEBサーバに再要求するだけで、サーバプログラムは別のランダム識別番号を生成し、この識別番号をSessionドメインに保存し、新たに戻ったFORMフォームの隠しフィールド値として保存する.
UUIDを使用すると、重複して提出されるステップを防止する.
a、UUUIDクラスを使ってランダムな文字列を生成することができます.
b、getUUID DStringは、UID値を生成し、sessionに格納する.
c、検証し、フォームから送られてきたuuid値とsessionの値を比較する.
4、uuid値をリセットします
サンプルコード:
(3)Sessionを利用した一回性検証コードの実現
一回性の検証コードの主な目的は、人々がツールソフトを利用して暗号を暴くことを制限するためで、その原理はSessionを利用してフォームの重複提出を防止する原理と基本的に同じで、フォームの識別番号を検証コードの形式に変えただけで、ユーザーに提示した検証コードをマニュアルでフォームフィールドに記入するように要求します.フォームの隠しフィールドではなく、自動的にサーバにフィードバックします.
サーバプログラムはフォームデータを受信した後、まずユーザが正しい検証コードを記入したかどうかを判断し、その検証コードがサーバ端に保存されている検証コードと一致した場合にのみ、サーバプログラムは正常なフォーム処理フローを開始する.
パスワード推測ツールは、まず正しい検証コードを入力し、検証コードは一回限り有効です.これで、基本的にはパスワード推測ツールの自動処理プロセスを遮断しました.
Servlet出力グラフィック認証コード:
BufferedImageはメモリグラフィックスを生成するために使用されます.
BufferedImageイメージ=new BufferedImage(width,height,BufferedImage.TYPE_BGR)
Graphicsは、描画可能な図形オブジェクトを生成するために使用されます.
Graphcs g=image.get Graphics()
g.fillRect(0,0,width,height);長方形を塗りつぶす
g.drawRect(0,0,width-1,height-1)//長方形を描く
g.set Font(new Font)//フォントの設定
g.drawString(rank,codeX*(i+1)、codeY);出力文字列
g.drawOval(x,y,0,0)//混同線を引く
g.dispose()
ImageIOオブジェクトは、画像を出力するために使用されます.
ImageIO.write(イメージ、「jpg」、レスポンスe.get OutputStream()//画像を出力
付:IE 7 firefox認証コードは反応問題がありません.
問題が発生しました.IE 6の下の写真は正常に修正されましたが、IE 7とFirefoxの下で更新されません.
状況分析:新しい写真と古い写真の住所が違ったら、効果が出ます.画像に変化があります.ただし、「認証コード」のような機能は、servletが動的に生成した画像なので、新旧の画像のアドレスは同じです.上記の場合、画像のアドレスが同じであるため、ブラウザが自動的にキャッシュを読み込むことになる可能性があります.
解決方法一(乱数を利用)
javascriptをこのように変更すればいいです. function nextpic(){
var img_=document.getElemenntById(「pic」);
imgu.src=「$pageConttext.request.com ntxtPath」/
image Servlet?"+Math.random();
}
つまり、訪問先は毎回違っています.乱数があるので、問題は解決されます.
解決方法二(タイムスタンプの利用)
javascriptをこのように変更すればいいです.
function nextPic(){
alert(Date.parse(new Date);
var pic=document.getElemenntById(「pic」);
pic.src=“$pageConttext.request.com ntxtPath”/
imagServlet?"+Date.parse(new Date);
}
Date.parse():日付を含む文字列を解析し、1970年1月1日午前0時までのミリ秒数を返します.
サンプルコード:
サーバーが遅い、またはネットワークが遅れているため、提出ボタンを繰り返しクリックします.
2,すでに提出しました.成功ページを更新しました.
3、すでに提出しました.キャンセルして、再度提出ボタンをクリックします.
注意:
1,返却後、フォームページを更新し、再度提出する場合は重複提出ではなく、新たな要求を送信します.
2,Firefoxで、同じアドレスに繰り返し提出するのは無効です.
二、ソリューションの繰り返し提出:
1、方案1、javaScriptを利用する:
繰り返しボタンをクリックした繰り返しの提出要求を解決しましたが、更新ページの繰り返し提出が解決されませんでした.
var flag=false;
function save(){
if(!flag){
document.forms[0].submit();
flag=true;
}else{
alert(" ");
}
}
注意:使用する 2、唯一のランダム文字列を利用する(sessionを使用する)
(1)UUID:
FORMフォームが含まれているページは一つのサーバプログラムによって動的に生成されなければならず、サーバプログラムは各ページのFORMフォームに固有のランダム識別番号を割り当て、FORMフォームの隠しフィールドにこの識別番号を設定し、現在のユーザのSessionドメインにこの識別番号を保存する.
ユーザがFORMフォームを提出すると、この要求を受信したサーバプログラムは、FORMフォーム非表示フィールドの識別番号と現在のユーザのSessionドメインに記憶されている識別番号とが同じかどうかを比較し、同じであればフォームデータを処理し、処理後に現在のユーザのSessionドメインに格納されている識別番号をクリアする.下記の場合、サーバプログラムは提出されたフォーム要求を無視します.
現在のユーザのセッションにはフォーム識別番号がありません.
ユーザが提出したフォームデータには識別番号フィールドがありません.
現在のユーザのSessionドメインに格納されているフォーム識別番号とフォームデータの識別番号が異なる.
ブラウザは、FORMフォームを含むページをWEBサーバに再要求するだけで、サーバプログラムは別のランダム識別番号を生成し、この識別番号をSessionドメインに保存し、新たに戻ったFORMフォームの隠しフィールド値として保存する.
UUIDを使用すると、重複して提出されるステップを防止する.
a、UUUIDクラスを使ってランダムな文字列を生成することができます.
b、getUUID DStringは、UID値を生成し、sessionに格納する.
c、検証し、フォームから送られてきたuuid値とsessionの値を比較する.
4、uuid値をリセットします
サンプルコード:
package cn.itcast.cd.util;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
public class TokenUtil {
public static void getToken(HttpServletRequest request) {
String randomValue = UUID.randomUUID().toString(); // session
String randomName = UUID.randomUUID().toString();// session
request.setAttribute("randomValue", randomValue);
request.setAttribute("randomName", randomName);
request.getSession().setAttribute(randomName, randomValue);
}
/**
* session return true
*
* @param request
* @return
*/
public static Boolean validate(HttpServletRequest request) {
// ..
String randomValue = request.getParameter("randomValue");
String randomName = request.getParameter("randomName");
// session
String randomValueInSesson = (String) request.getSession()
.getAttribute(randomName);
return StringUtils.isNotBlank(randomValueInSesson)
&& StringUtils.isNotBlank(randomValue)
&& randomValue.equals(randomValueInSesson);
}
public static void resetToken(HttpServletRequest request) {
String randomName = request.getParameter("randomName");
request.getSession().removeAttribute(randomName);
}
}
(2)stut 1の同期トークン(3)Sessionを利用した一回性検証コードの実現
一回性の検証コードの主な目的は、人々がツールソフトを利用して暗号を暴くことを制限するためで、その原理はSessionを利用してフォームの重複提出を防止する原理と基本的に同じで、フォームの識別番号を検証コードの形式に変えただけで、ユーザーに提示した検証コードをマニュアルでフォームフィールドに記入するように要求します.フォームの隠しフィールドではなく、自動的にサーバにフィードバックします.
サーバプログラムはフォームデータを受信した後、まずユーザが正しい検証コードを記入したかどうかを判断し、その検証コードがサーバ端に保存されている検証コードと一致した場合にのみ、サーバプログラムは正常なフォーム処理フローを開始する.
パスワード推測ツールは、まず正しい検証コードを入力し、検証コードは一回限り有効です.これで、基本的にはパスワード推測ツールの自動処理プロセスを遮断しました.
Servlet出力グラフィック認証コード:
BufferedImageはメモリグラフィックスを生成するために使用されます.
BufferedImageイメージ=new BufferedImage(width,height,BufferedImage.TYPE_BGR)
Graphicsは、描画可能な図形オブジェクトを生成するために使用されます.
Graphcs g=image.get Graphics()
g.fillRect(0,0,width,height);長方形を塗りつぶす
g.drawRect(0,0,width-1,height-1)//長方形を描く
g.set Font(new Font)//フォントの設定
g.drawString(rank,codeX*(i+1)、codeY);出力文字列
g.drawOval(x,y,0,0)//混同線を引く
g.dispose()
ImageIOオブジェクトは、画像を出力するために使用されます.
ImageIO.write(イメージ、「jpg」、レスポンスe.get OutputStream()//画像を出力
付:IE 7 firefox認証コードは反応問題がありません.
問題が発生しました.IE 6の下の写真は正常に修正されましたが、IE 7とFirefoxの下で更新されません.
状況分析:新しい写真と古い写真の住所が違ったら、効果が出ます.画像に変化があります.ただし、「認証コード」のような機能は、servletが動的に生成した画像なので、新旧の画像のアドレスは同じです.上記の場合、画像のアドレスが同じであるため、ブラウザが自動的にキャッシュを読み込むことになる可能性があります.
解決方法一(乱数を利用)
javascriptをこのように変更すればいいです. function nextpic(){
var img_=document.getElemenntById(「pic」);
imgu.src=「$pageConttext.request.com ntxtPath」/
image Servlet?"+Math.random();
}
つまり、訪問先は毎回違っています.乱数があるので、問題は解決されます.
解決方法二(タイムスタンプの利用)
javascriptをこのように変更すればいいです.
function nextPic(){
alert(Date.parse(new Date);
var pic=document.getElemenntById(「pic」);
pic.src=“$pageConttext.request.com ntxtPath”/
imagServlet?"+Date.parse(new Date);
}
Date.parse():日付を含む文字列を解析し、1970年1月1日午前0時までのミリ秒数を返します.
サンプルコード:
package cn.itcast.cd.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
public class LoginServlet extends HttpServlet {
/**
* @see HttpServlet#service(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String code = request.getParameter("code");
String randomCode = (String) request.getSession().getAttribute(
"randomCode");
if (StringUtils.equalsIgnoreCase(code, randomCode)) {
System.out.println(" ");
} else {
request.setAttribute("error", " ");
request.getRequestDispatcher("/login.jsp").forward(request,
response);
}
}
}
package cn.itcast.cd.servlet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import java.util.UUID;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class RandomCodeServlet
*/
public class RandomCodeServlet extends HttpServlet {
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String randomCode = (UUID.randomUUID().toString()).substring(0, 4);
request.getSession().setAttribute("randomCode", randomCode);
response.setContentType("image/jpeg"); // .
int width = 100;
int height = 50;
// >>1.
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_BGR);
// >>2.
Graphics graphics = image.getGraphics();
// >>3.
// >>3.1 .
graphics.setColor(Color.white);//
graphics.fillRect(1, 1, width - 2, height - 2);
// >>3.2
graphics.setColor(Color.black);
graphics.setFont(new Font(" ", Font.BOLD, 30));
graphics.drawString(randomCode, width / 6, height / 2 + 5);
// >>3.3
graphics.setColor(Color.red);
for (int i = 0; i < 50; i++) {
graphics.fillOval(new Random().nextInt(width),
new Random().nextInt(height), 3, 3);
}
for (int i = 0; i < 10; i++) {
graphics.setColor(new Color[] { Color.red, Color.blue, Color.GRAY }[new Random()
.nextInt(3)]);
graphics.drawLine(new Random().nextInt(width),
new Random().nextInt(height), new Random().nextInt(width),
new Random().nextInt(height));
}
// >>4. , ...
graphics.dispose();
//
ImageIO.write(image, "JPG", response.getOutputStream());
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function changeImage() {
document.getElementById("randomCode").src = "/randomCode?"
+ Math.random();
}
</script>
</head>
<body>
<form action="/login" method="post">
:<input name="username" type="text"><br /> :<input
name="password" type="password"><br /> :<input name="code"
type="text"><img alt="" src="/randomCode" id="randomCode"
style="cursor: pointer;" onclick="changeImage()"> ${error}<br />
<input type="submit" value=" ">
</form>
</body>
</html>