我的日常

登录/注册
您现在的位置:论坛 盖世程序员(我猜到了开头 却没有猜到结局) 盖世程序员 > Java安全实现自动登陆功能
总共48087条微博

动态微博

查看: 7079|回复: 0

Java安全实现自动登陆功能

[复制链接]

326

主题

72

听众

999

金钱

实习版主

该用户从未签到

优秀版主

跳转到指定楼层
楼主
发表于 2015-06-02 10:44:46 |只看该作者 |倒序浏览
现在很多网站都有为用户保存登陆信息(即保存Cookie)的功能,当用户下一次进入网站时,可以帮助用户自动登陆,使网站显得更加友好。笔者通过研究ACEGI项目的自动登陆源码,编写了一个安全有效的实现两星期自动登陆功能的java工具类,下面是具体的实现流程和实现代码。
5 W2 {  v& E: L( _, U# H
" ]! v, O+ t/ l0 P) g/ K$ z# X  先说一下流程:0 m2 l6 Z/ i/ |/ u
" w/ H9 a# l, m+ K: K
  1.保存用户信息阶段:
. L8 \0 b7 d! l
) I; e3 U- E' Z7 j0 ~; M  当用户登陆网站时,在登陆页面填写完用户名和密码后,如果用户在提交时还选择了“两星期内自动登陆”复选框,那么在后台程序中验证用户名和密码全都正确后,还要为用户保存这些信息,以便用户下一次可以直接进入网站;如果用户没有勾选“两星期内自动登陆”复选框,则不必为用户保存信息,那么用户在下一次登陆网站时仍需要填写用户名和密码。) D, ^3 V2 C, E- p' F# E
2 s% f# Y- f2 B* h' g& A
  在保存用户信息阶段,主要的工作是对用户的信息进行加密并保存到客户端。加密用户的信息是较为繁琐的,大致上可分为以下几个步聚:
/ j- j& M- U' A3 q# |
- d$ G0 T: _/ }1 a$ j   ① 得到用户名、经MD5加密后的用户密码、cookie有效时间(本文设置的是两星期,可根据自己需要修改)
  q/ r7 _+ w( [9 c   ② 自定义的一个webKey,这个Key是我们为自己的网站定义的一个字符串常量,这个可根据自己需要随意设置
4 ?" \. r" d' B, q/ e   ③ 将上两步得到的四个值得新连接成一个新的字符串,再进行MD5加密,这样就得到了一个MD5明文字符串& B& E" _9 `  g* p+ ~" K2 D5 K6 A
   ④ 将用户名、cookie有效时间、MD5明文字符串使用“:”间隔连接起来,再对这个连接后的新字符串进行Base64编码
8 I( [* Z/ D7 d   ⑤ 设置一个cookieName,将cookieName和上一步产生的Base64编码写入到客户端。
7 k& q( \( @6 a9 p; Q! F
2 |$ W0 }( ^, T; _3 B  2.读取用户信息:
# A  Q! ]9 F: \& q' V* T$ k" Y: l" @
  其实弄明白了保存原理,读取及校验原理就很容易做了。读取和检验可以分为下面几个步骤:( x2 @; U1 t3 M0 E1 k6 G

# i6 Z# U4 a  d2 E- d% u* ?   ① 根据设置的cookieName,得到cookieValue,如果值为空,就不帮用户进行自动登陆;否则执行读取方法
+ G1 t9 _# g4 |' `   ② 将cookieValue进行Base64解码,将取得的字符串以split(“:”)进行拆分,得到一个String数组cookieValues(此操作与保存阶段的第4步正好相反),这一步将得到三个值:. J4 u+ z3 {& ~* q9 O: l3 T

/ c6 H9 _- A" scookieValues[0] ---- 用户名7 L+ E' |1 E2 e$ _
cookieValues[1] ---- cookie有效时间+ F+ t3 W" p' {1 j0 I) j  d
cookieValues[2] ---- MD5明文字符串
' B' u* }: c7 ^& H: a9 d% n' y9 X% h% O( I" [2 L- H4 [
   ③ 判断cookieValues的长度是否为3,如果不为3则进行错误处理。
) k! n& q" t* g+ _/ ?   ④ 如果长度等于3,取出第二个,即cookieValues[1],此时将会得到有效时间(long型),将有效时间与服务器系统当前时间比较,如果小于当前时间,则说明cookie过期,进行错误处理。
9 @; w7 ?2 O0 n! d" x1 `   ⑤ 如果cookie没有过期,就取cookieValues[0],这样就可以得到用户名了,然后去数据库按用户名查找用户。
/ X/ l8 e! W+ Q7 X. n   ⑥ 如果上一步返回为空,进行错误处理。如果不为空,那么将会得到一个已经封装好用户信息的User实例对象user; G. @5 ~% l- F; a
   ⑦ 取出实例对象user的用户名、密码、cookie有效时间(即cookieValues[1])、webKey,然后将四个值连接起来,然后进行MD5加密,这样做也会得到一个MD5明文字符串(此操作与保存阶段的第3步类似)
7 k$ \8 ^" n: @7 V, D3 J* w   ⑧ 将上一步得到MD5明文与cookieValues[2]进行equals比较,如果是false,进行错误处理;如果是true,则将user对象添加到session中,帮助用户完成自动登陆
0 u8 y, ?' u# y
' I9 @2 k9 K! [  完整的代码,用途请参见注释
3 V# J2 B" @, D7 T; L( ICookieUtil.java
) @" r5 B) h: O8 N8 u4 P- i5 g+ Y% W  L  u
处理cookie的工具类,包括读取,保存,清除三个主要方法。4 _( O% N2 `( ~3 [; [, W( A- F  _% G  ]
( M. j  k- l" \
  1. public class CookieUtil {
    + f" D& ]& Y% U3 N3 r
  2. //保存cookie时的cookieName
    " g0 d/ f4 @' x' q$ `
  3. private final static String cookieDomainName = “cn.itcast”; : K/ A1 ?2 s# c) A  L  X0 n* L
  4. //加密cookie时的网站自定码
    ( k( t/ H2 [% h  r/ T5 C
  5. private final static String webKey = “itcast”; 5 `0 y( s% x( h. t/ M+ p4 ?* S
  6. //设置cookie有效期是两个星期,根据需要自定义( `2 K% N! Q) q" a1 k
  7. private final static long cookieMaxAge = 60 * 60 * 24 * 7 * 2; ' A: I! |* T: ^! Z0 N6 \' A& {: A
  8. //保存Cookie到客户端--------------------------------------------------------------------------------------------------------+ E( V6 h* x6 ]3 Z
  9. //在CheckLogonServlet.java中被调用% u8 K% o& y7 E+ u7 R' N
  10. //传递进来的user对象中封装了在登陆时填写的用户名与密码: g! p: l& K. t0 H" f% c
  11. public static void saveCookie(User user, HttpServletResponse response) {) Z: t7 m8 E" G0 ?$ E7 L

  12. * Z3 m. ]6 k0 [; i2 {4 d1 ~
  13. //cookie的有效期& \$ J  e# N  u. |
  14. long validTime = System.currentTimeMillis() + (cookieMaxAge * 1000); * D4 F0 e0 f' t1 i& E8 W4 S
  15. //MD5加密用户详细信息
    ( ~% A2 c- i% s/ I5 b  H
  16. String cookieValueWithMd5 =getMD5(user.getUserName() + ":" + user.getPassword()+ ":" + validTime + ":" + webKey);
    2 N) m# g2 S6 H4 g. k' e
  17. //将要被保存的完整的Cookie值+ Y; C$ a  |" E
  18. String cookieValue = user.getUserName() + ":" + validTime + ":" + cookieValueWithMd5;
    / n0 j5 G! \4 K3 j
  19. //再一次对Cookie的值进行BASE64编码
    , V5 g. j/ X3 M4 ]8 [; |# g
  20. String cookieValueBase64 = new String(Base64.encode(cookieValue.getBytes())); 4 C+ o7 ~9 f% ^8 `: C( X
  21. //开始保存Cookie% K" F% n% g2 S
  22. Cookie cookie = new Cookie(cookieDomainName, cookieValueBase64);
    $ k* ^- i0 j( z- o
  23. ; `) ~/ k9 B( l) }& m5 o1 R& a" ?
  24. //存两年(这个值应该大于或等于validTime)+ `! u: I; X& i4 Y) x
  25. cookie.setMaxAge(60 * 60 * 24 * 365 * 2);
    4 X; P" w, @# Q  _2 J
  26. //cookie有效路径是网站根目录
    ' f( _# G8 G: L6 p1 z5 h0 D
  27. cookie.setPath("/"); , A7 w0 k( U; Z! v9 o$ S
  28. //向客户端写入0 r1 X2 }) C9 J
  29. response.addCookie(cookie);
    + }7 K+ h8 c# D0 z
  30. ' i* F7 K7 F4 r
  31. }1 {" Z# {8 E, o7 z! q

  32. % ]% Z& F) i: K& [& D$ T
  33. //读取Cookie,自动完成登陆操作--------------------------------------------------------------------------------------------# [( A: y  ^. Z0 E
  34. & s$ k( u% D4 t/ D; V* a
  35. //在Filter程序中调用该方法,见AutoLogonFilter.java: |/ S* w; N, b; s, ]* R1 i1 [& g4 B
  36. public static void readCookieAndLogon(HttpServletRequest request, HttpServletResponse response, ! N* Q  ^$ }6 J& O* O) I6 A
  37. FilterChain chain) throws IOException, ServletException,UnsupportedEncodingException{
    4 s' H* Y- ~8 }' x8 r
  38. //根据cookieName取cookieValue
    7 u& @* a$ D& a. Q: E3 U0 ?: X
  39. Cookie cookies[] = request.getCookies(); : t8 |4 C: c* t$ S/ T5 U
  40. String cookieValue = null;
    3 z( b- h7 W+ E
  41. if(cookies!=null){
    ; f+ s$ J! n4 |7 i1 s! ]5 V5 ^
  42. for(int i=0; i<cookies.length; i++){0 c$ I. Y! ?4 n6 t4 R% E) p
  43. if (cookieDomainName.equals(cookies[i].getName())) {
    7 A% m9 y! W4 Y* S/ }2 ^9 T; D
  44. cookieValue = cookies[i].getValue();
    * t1 Y: _' I0 U/ d3 d1 a5 b
  45. break;
    8 m1 s1 ]" ]$ _6 O5 o" C
  46. }  j/ r! Q8 a/ V% ?) _! A
  47. }
    ) d$ k, Q# t8 W9 v  \8 ~
  48. }6 K1 u1 ~: T# C, U$ g% Y. W
  49. ' G7 v* ]# w7 |, l

  50. & t1 ^$ }% z" B
  51. //如果cookieValue为空,返回,% }" [$ n6 `% A+ U

  52. % x% b- l8 p' F  B) }: z3 v
  53. if(cookieValue==null){1 Y1 t. {  z, s. s8 b

  54. 7 A, `2 U7 N, F; ~+ N2 S+ M1 {4 i
  55. return;
    4 x' M) \) c2 `" H3 z4 B0 k: C
  56. 3 ?2 f: E+ \! p+ c- o* ?5 i  T6 i
  57. }
    ' T: x0 {0 Q- i$ v) U9 z) G

  58. - d! W! `' C. `% y. z7 ]8 ]1 d, N2 c. m
  59. //如果cookieValue不为空,才执行下面的代码
    / S" X/ c2 J; B: R6 \/ l1 P3 Q
  60. & a' C6 `" Y) v- [/ S$ K
  61. //先得到的CookieValue进行Base64解码: ~6 ~5 P5 E+ r* N2 w, U+ @+ }
  62.   L  ~' ?8 @  \) T
  63. String cookieValueAfterDecode = new String (Base64.decode(cookieValue),"utf-8");
    ! m9 E. B- u- V5 d

  64. ) D% q& I2 |, C1 e. ^
  65. //对解码后的值进行分拆,得到一个数组,如果数组长度不为3,就是非法登陆3 U* H! F2 p2 P6 |
  66. String cookieValues[] = cookieValueAfterDecode.split(":");
    : x7 Z6 |+ c- z1 y* b, ^
  67. if(cookieValues.length!=3){! ]' W0 f# \2 U7 q6 q& d  ]
  68. response.setContentType("text/html; charset=utf-8"); ; Q0 i  y* W7 `2 y% U, `0 W
  69. PrintWriter out = response.getWriter(); 3 v8 v9 h0 r# E
  70. out.println("你正在用非正常方式进入本站..."); 2 V1 X% a/ X4 x
  71. out.close();
    . z' K+ U, B) K
  72. return;
    - I# b- f+ b& P7 O% u
  73. }
    8 v: E9 M" q$ m$ s5 t
  74. //判断是否在有效期内,过期就删除Cookie( a% ?8 Z1 g2 Z
  75. long validTimeInCookie = new Long(cookieValues[1]);
    : B7 s; ]3 [3 |, M* j/ d
  76. if(validTimeInCookie < System.currentTimeMillis()){
    : q# m/ O) V1 T/ c5 B+ i
  77. //删除Cookie
    $ I! ^5 P! Q3 L8 y+ K
  78. clearCookie(response);
    - \' j1 m" b  e% C- C. H
  79. response.setContentType("text/html; charset=utf-8"); , s& z/ F+ V. L: i( Y% R
  80. PrintWriter out = response.getWriter(); - {  ^1 f& w; |! z9 Z
  81. out.println("<a href=’logon.jsp’>你的Cookie已经失效,请重新登陆</a>"); ) J% I" S. k% a) `8 x9 n
  82. out.close(); 8 [9 B6 S6 n+ f5 d" K% Q& G) V/ E
  83. return;
    0 [; u9 V4 L. l) b/ b/ ~$ H( O
  84. }: ~8 H. h  Z+ w. I$ S9 T! H

  85. 2 b9 y( S6 C9 s/ o
  86. //取出cookie中的用户名,并到数据库中检查这个用户名,, h' d) |* A! M* s$ N1 @' G
  87. String username = cookieValues[0];
    ( N7 j. }9 d$ ~
  88. //根据用户名到数据库中检查用户是否存在
    3 g/ e) Q! c  s4 d
  89. UserDAO ud = DaoImplFactory.getInstance();% K- L2 r/ X1 N3 u% q1 n7 ~0 C

  90. 7 X9 L' z, G4 U5 e/ ?$ @# q' N# d
  91. User user = ud.selectUserByUsername(username);1 t: q9 N$ W/ b* C

  92. - ]- ^6 W* T$ p, h
  93. //如果user返回不为空,就取出密码,使用用户名+密码+有效时间+ webSiteKey进行MD5加密
    $ x0 G4 S) E" n/ o% Y) U+ k2 _/ E$ s
  94. if(user!=null){4 z- P$ R2 S" k$ h
  95. String md5ValueInCookie = cookieValues[2]; % w7 h( D: v/ _- N( i
  96. String md5ValueFromUser =getMD5(user.getUserName() + ":" + user.getPassword()+ ":" + validTimeInCookie + ":" + webKey);
    ' L; W& E! V* a. v+ {
  97. //将结果与Cookie中的MD5码相比较,如果相同,写入Session,自动登陆成功,并继续用户请求$ f; x# @# o+ F$ Q8 s/ e
  98. if(md5ValueFromUser.equals(md5ValueInCookie)){4 o# w' Y) k5 Y: p' p2 v1 d  |  w' c
  99. HttpSession session = request.getSession(true); # O7 L. |! @& c) _+ G7 K4 C
  100. session.setAttribute("user", user); / O" f) l( M; q; w' v
  101. chain.doFilter(request, response); 6 R9 U* A: y, Z5 U: y  R( m/ S
  102. }0 u4 _+ R6 I: [& t6 |, j) A
  103. }else{
    2 p- z1 k% H* V: O
  104. //返回为空执行
    ! u+ z: D) P4 p* |+ S
  105. response.setContentType("text/html; charset=utf-8");
    + U4 v+ Z' t0 R/ Y' Z6 x
  106. PrintWriter out = response.getWriter(); 0 ^$ ?. x3 |9 L. q9 l$ t3 s4 y
  107. out.println("cookie验证错误!"); ( s7 Z5 T( O; g& I* m& Q
  108. out.close(); + `6 I$ R# H, e( [, o$ H. P2 M& V
  109. return;
    $ V) j. v/ m4 ?2 \7 b; A
  110. }
      ^" {& T1 a, V5 _
  111. }
    7 X5 D1 }  S" U# e; |( q
  112. //用户注销时,清除Cookie,在需要时可随时调用------------------------------------------------------------
    ! C) e3 Z8 j: i( ~" v7 u: E
  113. public static void clearCookie( HttpServletResponse response){
    6 ]& k; J" d( H4 s0 q& Q
  114. Cookie cookie = new Cookie(cookieDomainName, null); / @$ p2 r' w' R  ^; k9 r; ~
  115. cookie.setMaxAge(0); ) |. O* E" L6 p0 v' g' _
  116. cookie.setPath("/");
    % [$ p2 ]1 v6 |' g; H5 O
  117. response.addCookie(cookie);
    5 E/ C% C6 A. ^. D- L5 ]- @
  118. }
    7 q: }1 ^; l0 ?* E$ U
  119. //获取Cookie组合字符串的MD5码的字符串----------------------------------------------------------------------------1 d! ?( B% ^3 r7 i
  120. public static String getMD5(String value) {9 s' K7 W. ?9 K
  121. String result = null;
    1 L# M3 M) [3 t! H  f8 A
  122. try{
    3 C6 H( T. @4 Z
  123. byte[] valueByte = value.getBytes(); . D( B/ R  G0 T/ [- a) r, u! K: p
  124. MessageDigest md = MessageDigest.getInstance("MD5"); 8 I6 O0 U0 l7 d" i1 G7 y& S
  125. md.update(valueByte); 8 [' z/ [- @0 T& k: }# ?  W
  126. result = toHex(md.digest());
    4 W; u* f4 b" u! c  P
  127. } catch (NoSuchAlgorithmException e2){
    4 s2 S: e2 E. ]
  128. e1.printStackTrace(); ! Y  z7 m& \# k- d6 e
  129. }5 h1 v7 ?) U, y* ?7 V3 k
  130. return result; : Q1 Q6 ]1 l+ S/ Y& B
  131. }3 m9 l: P6 }) `" j% M
  132. 0 q3 ?1 b. }: W" R) X
  133. //将传递进来的字节数组转换成十六进制的字符串形式并返回  W' ]( b" w9 c% Q) j2 U

  134. 5 p$ h$ q. C4 T# k* s" z2 Y
  135. private static String toHex(byte[] buffer){
    2 W, z/ H6 a! E- o/ \
  136. StringBuffer sb = new StringBuffer(buffer.length * 2); 0 w; o8 B6 w5 l+ A, `
  137. for (int i = 0; i < buffer.length; i++){
    1 S; F7 n  \9 Z7 z% @
  138. sb.append(Character.forDigit((buffer[i] & 0xf0) >> 4, 16)); ) E% i0 N6 b9 a" E. q
  139. sb.append(Character.forDigit(buffer[i] & 0x0f, 16)); ' r4 E% D1 V: x; m/ Z
  140. }0 G- G% z+ `5 V- G; `0 }7 i
  141. return sb.toString();
    6 N' w) x$ H4 _7 |4 ^
  142. }
    1 w: k0 A$ l$ D. v" Z
  143. }
    $ K) @' q7 z" w( S5 b$ I5 m$ L4 _

  144. 9 z  E6 S) y* u3 C
  145. 下面的是对CookieUtil工具类各方法的调用演示:
    " @8 l1 o! f: [5 p# F# y7 H$ K, p
  146. . X. p4 x8 O' z8 p
  147. User.java0 Y2 b( h$ {1 J& o7 g) z. [2 W
  148. # a& S) o& u: E, V+ W
  149. 封装用户信息的JavaBean对象模型: \: `' ?! u. M4 z  A, l
  150. package com.itcast.bean;
    8 ^3 P: u$ g: [% r+ _
  151. public class User {9 K' B; B. f# B
  152. private int id;
    5 o' p; H# ?3 a( ]$ K- F; d0 K
  153. private String userName;
      W1 v# ]3 |/ x# p
  154. private String password; . B/ {! k# K  Z; }
  155. public String getPassword() {
    + K# n/ E, t& ?$ c: F# L
  156. + k7 c) [1 m: |$ y" K+ j
  157. return password;
    6 c) i6 V+ W% {6 m/ N
  158. ! M7 _* ~6 S3 J( I2 H4 Q
  159. }
    8 e& b  D) ]# N5 {( ~
  160. public void setPassword(String password) {: l) Z$ q% I$ j2 j, Q7 e6 |
  161. & K* L  o( q3 o" f' X
  162. this.password = password;
    6 f) Z! B* s% q7 m

  163. " i  x9 F9 Y# q! j7 v2 p
  164. }- `# O. D" g) L3 T" c2 g7 r

  165. 0 e- ]4 {( z# P7 F6 M
  166. public String getUserName() {# }$ Z1 U; r: m9 z, E) p. @0 w

  167. ( A* m2 A) {+ M8 I; R8 R7 |  k& c4 v
  168. return userName;
    ; w! T2 P& Y+ ?. t4 B' E) c
  169. 6 U' C' o& l; v) o
  170. }# x6 i  E" G# D" y  N) i

  171. , u4 F1 n, w, _: e* f1 @
  172. public void setUserName(String userName) {7 E% Y5 B/ R  d5 `" g: g
  173. & z6 r6 K7 ^; \( A5 x
  174. this.userName = userName;
    # D) e2 U; P2 {: ^. N0 a) _

  175. / z: C' O! G* ?2 Q* d4 b4 @
  176. }
    ) O' s: C! h2 N

  177. 4 v1 g$ {& l" u$ E# \
  178. public int getId() {( P2 ?" L! G( B+ F. N

  179. ( z' ~. L/ g! j9 N4 j
  180. return id;7 o) x, ]- z& S* ]* |
  181.   `" A' Y5 C. Q9 d% L8 E
  182. }
    + V, a  C: G0 o3 g: j' S- N& N8 {

  183. ' T2 p$ p- p' G
  184. public void setId(int id) {
    ) Z& c/ e9 s) o- o0 t6 I4 h

  185. ) `. m' u3 J7 x0 f2 E+ u+ k4 B
  186. this.id = id;
    9 J! p! z' v3 z- c* ]# E2 ^

  187. * b* Q/ D7 ]: s+ W1 g: v1 ]
  188. }% ~' g- }( ]& c/ \: ?
  189. 1 D/ P: R9 t! |' H# `" Y
  190. }
复制代码

7 Q0 q- n! Q* ?. WAutoLogonFilter.java  P, n7 @2 y2 d! p( g& \
3 u) t$ r$ N  ?& U* g
过滤器程序,可在WEB-INF/web.xml中设置过滤规则,本文对过滤规则不作介绍,此程序主要作用是检查用户在上一次登陆时是否保存了Cookie,如果保存了,就处理Cookie信息,并帮助用户自动登陆! m; q1 ?3 e& c9 R. ?2 V! Y! R
8 t/ `$ @, ~, F5 w( U0 U
% E+ [0 R  s( r- c5 @
本程序主要调用了CookieUtil.java中的读取与自动登陆方法,即readCookieAndLogon方法
8 t* t6 D- [' v% U  P/ Z: d
  1. package cn.itcast.filter;
    ! Q& E; v/ M* C: `8 n
  2. ) P8 \7 a4 ^( L& I) j$ S8 L
  3. import java.io.IOException;
    . ^" H# s; G( N2 l+ H
  4. import javax.servlet.Filter;
    6 `* W# A5 _% J- U- v
  5. import javax.servlet.FilterChain;
    ( t) u, h+ M4 P& l1 {# k
  6. import javax.servlet.FilterConfig;
    . W5 Z+ I) ]1 Z! G1 X2 y
  7. import javax.servlet.ServletException; ) ?0 a& p$ G/ k) ^: a
  8. import javax.servlet.ServletRequest;
    $ E4 a* i/ W, p/ j0 @. E" E
  9. import javax.servlet.ServletResponse; & M, u' ?0 X4 {! X* c. S! B" a
  10. import javax.servlet.http.Cookie; * S; }, I# R( b3 v" U
  11. import javax.servlet.http.HttpServletRequest;
    $ S  j3 a! j  {* X3 }& g3 `3 X
  12. import javax.servlet.http.HttpServletResponse;
    " E" V1 j: {( W7 R' f3 ^
  13. import javax.servlet.http.HttpSession; , z7 h. }$ \. J7 \  p
  14. import cn.itcast bean.User; 8 |/ W. a; ~2 @2 N' ~/ p8 R. A
  15. import cn.itcast.util.CookieUtil;
    * R! q$ J% w6 z4 Z, C; w

  16. ! `, h$ h/ A4 z  ?
  17. public class AutoLogonFilter implements Filter {2 G( Y0 Q* G) c- J. ~! k( `
  18. ' [9 x1 x- t/ D. n# [. J% M! |7 p
  19. public void destroy() {
    ! n9 G  ^$ I% R/ T+ N* l

  20. 6 X  D( m! b' c5 l
  21. }
    ( R0 P5 f' M: Z  Q$ h2 e

  22. ! @, c( {1 `5 B2 K
  23. //保存cookie时的cookieName,与CookieUtil.java中的设置相同* [5 q; e2 u3 t* t. D3 N

  24. ; I; o7 E! j  q7 q5 L7 v$ u6 h
  25. private final static String cookieDomainName = “cn.itcast”;" ]% Z" @+ G: z

  26. . \1 s) ^) }. n! u
  27. 0 r) b$ I1 o7 y) E

  28. 0 w4 D( S7 J- {
  29. public void doFilter(ServletRequest req, ServletResponse resp,! A% c' A% z: B: ?; D$ w8 O: k/ `
  30. FilterChain chain) throws IOException, ServletException {
    " l, x2 L7 @/ m5 h  J
  31. HttpServletRequest request = (HttpServletRequest)req;
    ! d) K' X1 Y3 q5 J5 F! c
  32. HttpServletResponse response = (HttpServletResponse)resp; ( i  L( Y. \" w1 E0 h: E
  33. HttpSession session = request.getSession(true); & r* @( A- l  D( M
  34. User user = (User)session.getAttribute("user");0 i# Z7 R6 X* E$ u) ]

  35.   g2 ~" I) l- U. t

  36. ' {  k' z( L! {9 k* k1 b* ]7 m
  37. //如果封装的user不为空,说明已经登陆,则继续执行用户的请求.下面的就不处理了
    * @0 U" P; V9 w! ~7 p

  38. $ i; @4 z( s& K, d& O9 }
  39. if(user!=null){* P! Q  Z( z' N5 K8 C& C9 h# U3 s
  40. chain.doFilter(request,response);
    : i6 R" j: G; L' s
  41. return; 5 w  {* b7 f# M# `# c
  42. }2 R. ~; E, {# N- S

  43. 4 o6 }# V- G. N- |: m3 Y5 n/ i, n+ q& l
  44. //user为空,说明用户还没有登陆,就尝试得到浏览器传送过来的Cookie
    7 s% x8 u% {$ c1 ^
  45. Cookie cookies[] = request.getCookies();
    ; o/ Y- @9 O$ X& i% i
  46. String cookieValue = null;
    - m( w, b( g5 T& N& j) [
  47. if(cookies!=null){
    , ^# s: G2 x" i/ {: t4 y1 e* D- U
  48. for(int i=0; i<cookies.length; i++){: h8 C: d& W. O4 b% x3 t3 j
  49. if (cookieDomainName.equals(cookies[i].getName())) {
    ! K# G- O  P! U" T) C5 S. }* N+ ~
  50. cookieValue = cookies[i].getValue(); 0 i, V2 [2 @" K* H/ h% j
  51. break; . l! I% n4 c: T7 N7 R
  52. }4 w% k, ?, X' y8 K! N9 [
  53. }3 b- f. w* I$ L- l+ X. F) V6 |
  54. }
    ( }$ k7 b- a$ A( m6 R4 X3 p1 m. ]
  55. ) R( f" k; @4 C
  56. 2 z: h% K2 N0 X3 z* s- d
  57. //如果cookieValue为空,也继续执行用户请求
    5 }; K, O1 p- Q- f5 U
  58. if(cookieValue==null){7 Y- u2 ]; u2 j$ E: y8 V- x0 Y
  59. chain.doFilter(request,response); ( Q' U! l. R; ^
  60. return; , |( P, g/ B" j( g8 G/ f3 }" N
  61. }
    4 Q1 }, y2 C  G2 }, c0 Z* M

  62. 6 h! N$ F6 l! Q
  63. //cookieValue不为空执行下面的方法,调用CookieUtil.java中的readCookieAndLogon方法
      m% b# Y6 E/ n% o, Y
  64. try{' a# Z  Z' A) U
  65. CookieUtil.readCookieAndLogon(cookieValue, request, response, chain); ( ~  E; p" t0 u- `
  66. }catch(Exception e){8 Z, }% }% ]$ ?2 r; o
  67. e.printStackTrace();
    5 X0 d' @& X! Y. X% W% g9 O& D
  68. }
    3 N, @! Y  A! F. U
  69. }
    0 p( ~# Q1 h8 B2 G6 q
  70. + a) [: L) f# p+ G" G
  71. public void init(FilterConfig arg0) throws ServletException {
    ! v; W9 {) Q  r
  72. }
    0 T" V. J/ v9 V6 F
  73. }
复制代码

0 S- P5 r6 i- {, K5 s1 ?% A' qCheckLogonServlet.java
  C) F5 }9 ^3 c5 ]8 }9 \3 A( l, Q4 f/ W. G
验证用户登陆信息的Servlet,此程序调用了CookieUtil.java中的saveCookie方法5 G7 K& r% o/ J5 H( ^% j% J
- N, R+ u6 S0 |; `
package cn.itcast.servlet;
0 E$ n# \5 ^" k
  1. import java.io.IOException; # g8 [- Z' m* M; w$ B0 @
  2. import javax.servlet.ServletException; 7 _/ J* _( q* d- z
  3. import javax.servlet.http.HttpServlet;
    & [+ {8 Z' ?3 l" k8 N2 a
  4. import javax.servlet.http.HttpServletRequest;
    5 K, i$ W) }* y6 l
  5. import javax.servlet.http.HttpServletResponse;
    # q$ j4 x6 z7 M+ s6 Y& F: Q
  6. import javax.servlet.http.HttpSession;
    : H/ J2 r: b" W7 _# `: u5 u
  7. import cn.itcast.bean.User; 5 g% H. y0 b% V, x+ T
  8. import cn.itcast.dao.UserDAO;
    / _4 i0 b3 f$ Z* L$ y6 b
  9. import cn.itcast.factory.DaoImplFactory;
    ( `! g+ ?0 F! {% g  {
  10. import cn.itcast.util.CookieUtil;" C) j* n7 T$ U) |( r8 U" }' H
  11. ! Q3 O! R& {; T5 I% t3 t- Q, }
  12. public class CheckLogonServlet extends HttpServlet {4 k+ B! Z- x4 J. \
  13.   |/ l! v: M+ H
  14. public void doGet(HttpServletRequest request, HttpServletResponse response)
    6 Q- j2 u3 W9 q1 @5 ~
  15. throws ServletException, IOException {) \7 \# s$ z% i5 E& N7 X& d  L
  16. doPost(request, response); & P8 y! e4 f: r  y# ^
  17. }
    $ J" s0 h, W$ L

  18. $ S" B9 C$ k* E$ J& Y7 U, k2 y. y# F
  19. public void doPost(HttpServletRequest request, HttpServletResponse response)
    " Y/ r/ _, w/ q. g
  20. throws ServletException, IOException {8 p( J: ?$ J3 J+ S1 w! ~$ V. _
  21. request.setCharacterEncoding("utf-8"); # r& `% J; C6 X; L: H
  22. String username = request.getParameter("username").trim();
    1 s3 Y! m6 F9 o( V7 s; Z* g0 _" [
  23. String password = CookieUtil.getMD5(request.getParameter("password"));
    ; S2 r! H  v2 U, A9 l8 ?( H+ \
  24. String remeberMe = request.getParameter("remeberMe");
    1 D; Z8 E, L0 J5 _  V
  25. HttpSession session = request.getSession(false);. O% r# {: x! s, \4 R2 Z) S
  26. 8 z* a' s+ H5 i1 k5 a* x& n
  27. // 将接收到的用户名传递到UserDao的checkUser方法中,检查用户+ [) ~( ?& ]+ P
  28. // 返回一个User类型的对象0 e; A7 D, {7 P' V  W& x) R2 d
  29. UserDAO ud = DaoImplFactory.getInstance();
    1 I) s, V! K- h7 Q& l
  30. User user = ud.selectUserByUsername(username);
    0 e- f1 H6 k8 Z+ H: f- o$ E
  31. if (user == null) {
    ) `, L* j) V8 L+ \0 }
  32. request.setAttribute("checkUserError","<a href='register.jsp'><font color=red>用户名不存在,请先注册</font></a>"); % _2 Q  f& z# U# }  G
  33. request.getRequestDispatcher("index.jsp").forward(request, response);   l9 a" }* {9 s1 a' ^
  34. return;
    0 [) L, @# e8 U; l1 D( o
  35. }" V* a. o- y0 N
  36. 2 P7 t& D, j4 e0 m8 a& ]) g
  37. if(!password.equals(user.getPassword())){) \0 F* j9 U# a+ m/ k2 {
  38. request.setAttribute("checkPasswordError","<font color=red>密码输入错误,请重新输入</font>"); ) j) S! Y; E* X: z7 U& v
  39. request.getRequestDispatcher("index.jsp").forward(request, response);
    9 x/ \& b! }) X9 s. K% Y
  40. return; % z. l* l5 k! X4 r
  41. }# e9 g3 I: E2 G* L% L' D; h+ L: j( `
  42.   \. V. @1 B8 u/ H
  43. : d) F% X! p: R
  44. //保存Cookie,这里调用了CookieUtil.java中的saveCookie方法,将上面的user对象作为参数传递
      h2 E* e* j% c
  45. if ("on".equals(remeberMe)) {0 Z3 ~& D! @) ]' y) u: C1 k( G1 B- |
  46. CookieUtil.saveCookie(user, response);
    ! B( f* l2 k) H& m: ?
  47. }
    2 j2 D; d5 S+ _- k5 t
  48. //在Session中保存用户信息,并转向用户的个人信息页面
    - q% N1 M9 s0 V$ L  F2 ]
  49. session.setAttribute("user", user);
    7 H5 c( X; v9 m+ n+ G' N' w
  50. request.getRequestDispatcher("User/userInfo.jsp").forward(request,response); - @  Y# S. k7 M! w& I
  51. }% O% K. |1 u. b1 |9 Z9 P
  52. }
复制代码
% B: Y7 e0 S* d
UserDAO.java与DaoImplFactory.java属于持久层相关的程序,这里就不贴出来了,读者可根据自己需要选择不同的持久层框架,在本程序中只要实现查询用户的功能就可以了, H# h* A" `* C1 h2 L; R$ k
# V, {# o9 M% J8 X1 a+ z& c
; _  i% `) K; X* A+ n

科帮网 1、本主题所有言论和图片纯属会员个人意见,与本社区立场无关
2、本站所有主题由该帖子作者发表,该帖子作者与科帮网享有帖子相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和科帮网的同意
4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、科帮网管理员和版主有权不事先通知发贴者而删除本文


JAVA爱好者①群:JAVA爱好者① JAVA爱好者②群:JAVA爱好者② JAVA爱好者③ : JAVA爱好者③

快速回复
您需要登录后才可以回帖 登录 | 立即注册

   

关闭

站长推荐上一条 /1 下一条

发布主题 快速回复 返回列表 联系我们 官方QQ群 科帮网手机客户端
快速回复 返回顶部 返回列表