ajax 访问--提高安全性
首先受到struts token的启发,产生了客户端发起的ajax请求进行验证的想法,大致思路是客户端每次请求产生一个key ,然后服务端接收到key,然后解析,判断是否为合法key, 对于不带key 或者验证失败的直接拦截下来,从而减轻服务器的压力,好了废话不多说,上代码
首先我使用的是struts2的拦截器,(ps:不知道的度娘告诉你)

继承 AbstractInterceptor 实现init()和 intercept() ,从字面意思上去理解这两个方法 初始化 和拦截
第一个方法 就是从配置文件读取配置信息,没什么特别的
第二个方法 主要是分为两部分验证key 我这里 分 ajax 访问和普通方法 看代码
public String intercept(ActionInvocation invocation) throws Exception {
String rs = null;
if (isTokenInterceptor) {
boolean flag = false;
String msg = "{_success : false,_operationMsg:'非正常访问,属于非法客户端!'}";
ActionContext ac = invocation.getInvocationContext();
HttpServletRequest request = (HttpServletRequest) ac.get("com.opensymphony.xwork2.dispatcher.HttpServletRequest");
if (PublicUtil.isNotEmpty(freeURL)) {
String urlValue[] = freeURL.split(",");
if (PublicUtil.isNotEmpty(urlValue)) {
String as[];
int j = (as = urlValue).length;
for (int i = 0; i < j; i++) {
String url = as[i];
if (request.getRequestURI().indexOf(url) != -1) {
flag = true;
break;
}
}
}
}
if(!flag){
HttpSession session = request.getSession();
String requestToken;
HttpServletResponse response;
try {
response = (HttpServletResponse) ac.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse");
String requestType = request.getHeader("X-Requested-With");
if("XMLHttpRequest".equals(requestType)){ //验证是否为ajax 请求
requestToken = request.getHeader(TOKEN_NAME);
if(PublicUtil.isNotEmpty(requestToken) && requestToken.indexOf("||")!=-1){
String token = (String) session.getAttribute(SESSION_TOKEN);
if (!requestToken.equals(token)) {
flag = true;
} else {
logger.warn(PublicUtil.toAppendStr(
"客户端表单防重复验证生效:客户端多次提交 requestToken:",
requestToken));
msg = "{_success : false,_operationMsg : '对不起,网络异常,请重新提交尝试!'}";
}
session.setAttribute(SESSION_TOKEN, requestToken);
}
}else{ //普通请求 通过读取cookie 来验证
requestToken = CookieUtil.getCookie(request, TOKEN_NAME);
if(PublicUtil.isEmpty(requestToken)){
requestToken = DesUtil.getRequestKey();
}
if(PublicUtil.match("^[0-9]{8}$", DesUtil.strDec(requestToken))){
String token = (String) session.getAttribute(COOKIE_TOKEN);
if(PublicUtil.isEmpty(token)){
token = requestToken;
}
if (requestToken.equals(token)) {
flag = true;
} else {
logger.warn(PublicUtil.toAppendStr(
"客户端表单防重复验证生效:客户端多次提交 requestToken:",
requestToken, " url:", request.getRequestURI()));
msg = "{_success : false,_operationMsg : '对不起,网络异常,请重新提交尝试!'}";
}
}
String nextToken = DesUtil.getRequestKey();
CookieUtil.setCookie(response, TOKEN_NAME, nextToken);
session.setAttribute(COOKIE_TOKEN, nextToken);
flag = true;
}
} catch (IllegalStateException e) {
flag = false;
msg = PublicUtil.toAppendStr(
"{_success : false,_operationMsg : 'Error creating HttpSession due response is commited to client. You can use the CreateSessionInterceptor or create the HttpSession from your action before the result is rendered to the client: ",
e.getMessage(), "'}");
e.printStackTrace();
}
}
if (flag) {
rs = invocation.invoke();
} else {
HttpServletResponse response = (HttpServletResponse) ac
.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(msg);
}
} else {
rs = invocation.invoke();
}
return rs;
}
前台, 对于ajax 提交,我采用的header 夹带验证key的方式进行传递, 因为项目中使用的jquery 所以 我直接重写 $.ajax 方法就搞定了
var TOKEN_NAME = "Albedo-Requst-Token";
(function($){
//备份jquery的ajax方法
var _ajax=$.ajax; //重写jquery的ajax方法
$.ajax=function(opt){
//备份opt中error和success方法
var fn = {
error:function(XMLHttpRequest, textStatus, errorThrown){},
success:function(data, textStatus){}
}
if(opt.error){
fn.error=opt.error;
}
if(opt.success){
fn.success=opt.success;
} //扩展增强处理
var _opt = $.extend(opt,{
beforeSend: function(request) {
request.setRequestHeader("Albedo-Requst-Token", getRequestKey()+"||"+opt.url); //产生一个时间不同时的唯一key 特别注意 时间不同,如果时间相同,可以应该一样
},
error:function(XMLHttpRequest, textStatus, errorThrown){
//错误方法增强处理
fn.error(XMLHttpRequest, textStatus, errorThrown);
},
success:function(data, textStatus){
//成功回调方法增强处理
if(typeof data=="string"){ //对于被拦截下来的请求统一做提示
try{
eval("var rs = " + data);
if(rs && rs._success == false && rs._operationMsg){
if(!g_showTip) alert(rs._operationMsg);
else setTimeout(function(){g_showTip(rs._operationMsg);},500);
}
}catch(e){}
}
fn.success(data, textStatus);
}
});
_ajax(_opt);
};
})(jQuery);
当然,没有用这个的,也不要跪,至少还有?后面传参也是可以搞定的 ^_^,
这样之后就搞定了,如果一个页面连续对一个地址发起几次请求,那么这样之后只会有第一个请求成功,之后的请求全部会被拦截下来
ps: 个人见解,有不足之处,可以提出来大家参考
7T42CD{)VL4DTJM1]R.jpg)
ajax 访问--提高安全性的更多相关文章
- 提高安全性而在HTTP响应头中可以使用的各种响应头字段
本文介绍在Web服务器做出响应时,为了提高安全性而在HTTP响应头中可以使用的各种响应头字段.由于部分浏览器中有可能对某些字段或选项不提供支持,所以在使用这些字段时请先确认客户端环境. X-Frame ...
- ie8用ajax访问不能每次都刷新的问题
最近发现,用ajax访问后台,用ie8访问,第一次可以正常返回值,后面就一直不会执行后台,总是返回第一次访问的结果. 用ie9,ie10等都没问题,chrome,等浏览器也没有问题. 测试后发现,是i ...
- WebForm.aspx 页面通过 AJAX 访问WebForm.aspx.cs类中的方法,获取数据
WebForm.aspx 页面通过 AJAX 访问WebForm.aspx.cs类中的方法,获取数据 WebForm1.aspx 页面 (原生AJAX请求,写法一) <%@ Page Langu ...
- 通过ajax访问Tomcat服务器web service接口时出现No 'Access-Control-Allow-Origin' header问题的解决办法
问题描述 通过ajax访问Web服务器(Tomcat7.0.42)中的json web service接口的时候,报以下跨域问题: XMLHttpRequest cannot load http:// ...
- 【spring 后台跳转前台】使用ajax访问的后台,后台正常执行,返回数据,但是不能进入前台的ajax回调函数中
问题: 使用ajax访问的后台,后台正常执行,并且正常返回数据,但是不能进入前台的ajax回调函数中 问题展示: 问题解决: 最后发现是因为后台的方法并未加注解:@ResponseBody,导致方法 ...
- 通过ajax访问aspx的CodeBehind中的方法
引言 在项目中突然看到,aspx中的ajax可以访问aspx.cs中的方法,觉得很新奇,也许是lz少见多怪,不过,真的有发现新大陆似的那种兴奋,你也许知道这代表什么,学会了这种方式,代表你以后,可以建 ...
- jquery ajax 访问webServer的xml文件
最近项目中要使用到通过ajax访问webServer的xml文件,通过下面的方式可以直接访问webServer的xml文件,不需要在web.xml中进行任何配置.它的返回参数就是服务器上的xml文件. ...
- WebForm.aspx 页面通过 AJAX 访问WebForm.aspx.cs类中的方法,获取数据(转)
WebForm.aspx 页面通过 AJAX 访问WebForm.aspx.cs类中的方法,获取数据 WebForm1.aspx 页面 (原生AJAX请求,写法一) <%@ Page Langu ...
- 微信公众平台宣布增加接口IP白名单提高安全性
微信公众平台目前已经发布通知在平台接口调用上为了提高安全性需要添加IP白名单并仅允许白名单IP调用. 目前微信公众平台面向开发者主要提供的开发者ID和开发者密钥,在调用时ID和密钥通过检验即可进行调用 ...
随机推荐
- poj 1180 斜率优化dp
这个题目要是顺着dp的话很难做,但是倒着推就很容易退出比较简单的关系式了. dp[i]=min(dp[u]+(sum[u-1]-sum[i-1]+s)*f[i]);dp[i]代表从i到结尾需要花费的代 ...
- git pull使用【转】
转自:http://www.yiibai.com/git/git_pull.html git pull命令的作用是,取回远程主机某个分支的更新,再与本地的指定分支合并.它的完整格式稍稍有点复杂. $ ...
- UVa 10006 - Carmichael Numbers
UVa 10006 - Carmichael Numbers An important topic nowadays in computer science is cryptography. Some ...
- [HDOJ1078]FatMouse and Cheese(记忆化搜索)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1078 题意:给出n, k,然后给出n*n的地图,(下标0~n-1),有一只老鼠从(0,0)处出发,只能 ...
- 安卓发展史以及安卓和苹果对比PPT
此PPT由我们小组协力完成,介绍了Android的发展史以及android与苹果的一些比较.概述了android发展至今的一系列版本,功能的日益完善,它的强大性,灵活性,公开性使其拥有吸引客服的绝大魅 ...
- 一、Oracle分析函数入门
分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计值. 分析函数和聚合函数的不同 ...
- jpa+spring配置多数据源
property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/test?useU ...
- 无锁编程(六) - seqlock(顺序锁)
seqlock(顺序锁) 用于能够区分读与写的场合,并且是读操作很多.写操作很少,写操作的优先权大于读操作. seqlock的实现思路是,用一个递增的整型数表示sequence.写操作进入临界区时,s ...
- 【转载】正则表达式学习 & ASCII码表
文章原地址: http://www.jb51.net/tools/zhengze.html <正则表达式30分钟入门教程> 其中有几个地方可以有笔记: \s 匹配任意的空白符 \b 匹配单 ...
- minimum-genetic-mutation
题目还是很好的,提供了一种新的思路方向. 细节方面,开始我的判断条件用的dict,不太好,后来debug好了. 另外,注意其中用数组初始化Set的方法:Set<String> dict = ...