ajax 訪問--提高安全性

來源:互聯網
上載者:User

標籤:des   style   blog   http   color   使用   

首先受到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: 個人見解,有不足之處,可以提出來大家參考

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.