你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 编程语言
Java Servlet中的Cookie及其在口令验证中的应用
 

  : 本文介绍了Java Servlet中使用Cookie的方法,并结合具体应用给出了对于授权访问通过Cookie进行口令验证的代码。提供了一个通用的软件包,可实现网上各种验证机制。

关键字Cookie, Java, Servlet,口令验证

 

Cookies是用户访问Web服务器时由Web服务器写入用户计算机特定目录的一小段信息,它可以被服务器进一步读取加以利用。Java Servlet是运行于Web服务器上的Java代码,它可以接受用户请求,进行相应的处理,并向用户提供反馈。Java Servlet中提供了Cookie类,可以对Cookie进行操作。本文利用这两项技术,实现了纯Java的基于Web的口令验证系统。

一、Java ServletCookie的支持

   1. 写入Cookie

Java Servlet中提供了Cookie类,其构造器有两个参数,分别代表Cookie的名字和值。Cookie类中提供了各种方法设置Cookie的属性,如通过setMaxAge( )方法可以设置Cookie的生存时间。若生存时间为负值,代表浏览器关闭Cookie即消失。生存时间为0,代表删除Cookie,生存时间为正数,代表Cookie存在多少秒。

同时Servlet中的HttpServletResponse类提供了addCookie()方法可以将创建好的Cookie写入用户计算机。

如下面的代码可向用户的计算机写入名称为account,值为xyxCookie

        Cookie c;

HttpServletResponse rp

             c=new Cookie("account","xyx");

             c.setMaxAge(-1);

             rp.addCookie(c);

 

2. 读取Cookie

Java ServletHttpServletRequest类提供了getCookies( )方法可以从相应用户读取Cookie列表,放在Cookie类型的数组中。通过数组中各个CookiegetName()getValue()方法可以获取各个Cookie的名称和值。

二、Java Servlet的数据库访问

我们的口令验证系统使用了一个口令数据库验证用户口令。Java Servlet可通过JDBC访问数据库系统。其基本步骤如下:

1.加载程序

        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

    2.连接数据源

        Connection con = DriverManager.getConnection("jdbc:odbc:数据库名", "", "");

3.创建Statement对象

    Statement stmt = con.createStatement ();

4.发送SQL查询语句进行数据库查询

        ResultSet rset = stmt.executeQuery (SQL语句);

        通过其返回值可以使用getString(x)获取第x列的查询结果。

或发送SQL更新语句修改数据库

stmt.executeUpdate(SQL语句)

 

在此机制下,我们定义了一个通用的类:pro,在其中定义了checkdb()方法,可以检查dbmame数据库中、tname表的字段名为accountID、值为accountValue的数据项,其PassID字段的值是否为passValue,若是,则返回true,否则返回false.

import java.sql.*;

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

 

public class pro{

   /*  检查输入的accountValuepassValue和数据库中是否一致 

        数据库名,表名,账号字段名, 账号值,密码字段名, 密码值  */

   boolean  checkdb(String dbname, String tname,String accountID, String accountValue,String passID, String passValue){

      try {

         Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

         Connection con = DriverManager.getConnection("jdbc:odbc:"+dbname, "", "");

         Statement stmt = con.createStatement ();

         /* 查询accountIDaccountValue的记录中密码值,

注意其中的但引号和双引号: '  "+accountValue+"  '  "  */

         ResultSet rset = stmt.executeQuery ("select "+passID+" from "+tname+

" where "+accountID+"='"+accountValue+"'");

         String dbpass=null;

        /*  dbpass代表数据库中的符合accountID=accountValue的数据项的密码值 */

        while (rset.next ()){

                 dbpass= rset.getString (1);

       }

 

        con.close();

        /* 检查数据库中密码值dbpass和参数中的密码值passValue是否一致 */

        if (passValue.equals(dbpass))

                 return (true);

        else return(false);

       

     } catch (Exception e) {

          return(false);

     }

  }

   }

三、使用Cookie实现登录

在上述pro类中,编写了方法cLogin(),可以实现基于Web的登录。其功能是:执行以后将检查账号和密码是否正确,若正确,则写入Cookie,供以后自动验证用。

代码如下,其变量含义同上。该程序中,首先用checkdb检测账号值accountValue和密码值passValue是否和数据库中匹配,不匹配则登录失败,匹配则向用户机器写入两个CookieaccountIDpassID。分别存放用户的账号值和口令值。

 

/*第一次登录,如密码正确,将账号和密码写入Cookie,以备以后检测 */

  boolean cLogin(HttpServletResponse rp,String dbname, String tname,String accountID,

String accountValue,String passID, String passValue){

/* 检测密码是否正确 */

         if( checkdb(dbname, tname,accountID, accountValue,passID, passValue)){

            /* 密码正确,写入账号Cookie  */

            Cookie c=new Cookie(accountID,accountValue);

            c.setMaxAge(-1);

rp.addCookie(c);

/* 密码正确,写入密码Cookie */

            c=new Cookie(passID,passValue);

            c.setMaxAge(-1);

            rp.addCookie(c);

            return(true);

         }   

         else return(false);  /* 密码不正确,返回false */

  }

四、使用Cookie随时验证

pro类中,还编写了方法cCheck(),可以在编程时随时验证用户是否已经正确登录过。如Java Servlet中涉及到访问敏感数据或需要特权的数据时,便可先运行一下cCheck()方法,若返回值为true,才继续执行相关操作。

cCheck()的代码如下,其变量含义同上。该程序中,首先用getCookies( )方法获取用户的Cookie,然后循环比较得到名称为accountIDCookie中保存的账号值和名称为passIDCookie中保存的密码值。最后用前面定义过的checkdb( )方法检查Cookie中的账号值accountValue及密码值passValue和数据库中是否一致 

 

/* 获取cookie中的accountIDPassID值, 检测CookiezaccountID和密码是否正确 */ 

  boolean cCheck(HttpServletRequest rq,String dbname, String tname,String accountID, String passID){

            Cookie x[]=rq.getCookies();

            String accountValue=null;

            String passValue=null;

            for(int i=0;i<x.length;i++)

            {

String n=x[i].getName();  // 获取Cookie的名称

          if(n.equals(accountID))  

              {     // 获取名称为accountIDCookie中保存的账号值 

              accountValue=x[i].getValue();              

 }

              if(n.equals(passID))

              {      // 获取名称为passIDCookie中保存的密码值 

               passValue=x[i].getValue(); 

              }

            }

 

            if( accountValue!=null && passValue!=null)

           // 检查Cookie中的accountValuepassValue和数据库中是否一致 

              return(checkdb(dbname, tname,accountID, accountValue,passID,

passValue));

            else return(false);

  }

五、注销

由于登录时Cookie的生存期设为负值,因此,用户退出浏览器后,Cookie中保存的账号和密码自动消失,再进行随时验证时将无法通过验证。

为了使用户在退出浏览器之前也可以手工强制退出,pro类中提供了cLogout( )方法来强制删除Cookie。其代码如下,主要是重新写入名称为accountIDpassIDCookie,并将其生存时间设置为0,这样,这些Cookie将立刻删除。以后再用方法cCheck()检测时将找不到这些Cookie,从而无法通过验证。

  void cLogout(HttpServletResponse rp,String accountID, String passID){

            Cookie c=new Cookie(accountID,"0");

             c.setMaxAge(0);

             rp.addCookie(c);

             c=new Cookie(passID,"0");

             c.setMaxAge(0);

             rp.addCookie(c);

  }

 

六、修改口令

pro类中提供cChangepass方法修改口令。该方法首先用前面的cCheck()方法检测当前是否已经登录。只有在登录状态才可以修改口令。

程序代码如下。其首先获取名称为accountIDCookie中保存的账号值,存入变量accountValue。然后在数据库中accountID等于Cookie中保存的账号值的记录中,将passID字段的值设置为新口令newpass,最后将新的口令newpass写入Cookie

 

  boolean cChangepass(HttpServletResponse rp,HttpServletRequest rq,String dbname,

         String tname,String accountID, String passID,String newpass){

 

      if(cCheck(rq,dbname,tname,accountID,passID)){ 

//已经登录过才可修改口令

         try {

            String accountValue=null;

            Cookie x[]=rq.getCookies();

            for(int i=0;i<x.length;i++)

            {

               String n=x[i].getName();

              if(n.equals(accountID))

                { // 获取名称为accountIDCookie中保存的账号值 

                  accountValue=x[i].getValue(); 

                  break;

                }

            }

          Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

          Connection con = DriverManager.getConnection("jdbc:odbc:"+dbname, "", "");

          Statement stmt = con.createStatement ();

        /* 将满足accountID= accountValue条件的记录中,

passID字段的值设置为新口令newpass

注意其中的但引号和双引号:'  "+newpass+" ' where

'  "+accountValue+"  '  " ;

 

 */

          String sss="update "+tname+" set "+ passID + " = '"+newpass+

"' where "+accountID+ "='"+accountValue+"'";

          stmt.executeUpdate(sss);

             // 将新的口令newpass写入Cookie

      Cookie c=new Cookie(passID,newpass);

              c.setMaxAge(-1);

              rp.addCookie(c);

              con.close();

              return(true);

 

           } catch (Exception e) {

               return(false); // 发生异常,不可修改口令

          }

        }

         else      return(false); // 没有登录过,不可修改口令

      }

七、示例程序

为了验证该pro类的使用,定义了一个数据库,在ODBC数据源中添加了一个名称为au1的数据源,数据表名称为pass,包含多个字段,其中账号和口令字段为account1pass1

登录的验证程序为:

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

public class c1 extends HttpServlet

{

    public void service(HttpServletRequest rq, HttpServletResponse rp)

         throws ServletException,IOException

     {  pro x=new pro();

        rp.setContentType("text/html");

    PrintWriter out=rp.getWriter();

    if(x.cLogin(rp,"au1","pass1","account1",rq.getParameter("account"),

                        "password1",rq.getParameter("password")))

              out.println("login OK");

       else            

              out.println("error in login");

   }

}

 

另外编写了随时验证的程序c2,只要将c1中的if语句该为:

    if(x.cCheck(rq,"au1","pass1","account1","password1"))

              out.println("already logged in");

    else           

              out.println("not logged in");

   }

注销的验证程序c3,只要将c1中的if语句该为:

    x.cLogout(rp,"account1","password1");

    out.println("logged out");

修改口令的验证程序c4,只要将c1中的if语句该为:

 

if(x.cChangepass(rp,rq,"au1","pass1","account1","password1",

rq.getParameter("password")))

              out.println("Password changed");

    else

             out.println("Error in ChangingPassword");

Servlet程序和数据库均安装在202.120.127.202计算机中,编制了如下HTML文档验证了整个操作过程。

<form action=http://202.120.127.202:8080/examples/servlet/c1 method=get>

输入账号:<input type=text name=account>  <br>

输入口令:<input type=password name=password>  <br>

<input type=submit value= "登录">

</form>

 

<form action=http://202.120.127.202:8080/examples/servlet/c2 method=get>

<input type=submit value= "检测是否登录">

</form>

 

<form action=http://202.120.127.202:8080/examples/servlet/c3 method=get>

<input type=submit value= "注销">

</form>

 

<form action=http://202.120.127.202:8080/examples/servlet/c4

method=get>

新口令:<input type= password name=password>  <br>

<input type=submit value= "修改口令">

</form>

 

在账号和密码正确输入并登录之前,修改口令无法进行,检测登录结果显示未登录。在正确登录后,检测登录结果一直为已登录。如果点击注销,或退出浏览器再重新打开页面,检测登录结果为未登录。检测登录结果为已登录方可修改口令。

 

  推荐精品文章

·2024年12月目录 
·2024年11月目录 
·2024年10月目录 
·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089