小菜最近接触了struts2中的令牌知识,由于该知识点比较重要,因此想弄明白些,于是满怀信心的上网查阅资料,结果让小菜很无奈,网上的资料千篇一律,总结出来就一句话:“访问页面时,在页面产生一个token id,同时在服务器的session中保存一个同样的id,提交时判断如果相同怎么样不相同怎么样。。。”

可能是小菜愚笨,实在是无法从这么精炼的描述中体会令牌的精髓。

肤浅的那么一说,然后上来就是一堆代码,有时候对初学者的帮助可能不是很大,如果能够介绍一下其中的原理,无疑会加快读者学习速度。

经过刻苦的研究,下面小菜来介绍一下,令牌究竟是如何做到防止界面刷新的。

本文不涉及令牌具体用法,只讲原理。

首先需要说明的是,在struts2框架中使用令牌基本上就是两步:

l  在jsp页面中使用<s:token></s:token>标签,可以放在表单中任何位置,这个标签的作用就是在页面中产生一个token id,可以通过“查看源文件”的形式看到。为什么要放在表单中呢?因为这个是要提交到服务器的,要不然服务器怎么知道你的id是多少?

l  在struts2核心配置文件中为token拦截器添加参数,来指明需要拦截哪些方法,例如:<interceptor-ref name="token"><param name="includeMethods">save</param></interceptor-ref>,指明拦截save方法。当然也可以用excludeMethods来声明不拦截哪些方法。

令牌生成原理图:

从图中可以看出,如果某个jsp页面中有token标签,那么无论是请求这个界面还是内部转发到这个界面,我们统一说成是“渲染界面”的时候,都会造成token id的产生或者更新。

一定要搞清楚,这里是请求的jsp页面,此时可以产生令牌,但令牌不会起作用,因为它拦截的不是jsp,而是通过反射机制调用的方法。

令牌拦截原理图:

从图中可以看出,令牌可以拦截的是Action中的方法。

如果方法需要被拦截,会判断session中的token id和提交过来的token id是否相等。如果不相等,则直接跳转到预先配置好的界面,session中的token id不变;如果相等,则执行请求的方法,关键的一点是,此时session中的token id会被清空!这个步骤非常关键!

综上,关于令牌的使用,记住以下几点,基本可以应对各种复杂的令牌应用场景

l  注意令牌的产生时机,它是在加载(或渲染)带有token标签的jsp页面时产生的,与请求或者转发无关,与方法是否被拦截无关。

l  由于服务器端的token id是保存在session中的,因此不同的页面间可以共享,使用时注意,避免混乱。

l  如果访问的方法属于被拦截的方法,验证通过之后,会清空session中的token id;如果验证不通过,session 中的token id不变,直到下一次加载(或渲染)带有token标签的jsp页面。

再多啰嗦一些,为什么验证通过后要清空session中的token id呢?其实不难理解,从宏观上来思考,重复提交有一个必然的特征:它的token id是上一个。因此只要保证验证通过后session中保存的token id变化即可,清空是最直接的办法。要想通过验证,只有一个途径:重新加载(或渲染)带有token标签的jsp页面,使客户端的token id和服务器端的token id一致。

小菜总是希望自己的文章能够帮助更多的人,因此写的有点啰嗦,大家见谅!

struts2令牌(token)内部原理的更多相关文章

  1. struts2令牌,防止重复提交

    struts2的令牌,可以用来防止重复提交,其原理是在提交jsp页面中,写入一个隐藏域name="token",然后在action中定义一个变量token并get.set.在服务器 ...

  2. 深入理解javascript作用域系列第一篇——内部原理

    × 目录 [1]编译 [2]执行 [3]查询[4]嵌套[5]异常[6]原理 前面的话 javascript拥有一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量,这套规则被称为作用域.作用域 ...

  3. 【转】SQLServer内部原理

    原文地址:http://twb.iteye.com/blog/182083 在讲SQLSERVER内部原理的之前,我觉得非常有必要向大家介绍一下SQLSERVER的历史. 让我们站在1999年,看看计 ...

  4. QoS令牌桶工作原理

    QoS的一个重要作用就是对port流量进行监管,也就是限制port流量.但QoS是怎样做到这点的呢?那就是QoS的令牌桶机制了.以下是在笔者刚刚出版的<Cisco/H3C交换机高级配置与管理技术 ...

  5. Struts2进阶(一)运行原理及搭建步骤

    Struts2进阶(一)运行原理 Struts2框架 Struts2框架搭建步骤 致力于web服务,不可避免的涉及到编程实现部分功能.考虑使用到SSH框架中的Struts2.本篇文章只为深入理解Str ...

  6. 【转载】深入研究Windows内部原理绝对经典的资料

    原文:深入研究Windows内部原理绝对经典的资料 另一篇资料:深入研究Windows内部原理系列 (为了方便大家下,我打包了放在一下地址: 1-6:http://download.csdn.net/ ...

  7. struts2的token interceptor

    关于struts2的token拦截器的说明 原理:struts2的token interceptor是关于重复提交的拦截器,其实现是:在form表单中加入token标签,如下: <form ac ...

  8. Django中csrf token验证原理

    我多年没维护的博客园,有一篇初学Django时的笔记,记录了关于django-csrftoekn使用笔记,当时几乎是照抄官网的使用示例,后来工作全是用的flask.博客园也没有维护.直到我的博客收到了 ...

  9. [转]js作用域系列——内部原理

    前面的话 javascript拥有一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量,这套规则被称为作用域.作用域貌似简单,实则复杂,由于作用域与this机制非常容易混淆,使得理解作用域的原 ...

随机推荐

  1. AireOS WLC配置抓包

    这个Note主要列举在AireOS WLC上如何抓包.它实现的步骤也相对比较简单: 1.开启debug packet, 2.有数据被抓取到时,会以16进制的形式在WLC上输出, 3.我们将输出信息保存 ...

  2. Java面向对象编程 -2.2

    构造方法与匿名对象 现在的程序在使用类的时候一般都按照了如下的步骤进行: 声明并实例化对象,这个时候实例化对象中的属性并没有任何的数据存在,都是其对于数据类型的默认值 需要通过一系列的setter方法 ...

  3. 【PAT甲级】1065 A+B and C (64bit) (20 分)(大数溢出)

    题意: 输入三个整数A,B,C(long long范围内),输出是否A+B>C. trick: 测试点2包括溢出的数据,判断一下是否溢出即可. AAAAAccepted code: #defin ...

  4. vue父孙组件传值($attr及$listeners)的使用

    父组件 <template> <div> <!-- 将值传给子组件 子组件可以获取自己想要的值 也可以忽视掉需要传给孙子组件的值 --> <!-- 同时获取通 ...

  5. SpringMVC:详述拦截器

    将堆内存SpringMVC使用拦截器对请求进行拦截处理,以实现特定的功能: 具体实现: 1.自定义一个实现HandlerInterceptor接口的类并实现接口中定义的抽象方法(实现了三个方法,分别处 ...

  6. nginx防盗链处理模块referer和secure_link模块

    使用场景:某网站听过URI引用你的页面:当用户在网站点击url时:http头部会通过referer头部,将该网站当前页面的url带上,告诉服务本次请求是由这个页面发起的 思路:通过referer模块, ...

  7. 吴裕雄--天生自然ORACLE数据库学习笔记:其它数据对象

    create index emp_deptno_index on emp(deptno) pctfree tablespace users; create bitmap index emp_salar ...

  8. windows下代码规范检测工具sonarqube安装与使用,含与maven的结合

    一.首先下载sonarqube   地址 : https://www.sonarqube.org/downloads/   (最新版本支持java11+,博主下载支持java8的版本7.7), 下载S ...

  9. 63 滑动窗口的最大值 &&front(),back()操作前一定要判断容器的尺寸不能为0

    给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值.例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6, ...

  10. Java程序挂掉的几种可能

    今天花了一整天在跟踪一个问题,每次感觉已经快找到原因的时候发现现象又变了,我觉得从中吸取的教训可以给大家分享一下. 为了重现这个现象,我写了一个简单的例子.在本例中,先初始化了一个map,然后用一个无 ...