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和密钥通过检验即可进行调用 ...
随机推荐
- USACO Section 2.4: Fractions to Decimals
乍看题目感觉有难度,实际分析后其实是道简单题 /* ID: yingzho1 LANG: C++ TASK: fracdec */ #include <iostream> #include ...
- SGU 125 Shtirlits 搜索+可行性剪枝
500ms时限406ms水过…… 直接枚举肯定超时,需要剪枝. 枚举每个格子的元素,检查其左上角和正上方格子是否满足条件,若不满足不必再向下搜索. 在 这里 看到一个更好的方法: 枚举每个格子是哪个相 ...
- javascript 网络是否连接的几种方案
js 网络是否连接的几种方案 1.通过html5的新属性: window.onload = function () { var isOnLine = navigator.on ...
- POJ 3468 A Simple Problem with Integers (伸展树区间更新求和操作 , 模板)
伸展数最基本操作的模板,区间求和,区间更新.为了方便理解,特定附上一自己搞的搓图 这是样例中的数据输入后建成的树,其中的1,2是加入的边界顶点,数字代表节点编号,我们如果要对一段区间[l, r]进行操 ...
- EasyUi datagrid 表格分页例子
1.首先引入 easyui的 css 和 js 文件 2.前台 需要写的js //源数据 function Async(action,args,callback){ $.ajax({ url: a ...
- CSS和JavaScript标签style属性对照表
CSS和JavaScript标签style属性对照表一般情况是把"-"去掉,后面字母用大写. CSS语法 (不区分大小写) JavaScript语法 (区分大小写) border ...
- Android实现网络多线程文件下载
实现原理 (1)首先获得下载文件的长度,然后设置本地文件的长度. (2)根据文件长度和线程数计算每条线程下载的数据长度和下载位置. 如:文件的长度为6M,线程数为3,那么,每条线程下载的数据长度为2M ...
- Python 中 os.path模板
os.path.abspath(path) #返回绝对路径 os.path.basename(path) #返回文件名 os.path.commonprefix(list) #返回list(多个路径) ...
- JUnit 4
本文是转载的, 主要介绍 Junit 4 ( 搭建在 eclipse 中 ) JUnit4 初体验 Eclipse: 下载 Ant, 基于java的开源构建工具, 你可以在 http://ant.ap ...
- Intent Flag介绍 intent.addFlags()
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); FLAG_ACTIVITY_BROUGHT_TO_FRONT 这个标志一般不是由程序代码设置的 ...