怎样定时清除session中的某一个值

maci_hotesion 2008-06-20 09:19:10
session 中放的是验证码,为了防止攻击,我要定时清除session中的这个验证码
产生验证码之后放入session中
session.setAttribute("verifyCode",验证码);
定时清除
session.removeAttribute("verifyCode")
...全文
1904 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
maci_hotesion 2008-06-24
  • 打赏
  • 举报
回复
[size=30px]已经结贴[/size]

下载地址:
http://download.csdn.net/source/511314
sagezk 2008-06-23
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 maci_hotesion 的回复:]
回 12、13楼 sagezk

说的很对,我确实发现过这个问题,但是不知道是怎么回事。有的浏览器确实能刷新,但有的浏览器确实不能刷新,此问题我一直没有去跟踪。这里非常感谢sagezk

验证码 放入session中不是不安全,这个大家都知道,应该是安全的;这也是我的错,首先前面我说的不到位。

其实我想做的功能是:让验证码在一段时间内有效。超过这段时间之后,哪怕用户输入正确的验证码也是错误的(因为时间已超过)。于是我…
[/Quote]

自己解决的很完美。
maci_hotesion 2008-06-23
  • 打赏
  • 举报
回复
回 12、13楼 sagezk

说的很对,我确实发现过这个问题,但是不知道是怎么回事。有的浏览器确实能刷新,但有的浏览器确实不能刷新,此问题我一直没有去跟踪。这里非常感谢sagezk

验证码 放入session中不是不安全,这个大家都知道,应该是安全的;这也是我的错,首先前面我说的不到位。

其实我想做的功能是:让验证码在一段时间内有效。超过这段时间之后,哪怕用户输入正确的验证码也是错误的(因为时间已超过)。于是我有了这个念头(定时清除session中的这个验证码),之后引出了这么多的问题。

sagezk的帮助下,最后问题得到解决。
解决办法是:
1.定义一个bean; bean,这个bean存放 verifyCode(验证码), expiredDate(过期时间);
2.把上面的这个bean保存到session中; session.setAttribute("veriryCode", bean);
3.从session中取出这个bean,将bean中的get属性,和用户输入的验证码提交的时间进行相比,如果小于expiredDate(过期时间),则在有效时间之类,进一步对用户输入的验证码进行比较。;

最后非常感谢sagezk的支持和帮助,以及来到这里的各位盟友。
这是我最后解决的方案,如果大家觉得还有问题的话,就再次提出。最后我将会把最终代码呈上。


maci_hotesion 2008-06-21
  • 打赏
  • 举报
回复
回 6 楼 laorer,非常感谢。 现将问题描述如下:


比如定时任务为10秒钟就执行: session.removeAttribute(sessionKey);

点击次数 验证码 开始时间 清除时间
1 ABCD 0 0....5...10
2 DCBA 5 5....10...15
3 KKBB 9 9....14...19

分析如下:
第2点击之后,第1次的任务还没有执行;第1次执行的任务时间为第10秒,可是第5秒的时候又有2次的点击,
于是第2次产生的验证码DCBA覆盖了第1次产生的验证码ABCD;
第3点击之后,第1次和第2次的任务都还没有执行,理论同上;可是到第10秒时,第1次的点击要执行任务,
于是把第3次产生的验证吗清除了。也就是说第3次产生的验证码的有限时间为1秒钟。
第2、3次的点击也会执行任务,但此时session中的验证码早已被第1次的任务清除了。

现在要解决的是:怎样判断上一次的任务是否已经执行,如果没有执行则销毁,重新分配新任务,如果
上一次的任务已经执行,则直接分配新任务。

这可能要涉及到线程处理的问题。

帮帮忙??谢谢各位。
来到这里的各位都发表一下自己的观点。
laorer 2008-06-21
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 maci_hotesion 的回复:]
代码基本上已经实现,可是用户不停的 点击图片验证码 进行刷新时,就会有问题。
[/Quote]
什么样的问题?
一般刷新时,就刷新 session啊
laorer 2008-06-21
  • 打赏
  • 举报
回复
我没有明白,感觉验证码用一次之后,就不可能再用的,
sagezk 2008-06-21
  • 打赏
  • 举报
回复
另外请教一下,为什么验证码在 Session 中保存时间超过 10 秒(一段时间)就会不安全?
sagezk 2008-06-21
  • 打赏
  • 举报
回复
先不跟你争论我对验证码的了解深不深入,先揪出你的一个严重的 Bug如下:
<img border="0" src="image.jsp" onclick="this.src='image.jsp'" title="看不清楚,点击图片即可刷新" style="cursor: hand;">
没看出什么问题吗?
虽然你在验证码图片响应头中设置了
//设置页面不缓存
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);

但这远远不够,如果你实际测试过就应该发现,有时点击验证码图片它并不会更新。原因在浏览器缓存。浏览器有时不会忠实的遵照你的响应头处理缓存。
改为如下:
<img src="image.jsp" title="看不清楚,点击图片即可刷新" style="border-style:none;cursor:hand;" onclick="this.src='image.jsp?temp='+(new Date().getTime().toString(36))">

你要是理解得“深入”应该能看明白上面的代码。
sagezk 2008-06-21
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 maci_hotesion 的回复:]
回 8 楼 sagezk :
看来你还不明白整个流程的意思,你对验证码的了解并不深入。登陆成功之后就可以让它失效,这个可以做到,但是如果不定时清除,会有一些不安全。加验证码的目的就是防止暴力破解


回 9 楼 fulianglove:
你把上面的程序运行一下,然后在页面上不停的 点击 验证码图片 刷新就看到效果了。
在image.jsp 文件里打印一下验证码的实际值;
在image.jsp 文件的代码前面加上这个代码
System.out.println…
[/Quote]
服!
maci_hotesion 2008-06-21
  • 打赏
  • 举报
回复
回 8 楼 sagezk :
看来你还不明白整个流程的意思,你对验证码的了解并不深入。登陆成功之后就可以让它失效,这个可以做到,但是如果不定时清除,会有一些不安全。加验证码的目的就是防止暴力破解



回 9 楼 fulianglove:
你把上面的程序运行一下,然后在页面上不停的 点击 验证码图片 刷新就看到效果了。
在image.jsp 文件里打印一下验证码的实际值;
在image.jsp 文件的代码前面加上这个代码
System.out.println(session.getAttribute("verifyCode"));
不停的点击之后打印出来的都是null


fulianglove 2008-06-21
  • 打赏
  • 举报
回复
你用什么做的,怎么还自己考虑并发处理阿,一个session对应一个用户会话,有什么影响??
而且我很不习惯把东西放到session里去,我觉得从头到尾只使用一个session,就是存放登录用户的信息就够了,其他的都不用
sagezk 2008-06-21
  • 打赏
  • 举报
回复
登录或注册成功后校验码就没用了,所以可以在登录或注册成功后 session.removeAttribute("verifyCode");。
maci_hotesion 2008-06-20
  • 打赏
  • 举报
回复
代码基本上已经实现,可是用户不停的 点击图片验证码 进行刷新时,就会有问题。
maci_hotesion 2008-06-20
  • 打赏
  • 举报
回复
回 3 楼,非常感谢。

可是如果不定时清除的话,这个验证码会一直存放在session中,攻击者会利用一定的时间进行攻击,所以要定时清除。


再详细描述一下:
session 中放的是验证码,为了防止攻击,我要定时清除session中的这个验证码
产生验证码之后放入session中:session.setAttribute("verifyCode",验证码);

定时清除:session.removeAttribute("verifyCode")

用户在页面点击【图片】(也就是验证码图片) 刷新 的时候,把上一次放入session中验证码清除掉,重新产生验证码,并存放到session中;
如果用户没有点击刷新,则在一定的时间之后自动清除session中的验证码。


代码:
index.jsp
<img border="0" src="image.jsp" onclick="this.src='image.jsp'" title="看不清楚,点击图片即可刷新" style="cursor: hand;">


image.jsp
<%@ page contentType="image/jpeg" import="java.io.*,java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %>
<%!
Random random = new Random();
Color getRandColor(int fc,int bc){//给定范围获得随机颜色
if(fc>255) fc=255;
if(bc>255) bc=255;
int r=fc+random.nextInt(bc-fc);
int g=fc+random.nextInt(bc-fc);
int b=fc+random.nextInt(bc-fc);
return new Color(r,g,b);
}

String getVerifyCode()
{
String strBase = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
int strBaseLen = strBase.length();
String verifyCode = "";
for (int i = 0; i < 6; i++)
{
int indexOf = random.nextInt(strBaseLen);
verifyCode += strBase.substring(indexOf,indexOf+1);
}
return verifyCode;
}
%>
<%
String fontName[] = {"Arial", "Courier", "Courier New", "Times New Roman"};

int fontSizeMin = 30;
int fontSizeMax = 30;

int imageWidth = 150;
int imageHeight = 35;

int fontSize = 50;

//设置页面不缓存
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);

// 在内存中创建图象
BufferedImage gImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);

// 获取图形上下文
Graphics gGraphic = gImage.getGraphics();

//生成随机类
Random random = new Random();

// 设定背景色
gGraphic.setColor(getRandColor(200,250));
gGraphic.fillRect(0, 0, imageWidth, imageHeight);


//画边框
gGraphic.setColor(new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256)));
gGraphic.drawRect(0,0,imageWidth-1,imageHeight-1);

//产生300条以内的干扰线,使图象中的认证码不易被其它程序探测到
gGraphic.setColor(getRandColor(160,200));
int intLen = random.nextInt(300);
for (int i=0;i<intLen;i++){
int x = random.nextInt(imageWidth);
int y = random.nextInt(imageHeight);
int xl = random.nextInt(imageWidth);
int yl = random.nextInt(imageHeight);
gGraphic.drawLine(x,y,x+xl,y+yl);
}

// 取随机产生的认证码(4位数字)
String verifyCode = getVerifyCode();
int _style = Font.BOLD;
for (int i=0;i<verifyCode.length();i++){
String rand = verifyCode.substring(i,i+1);
fontSize = fontSizeMin+random.nextInt(fontSizeMax - fontSizeMin+1);
//设定字体
gGraphic.setFont(new Font(fontName[random.nextInt(fontName.length)],Font.PLAIN,fontSize));
if (random.nextInt(100) > 40)
_style |= Font.ITALIC;
// 将认证码显示到图象中
gGraphic.setColor(new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256)));
//调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
gGraphic.drawString(rand,25*i+random.nextInt(4),(fontSize * 15 / 20)+4);
}

// 图象生效
gGraphic.dispose();
//将认证码存入session
out.clear();
out = pageContext.pushBody();
session.setAttribute("veriryCode", verifyCode);
//输出图象到页面
ImageIO.write(gImage, "JPEG", response.getOutputStream());

VerifyCodeTimer timerCode = new VerifyCodeTimer (request.getSession(),"veriryCode");
timerCode.timer.schedule(timerCode, 30 * 1000);//30秒钟
%>



VerifyCodeTimer.java 文件
public class VerifyCodeTimer extends TimerTask
{
private Timer timer;
private HttpSession session;
private String sessionKey;

public VerifyCodeTimer(HttpSession session,String sessionKey)
{
timer = new Timer();
this.session = session;
this.sessionKey = sessionKey;
}

public void run()
{
session.removeAttribute(sessionKey);
//timer.cancel();
}
}






laorer 2008-06-20
  • 打赏
  • 举报
回复
一般不是验证之后就清掉他吗?为什么要定时清掉?
phyeas 2008-06-20
  • 打赏
  • 举报
回复
Java Timer

67,515

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧