项目实施-08 (Jquery埋点设计)

概述

前端页面中要设计埋点,用来收集用户的行为习惯等信息以便进行实时流计算,从而提高系统的安全性。如:登录风险评估等。
本篇简单介绍了一个登录输入时长检查的埋点的设计。

引入Cookic

引入cookic,目的是为了,我们可以将在页面定制的一些采集的数据,通过请求发送的形式,携带到服务器端。

引入cookic插件

将下面的文本Copy到自定义的一个**.js**结尾的文件中, 完成cookic插件的引入。
例: jquery.cookic.min.js

/*! jquery.cookie v1.4.1 | MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?a(require("jquery")):a(jQuery)}(function(a){function b(a){return h.raw?a:encodeURIComponent(a)}function c(a){return h.raw?a:decodeURIComponent(a)}function d(a){return b(h.json?JSON.stringify(a):String(a))}function e(a){0===a.indexOf('"')&&(a=a.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return a=decodeURIComponent(a.replace(g," ")),h.json?JSON.parse(a):a}catch(b){}}function f(b,c){var d=h.raw?b:e(b);return a.isFunction(c)?c(d):d}var g=/\+/g,h=a.cookie=function(e,g,i){if(void 0!==g&&!a.isFunction(g)){if(i=a.extend({},h.defaults,i),"number"==typeof i.expires){var j=i.expires,k=i.expires=new Date;k.setTime(+k+864e5*j)}return document.cookie=[b(e),"=",d(g),i.expires?"; expires="+i.expires.toUTCString():"",i.path?"; path="+i.path:"",i.domain?"; domain="+i.domain:"",i.secure?"; secure":""].join("")}for(var l=e?void 0:{},m=document.cookie?document.cookie.split("; "):[],n=0,o=m.length;o>n;n++){var p=m[n].split("="),q=c(p.shift()),r=p.join("=");if(e&&e===q){l=f(r,g);break}e||void 0===(r=f(r))||(l[q]=r)}return l};h.defaults={},a.removeCookie=function(b,c){return void 0===a.cookie(b)?!1:(a.cookie(b,"",a.extend({},c,{expires:-1})),!a.cookie(b))}});
声明插件的引用
 <script type="text/javascript" src="/static/common/jquery.cookic.min.js"></script>

设计埋点

定义埋点
$.fn.extend({
    inputFeatures: function () {//收集用户的表单输入特征
        var inputs = $(this).find("input")
        //定义一个特性集合
        var futuresMap = {}
        $.each(inputs, function (i, item) {

            $(item).bind("keydown", function (event) {
                //如果已经有起始时间就采用原来的起始时间
                var start = $(this).data("start")
                //如果时间是空的
                if (!start) {
                    var start = new Date().getTime();//按下去记一次start
                    $(this).data("start", start)
                }
            })

            $(item).bind("keyup", function (event) {
                var end = new Date().getTime();//弹起去记一次end
                var start = $(this).data("start")
                //如果当前输入框中无值
                if ($(this).val() == "") {
                    //将时间start置为null
                    $(this).data("start", null)
                    //这个特性的数组置为0
                    futuresMap[i] = 0
                } else {
                    futuresMap[i] = end - start
                }

                //定义一个数组
                var keys = []
                for (var k in futuresMap) {
                    keys.push(k)
                }
                //对key进行排序
                var sortedKeys = keys.sort();
                //获取表单输入特征
               var feature =  sortedKeys.map(key=>futuresMap[key])
             /*   console.log(feature.join(","))*/
                //存放到会话cookic中 //设置全局可访问此cookic
                $.cookie("feature",feature.join(","),{path:'/'})
            })
        })
    }
})
声明使用埋点
<script>
   //设置一个定时器,给当前的输入绑定一个输入特性采集
   setTimeout(function(){
       $("#user_login_form").inputFeatures()
   },1000)
 })
</script>

<form id="user_login_form" method="post">
.
.
.
</form>ss

控制层接收埋点

这里的接收埋点信息,此次项目放在了拦截器中进行处理。
定义拦截器
package com.baizhi.interceptor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

//将此组件交给工厂
@Component
public class UserInputFeatureInterceptor implements HandlerInterceptor {
    private static final Logger LOGGER = LoggerFactory.getLogger(UserInputFeatureInterceptor.class);
    @Autowired
    private RestTemplate restTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //从请求中,获取cookic
        Cookie[] cookies = request.getCookies();
      /*  LOGGER.info("COOKIS长度\t"+cookies.length);
        for (Cookie cookie : cookies) {
            LOGGER.info(cookie.getName());
        }*/
        //定义一cookic值引用
        String  inputFeature=null;

        //遍历cookics,取出名为“feature”的cookic
        for (Cookie cookie : cookies) {
            if("feature".equals(cookie.getName())){
                inputFeature = URLDecoder.decode(cookie.getValue());
                //跳出循环
                break;
            }
        }
        //定义一处理ip的请求头
        String url = "http://ip-api.com/json/?ip={ip}";
        HashMap<String, Object> map = new HashMap<>();
        map.put("ip","123.149.125.171");
        Map ipParse = restTemplate.getForObject(url, Map.class, map);
        //获取信息
        String name = request.getParameter("name");
        String password = request.getParameter("password");
        //获取ip地址
        String ip = request.getRemoteAddr();
        //获取头信息
        String agent = request.getHeader("User-Agent");
        LOGGER.info("请求参数为\t"+name+"\t"+password+"\tip地址:"+ipParse+"\t请求头:"+agent+"\t输入特性是:"+inputFeature);
        /*2020-03-29 15:56:35.783  INFO 12620 --- [nio-9999-exec-8] c.b.i.UserInputFeatureInterceptor        : 请求参数为	测试数据2	000000	ip地址:{status=success, country=China, countryCode=CN, region=HA, regionName=Henan, city=Yingchuan, zip=, lat=34.2904, lon=113.382, timezone=Asia/Shanghai, isp=Chinanet, org=Chinanet HA, as=AS4134 Chinanet, query=123.149.125.171}	请求头:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36	输入特性是:2718,7472,1612
         */

        return true;
    }
}
配置拦截器

package com.baizhi.interceptor;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

//配置拦截器属性,使拦截器生效
@Configuration
class RealInerceptor implements WebMvcConfigurer {

    //注入自定义拦截器
    @Autowired
    UserInterceptor userInterceptor;
    @Autowired
    UserInputFeatureInterceptor userInputFeatureInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(userInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/static/**")
                .excludePathPatterns("/work/login/**")
                .excludePathPatterns("/user/loginCheck")
                .excludePathPatterns("/user/session")
                .excludePathPatterns("/user/existsUser")
                .excludePathPatterns("/user/zhuce")
                .excludePathPatterns("/code/**");
        //添加用户输入特征的拦截器
        registry.addInterceptor(userInputFeatureInterceptor)
                //拦截
                .addPathPatterns("/user/loginCheck");
    }
}

发布了32 篇原创文章 · 获赞 1 · 访问量 1155

猜你喜欢

转载自blog.csdn.net/ASYMUXUE/article/details/105180492
今日推荐