2011年12月27日星期二

防止页面重复提交的 token使用方法

1、让你的Controller继承AbstractController
2、在加载新增/修改页面的方法中调用saveToken(request,response);
3、在jsp页面中的<form>中加入一个hidden:(这是死的 不用任何修改)
<input type="hidden" name="TRANSACTION_TOKEN_KEY" id="TRANSACTION_TOKEN_KEY" value="${sessionScope.TRANSACTION_TOKEN_KEY}"/>
4、在保存方法中加入下面类似代码:
if(!super.isTokenValid(request)){
model.addAttribute(DataKey.MESSAGE, "对不起,你不能重复提交同一表单内容");
return "error";
}

 

==================

AbstractController:

public synchronized void saveToken(HttpServletRequest request,HttpServletResponse response) {
//        setResponseNoCache(response); //
        HttpSession session = request.getSession();
        String token = generateToken(request);
        if (token != null) {
            session.setAttribute("TRANSACTION_TOKEN_KEY", token);
        }

    }

    public synchronized void saveToken(HttpServletRequest request) {
        HttpSession session = request.getSession();
        String token = generateToken(request);
        if (token != null) {
            session.setAttribute("TRANSACTION_TOKEN_KEY", token);
        }

    }


    /**
     * 验证TOKEN
     * @param request
     * @return
     */
    public synchronized  boolean isTokenValid(HttpServletRequest request) {
        // Retrieve the current session for this request
        HttpSession session = request.getSession(false);

        if (session == null) {
            return false;
        }

        // Retrieve the transaction token from this session, and
        // reset it if requested
        String saved =
            (String) session.getAttribute("TRANSACTION_TOKEN_KEY");

        if (saved == null) {
            return false;
        }


        // Retrieve the transaction token included in this request
        String token = request.getParameter("TRANSACTION_TOKEN_KEY");

        if (token == null) {
            return false;
        }
        session.removeAttribute("TRANSACTION_TOKEN_KEY");
        return saved.equals(token);
    }

    private synchronized String generateToken(HttpServletRequest request) {
           HttpSession session = request.getSession();
           try {
               byte id[] = session.getId().getBytes();
               byte now[] =
                   new Long(System.currentTimeMillis()).toString().getBytes();
               MessageDigest md = MessageDigest.getInstance("MD5");
               md.update(id);
               md.update(now);
               return (toHex(md.digest()));
           } catch (IllegalStateException e) {
               return (null);
           } catch (NoSuchAlgorithmException e) {
               return (null);
           }
       }

    private static String toHex(byte[] buffer) {
        StringBuffer sb = new StringBuffer(buffer.length * 2);

        for (int i = 0; i < buffer.length; i++) {
           sb.append(Character.forDigit((buffer[i] & 0xf0) >> 4, 16));
            sb.append(Character.forDigit(buffer[i] & 0x0f, 16));
        }

        return sb.toString();
   }

没有评论:

发表评论