菜鸟合作伙伴日志接入规范之C#实现

由于行业的业务功能需要,需要与菜鸟对接登录日志,将我们系统的用户登录信息提交给菜鸟,菜鸟分析通过分析日志,检查存在的一些安全问题。根据菜鸟提供的标准,实现了C#的接入,下面分享给大家,让需要的朋友少走些弯路。

 

 

 

        /// <summary>
        /// 向菜鸟提交登录日志
        /// </summary>
        /// <param name="loginLogEntity">登录日志实体</param>
        private static void SendLoginLog(BaseLoginLogEntity loginLogEntity)
        {
            /*
            appId	                御城河应用标识	和御城河appKey值一样
            appKey	                御城河appKey	
            method	                日志类型(标识)	express_login
            time	                上传日志的时间	yyyy-MM-dd HH:mm:ss格式
            operation_time	        操作时间	yyyy-MM-dd HH:mm:ss格式
            company	                公司名称	公司名全称
            station_id	            站点id	例如:14214
            station	                站点名称	例如:xxx数据中心
            province	            站点所在省份	注:勿根据IP地址计算,要记录注册地址。例如:浙江
            city	                站点所在城市	注:勿根据IP地址计算,要记录注册地址。例如:杭州
            user_id	                操作员账号ID	
            user	                操作员账号名	
            source_type	            发起请求的终端应用类型	web、client、ios、android、database
            source_application	    发起请求的应用	如果是从数据库直接登陆数据库(source_type=Database),则记数据库名。如果是登陆系统,记录发起登录请求的应用(source_type=web、client、ios或android),若有跳转或通过单点登录方式登录,记录跳转前的应用名称;否则source_application应和target_application一致。
            source_public_ip(*)	    登陆操作源公网IP	如果请求通过公网,记录来源的公网IP,如:xxx.xxx.xxx.xxx
            source_private_ip(*)	登陆操作源内网IP	如果使用了NAT转换,记录内网IP,如:192.168.xxx.xxx
            source_vpn_ip(*)	    登陆操作源VPN IP	如果使用了vpn,使用vpn分配的IP,如:192.168.xxx.xxx
            source_mac	            源MAC地址	如果是CS架构则记录,BS架构无需记录
            target_application  	登录的目标应用	如果从数据库直接登陆数据库(source_type=Database),则记数据库名。如果登录系统(source_type=web、client、ios或android),则记录登录的目标系统名称,若有跳转或通过单点登录方式登录,记录跳转后的系统名称;否则target_application应和source_application一致。
            target_public_ip(*) 	登陆目标端公网IP	如果通过公网访问目标,记录目标的公网IP。如:xxx.xxx.xxx.xxx
            target_private_ip(*)	登陆目标端内网IP	如果目标进行了NAT转换或使用了负载均衡,记录目标的内网IP,如:192.168.xxx.xxx
            operation_type	        操作类型	login/logout(两种类型必须记录)
            result	                操作结果	success/fail(两种类型必须记录)
            reason	                结果原因	当登录失败,或者退出时记录原因。例如timeout,password error等
            feature	                预留拓展字段	用键值对记录拓展字段,英文分号隔开
            
            1.	获取御城河appKey 和appSecret
            2.	按日志规范准备传入的字段参数(以UTF-8格式编码)
            3.	计算signValue;
            1)	针对上面准备的参数按照key进行排序(升序)然后拼接字符串
            appSecretappId******appKey******company******computer_nameit-230000.xx.com……method******time******appSecret
            注:将上面字符串中的红色字体替换成对应的值;最前面和最后面的appSecret处填写自己的appSecret。
            2)		获取拼接字符串的UTF-8编码字节序列,采用md5方式加密,再把加密后的字节转化为16进制,得到sign字符串。
            4.	对要传输的内容进行编码:
            对参入的每个参数值做URL编码,这里的参数不要求顺序,但是必须对参数值进行url编码;尾部加上&sign=signValue。
            appId=urlencode(appKeyValue)&…&time=urlencode(timeValue)&sign=signValue;
            5.	推送数据
            1)	使用post方法请求服务
            http://gw.ose.aliyun.com/event/ecoLog?加上4步骤产生的字符串;
            POST请求的ContentType设置为:application/x-www-form-urlencoded。
            2)	API返回值
            所有API返回json字符串,表示调用成功与否,格式如下:{"result":"success","errMsg":""}
            */
            string appId = "12111";
            string appSecret = "abcter";
            Dictionary<string, object> dict = new Dictionary<string, object>();
            dict.Add("appId", appId);
            dict.Add("appKey", appId);
            dict.Add("method", "express_login");
            DateTime createOn = loginLogEntity.CreateOn ?? DateTime.Now;
            dict.Add("time", createOn.ToString(BaseSystemInfo.DateTimeFormat));
            dict.Add("operation_time", createOn.ToString(BaseSystemInfo.DateTimeFormat));
            dict.Add("company", "XXX公司");
            dict.Add("station_id", loginLogEntity.CompanyId);
            dict.Add("station", loginLogEntity.CompanyName);
            dict.Add("province", loginLogEntity.Province);
            dict.Add("city", loginLogEntity.City);
            dict.Add("user_id", loginLogEntity.UserId);
            dict.Add("user", loginLogEntity.UserName);
            dict.Add("source_type", loginLogEntity.SourceType);
            dict.Add("source_application", loginLogEntity.SourceApplication);
            dict.Add("target_application", loginLogEntity.TargetApplication);
            dict.Add("source_public_ip", loginLogEntity.IPAddress);
            dict.Add("source_mac", loginLogEntity.MACAddress);
            dict.Add("operation_type", loginLogEntity.OperationType == 1 ? "login" : "logout");
            dict.Add("result", loginLogEntity.Result == 1 ? "success" : "fail");
            dict.Add("reason", loginLogEntity.LoginStatus);
            dict.Add("feature", string.Empty);

            var dicSort = from objDic in dict orderby objDic.Key ascending select objDic;
            StringBuilder sb = new StringBuilder();
            sb.Append(appSecret);
            List<string> list = new List<string>();
            foreach (KeyValuePair<string, object> kvp in dicSort)
            {
                sb.Append(kvp.Key + kvp.Value);
                list.Add(kvp.Key + "=" + System.Web.HttpUtility.UrlEncode(kvp.Value.ToString(), Encoding.UTF8));
            }
            string parameters = string.Join("&", list);
            sb.Append(appSecret);
            string signValue = sb.ToString();
            MD5 md5 = MD5.Create();
            byte[] hashBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(signValue));
            string result = string.Empty;
            for (int i = 0; i < hashBytes.Length; i++)
            {
                //X 表是10进制,X2表示16进制
                result += hashBytes[i].ToString("x2");
            }
            signValue = result;

            // 线程提交
            ThreadPool.QueueUserWorkItem(delegate
            {
                try
                {
                    string url = "http://gw.ose.aliyun.com/event/ecoLog?" + parameters + "&sign=" + signValue;
                    var request = (HttpWebRequest)WebRequest.Create(url);
                    request.Method = "POST";
                    request.ContentType = "application/x-www-form-urlencoded";
                    request.GetResponse();
                    var response = (HttpWebResponse)request.GetResponse();
                    using (var stream = response.GetResponseStream())
                    {
                        if (stream != null)
                        {
                            var responseString = new StreamReader(stream).ReadToEnd();
                            if (!string.IsNullOrWhiteSpace(responseString))
                            {
                                NLogHelper.Trace("向菜鸟推送登录日志,登录人:" + loginLogEntity.UserName + ",推送结果:" + responseString);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    NLogHelper.Warn(ex, "向菜鸟推送登录日志出现异常:"+ex.Message);
                }
            });
        }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值