防盗链

Posted wuxun1997

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了防盗链相关的知识,希望对你有一定的参考价值。

  要说防盗链,得先说盗链。见名知义,盗链就是盗取别人的链接,最常见的就是盗图了。那么怎么防火防盗呢?传统的防盗链是通过http协议中的referer请求头来跟踪请求的来源,进而判断是否本站点的请求,从而达到防盗的目的。Referer长啥样?我用Fiddler抓了个包,看图

技术分享图片

 

 

 

 

 

 

 

 

 

 

 

       

 

  但目前更流行的防盗链方式是url签名,基本实现方案是针对请求参数签名,加入到url中,接收到该url后验证签名,通过则说明是自己人。参数的选取一般是个变量,比如时间戳、用户ID,签名算法一般是MD5。下面看个例子:

    public void action(HttpServletRequest request, HttpServletResponse response)
    {
        String purl = RequestTool.getParameter(ParamKeys.purl);
        
        // 获取原来的加密串
        String oldHash = RequestTool.getParameter(ParamKeys.safetyChainHashValue);
        
        // 获取session中保存的随机数
        String rands = (String)RequestTool.getSession().getAttribute(AttributeKeys.RANDOM_NUM);
        
        String msisdn = UserSession.getUserID(request);
        
        // 防盗链加密并加上随机数
        String hash = OrderHashTools.getSameUserHash(msisdn, rands);
        String newHash = SessionTools.encode(hash);
        
        // 防盗链校验通过,清空session中的随机数
        RequestTool.getSession().removeAttribute(AttributeKeys.RANDOM_NUM);
        
        OptResultBean resultBean = new OptResultBean();
        
        resultBean.setBackUrl(purl);
        
        // 如果防盗链不相等则跳通用的操作结果页
        if (StringTools.isEmpty(oldHash) || StringTools.isEmpty(newHash) || !StringTools.isEq(oldHash, newHash))
        {
            
            String sucMsg = PortalCacheManager.getParamValue("Anti_theft_chain_describe");
            resultBean.setResultMsg(sucMsg);
            RequestTool.getSession().setAttribute(AttributeKeys.OPERATE_RESULT, resultBean);
            
            // 跳通用的操作结果页
            String url = UrlTools.processForView(PreUrlConfig.getPreUrl(PreUrlConfig.OPERATE_RESULT_URL));
            
            RequestTool.sendRedirectAppendParams(url);
            return;
        }
        
        // 领取提示语
        String sucMsg = "";
        // 结果码
        String resultCode = "";
        
        Response resp =
            ((IserverService)ContextRegistry.getContextHolder().getContext().getBean("WlfService"))
                .exchangeCode("", "", "");
        if (Util.isNotEmpty(resp))
        {
            resultCode = resp.getResultCode();
            if (StringTools.isEq(resultCode, GET_KINDLE_SUCCESS))
            {
                // 领取成功
                sucMsg = resp.getPromptSuccess();
                resultBean.setResultMsg(sucMsg);
            }
            else if (StringTools.isEq(resultCode, GET_KINDLE_FAIL))
            {
                // 领取失败
                sucMsg = resp.getPromptFailure();
                resultBean.setResultMsg(sucMsg);
            }
        }
        
        RequestTool.getSession().setAttribute(AttributeKeys.OPERATE_RESULT, resultBean);
        // 跳通用的操作结果页
        String url = UrlTools.processForView(PreUrlConfig.getPreUrl(PreUrlConfig.OPERATE_RESULT_URL));
        
        RequestTool.sendRedirectAppendParams(url);
        
        return;
    }

  看下加密算法:

    /**
     * 根据手机号获得防盗链key加随机数
     * @param msisdn 手机号
     * @param random 随机数
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static String getSameUserHash(String msisdn,String random)
    {
        StringBuffer sb = new StringBuffer();
        sb.append(msisdn);
        sb.append(ENCRYPT_KEYS);
        sb.append(random);
        
        // 对字符串做MD5加密,再进行Base64编码
        return ThreeDes.base64AndMd5(sb.toString());
    }

 

以上是关于防盗链的主要内容,如果未能解决你的问题,请参考以下文章

C#防盗链处理类的代码

Apache网页优化之防盗链

Apache网页优化 ---配置防盗链

Nginx优化与防盗链

Nginx系列:Nginx + keepalived 实现高可用 + 防盗链 + 动静分离

Nginx系列:Nginx + keepalived 实现高可用 + 防盗链 + 动静分离