実装と実行プロセスについてhttp://www.cnblogs.com/android-html5/archive/2012/05/19/2533650.html
43289 ワード
認証コードはよく見られる機能で、認証コードはハッカーが何らかの手段で無間隔に登録することを防止することができるなど
認証コードは、サーバ側で生成された画像を介してクライアントに送信されます.
実装手順(プロセス):
1)servletなどのサーバ側からランダムにいくつかの文字数を生成するなど,これらの文字を1つの文字列につなぎ合わせてsessionドメインに格納する.
2)画像でクライアントに渡されます.認証コードの具体的な値はサーバー側で検証されています.もし具体的な値がクライアントで検証されていたら、不便かもしれません.例えば、初めて静的ログインインタフェースにアクセスした場合、sessionを取りに行く値は空です.ページ全体を再度更新しない限り.
3)クライアントは検証コードに対して、空であるかどうか、入力した文字の長さが標準に達しているかどうかを検証する.
4)入力した認証コードをサーバ側に伝え,サービス側はセッションで値をとり,具体的な判断を行う.
5)入力の有無によって、別のインタフェースにジャンプして、もし入力が間違っていたら、一般的に現在のインタフェースにジャンプして、検証コードの変更はもう一度更新される.
実装されたページ:
認証コードを生成するResponse_3クラス 参照------>クリックしてリンクを開く
Myeclipse環境で
ここではもちろんWEB-INFディレクトリの下にweb.xmlを配置します
まとめ:
コントロールブラウザをキャッシュするには:
response.setDateHeader("Expires",System.currentTimeMillis() + 1000*3600);注意:この文が追加されていない場合 System.currentTimeMillis()はキャッシュ締切日がなく、デフォルトでは1970年からキャッシュが1時間、つまり期限切れになっているので、System.currentTimeMillis()という文の役割は、現在の日付時間を取得し、キャッシュする時間を加えることで、1000は1秒を表します.
コントロールブラウザはキャッシュしない:
response.setDateHeader("Expires", -1); または response.setDateHeader("Expires", 0); 同じように
response.setHeader("cache-control", "no-cache");
response.setHeader("pragma", "no-cache");
ここに色を設定したり、色を塗りつぶしたり、枠を描いたりするのを忘れないでください.
描画枠:g.drawRect(1,1,WIDTH-2,HEIGHT-2);枠の幅と高さは、いずれも背景色の幅より1小さく、この枠はx=1,y=1(座標(1,1))から描き始めますが、本来はx=0,y=0から描きますが、一番左寄りの効果はよくないのでWIDTH-2,HEIGHT-2は2を減らします
中国語フォント範囲[u 4 e 00-u 9 fa 5]
ランダム文字の取得:String ch=base.charAt(new Random().nextInt(base.length())+"";
文字列に変換
注意: 字の回転角度を設定します.g.rotate(theta*Math.PI/180,x,20);//回転角度(必ずラジアン)を設定し、ラジアンに変換します(式:theta*Math.PI/180;このthetaは度):int theta=new Random().nextInt()%30;//-30から30の数を取得し、
回転が終わったら、字をボックスに入れてから、回転角度を初期状態に回転させて、次の字を回転させることに注意しなければなりません.
サーバ側検証、ここでは検証コードのみ検証
認証コードは、サーバ側で生成された画像を介してクライアントに送信されます.
実装手順(プロセス):
1)servletなどのサーバ側からランダムにいくつかの文字数を生成するなど,これらの文字を1つの文字列につなぎ合わせてsessionドメインに格納する.
2)画像でクライアントに渡されます.認証コードの具体的な値はサーバー側で検証されています.もし具体的な値がクライアントで検証されていたら、不便かもしれません.例えば、初めて静的ログインインタフェースにアクセスした場合、sessionを取りに行く値は空です.ページ全体を再度更新しない限り.
3)クライアントは検証コードに対して、空であるかどうか、入力した文字の長さが標準に達しているかどうかを検証する.
4)入力した認証コードをサーバ側に伝え,サービス側はセッションで値をとり,具体的な判断を行う.
5)入力の有無によって、別のインタフェースにジャンプして、もし入力が間違っていたら、一般的に現在のインタフェースにジャンプして、検証コードの変更はもう一度更新される.
実装されたページ:
認証コードを生成するResponse_3クラス 参照------>クリックしてリンクを開く
package cn.response;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random; //
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//
public class Response_3 extends HttpServlet {
private static final int WIDTH=120, HEIGHT=50;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//
BufferedImage image = new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
//1.
setBackGround(g);
//2.
setBorder(g);
//3.
drawRandomLine(g);
//4.
String validateValue = drawRandomNum((Graphics2D)g);
System.out.println(" :"+validateValue);
// session
request.getSession().setAttribute("validateValue", validateValue);
//5.
// System.currentTimeMillis()
//response.setDateHeader("Expires",System.currentTimeMillis() + 1000*3600); // 1
//
response.setDateHeader("Expires", -1);
response.setHeader("cache-control", "no-cache");
response.setHeader("pragma", "no-cache");
response.setContentType("image/jpeg");//
// JPG ImageIO.write
ImageIO.write(image,"jpg",response.getOutputStream());
}
private void setBackGround(Graphics g)
{
g.setColor(Color.lightGray);//
g.fillRect(0, 0, WIDTH, HEIGHT);//
}
private void setBorder(Graphics g)
{
//
if(0 == new Random().nextInt(3))
{
g.setColor(Color.cyan);//
}
else if(1 == new Random().nextInt(5))
{
g.setColor(Color.red);//
}
else
{
g.setColor(Color.yellow);//
}
g.drawRect(1, 1, WIDTH-2, HEIGHT-2);//
}
private void drawRandomLine(Graphics g)
{
g.setColor(Color.green);
for(int i=0; i<5; i++)
{
// ,
int x1 = new Random().nextInt(WIDTH);//
int y1 = new Random().nextInt(HEIGHT);//
int x2 = new Random().nextInt(WIDTH);
int y2 = new Random().nextInt(HEIGHT);
g.drawLine(x1, y1, x2, y2);//
}
}
private String drawRandomNum(Graphics2D g)
{
String validateValue = "" ; //
g.setColor(Color.red);
g.setFont(new Font(" ",Font.BOLD,28));//
//
//String base="\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08\u4e09";
String base= "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz" ;
int x=5;
// [\u4e00-\u9fa5]
for(int i=0; i<4; i++)
{
int theta = new Random().nextInt()%30;// -30 30
//String x1 = new Random().nextInt(9)+"";
String ch = base.charAt( new Random().nextInt(base.length()) )+"";//
g.rotate(theta*Math.PI/180, x, 30);// ( )
g.drawString(ch, x, 30);//
g.rotate(-theta*Math.PI/180, x, 30);//
//g.drawString(x1, x, 20);
x+=30;
//g.drawString(x1, x, 20);
//x+=30;
validateValue = validateValue + ch ;
}
return validateValue;
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}
Myeclipse環境で
ここではもちろんWEB-INFディレクトリの下にweb.xmlを配置します
まとめ:
コントロールブラウザをキャッシュするには:
response.setDateHeader("Expires",System.currentTimeMillis() + 1000*3600);注意:この文が追加されていない場合 System.currentTimeMillis()はキャッシュ締切日がなく、デフォルトでは1970年からキャッシュが1時間、つまり期限切れになっているので、System.currentTimeMillis()という文の役割は、現在の日付時間を取得し、キャッシュする時間を加えることで、1000は1秒を表します.
コントロールブラウザはキャッシュしない:
response.setDateHeader("Expires", -1); または response.setDateHeader("Expires", 0); 同じように
response.setHeader("cache-control", "no-cache");
response.setHeader("pragma", "no-cache");
ここに色を設定したり、色を塗りつぶしたり、枠を描いたりするのを忘れないでください.
描画枠:g.drawRect(1,1,WIDTH-2,HEIGHT-2);枠の幅と高さは、いずれも背景色の幅より1小さく、この枠はx=1,y=1(座標(1,1))から描き始めますが、本来はx=0,y=0から描きますが、一番左寄りの効果はよくないのでWIDTH-2,HEIGHT-2は2を減らします
中国語フォント範囲[u 4 e 00-u 9 fa 5]
ランダム文字の取得:String ch=base.charAt(new Random().nextInt(base.length())+"";
文字列に変換
注意: 字の回転角度を設定します.g.rotate(theta*Math.PI/180,x,20);//回転角度(必ずラジアン)を設定し、ラジアンに変換します(式:theta*Math.PI/180;このthetaは度):int theta=new Random().nextInt()%30;//-30から30の数を取得し、
回転が終わったら、字をボックスに入れてから、回転角度を初期状態に回転させて、次の字を回転させることに注意しなければなりません.
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'ValidateLogin.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<BODY style="background-color:66CCFF" >
<table cellspacing="10"
border=1 background="" align="center">
<tr>
<td>
<b style="font-size:20;color:green;" > -- </b>
<hr width=220 align=left>
<form name=form1 Action="LoginServlet" method="get" >
<br />
:
<input type="text" name="usename" value[email protected] size=19 maxlength=16 />
<br />
<br />
:
<input type="password" name="password" maxlength=16 />
<br /><br />
: <input type="text" name="validateValue" size=19 onblur="checkVlidte(this)"/><br>
<img id="image" src="servlet/Response_3"/>
<a href="javascript:changeimage()" > ? </a>
<br /><br />
<br /><br />
<input type="submit" value=" "/>
<input type="reset" value=" " />
<hr width=220 align=left>
</form>
</td>
</tr>
</table>
</body>
<script type="text/javascript">
function validate_required(field,alerttxt)
{
with(field)
{
/*if(value==null||value=="")
{
alert(alerttxt);
return false ;
}
else
return true ;
*/
i = value.indexOf("@"); //
j = value.lastIndexOf(".");
if(i < 1 || j-i <2)
{
alert(alerttxt) ;
return false ;
}
else
return true ;
}
}
function password_validate (_pass,alerttxt)
{
with(_pass)
{
if(value!="")
return true ;
else
{
alert(alerttxt) ;
return false ;
}
}
}
function validate_form(thisform)
{
with(thisform)
{
if(validate_required(name1," !") == false)
{
name1.focus();
return false ;
}
if(password_validate(pass," !") == false)
{
pass.focus();
return false ;
}
}
}
</script>
<script type="text/javascript">
function proving()
{
if(form1.pass.value!="")
window.open("http://www.baidu.com/","_self");
else
window.open("http://www.google.com/","_self");
}
</script>
<!-- -->
<script type="text/javascript">
function changeimage()
{
var img = document.getElementById("image") ;
if(img)
img.src=img.src+ "?" + new Date().getTime();
}
function checkVlidte(object)
{
if(object.value.length != 4 )
{
alert(" !");
//object.focus() ;//
//object.select() ;//
}
}
</script>
</html>
サーバ側検証、ここでは検証コードのみ検証
package cn.request;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String usename = request.getParameter("usename");
String password = request.getParameter("password");
String validateValue = request.getParameter("validateValue");
String vv = (String)request.getSession().getAttribute("validateValue");
//
if( (validateValue.toLowerCase()).equals(vv.toLowerCase()) )
{
response.sendRedirect("index.jsp");
}
else
{
request.getRequestDispatcher("ValidateLogin.jsp").forward(request, response);
}
}
}