美文网首页.Netcore.NETASP.NET Core见识录
Asp.netCore3.0 WebApi从0到1手摸手教你写【

Asp.netCore3.0 WebApi从0到1手摸手教你写【

作者: 我是Mr小赵先生 | 来源:发表于2019-10-24 14:41 被阅读0次

    通过前几个教程的学习,对webapi的编写基本上就可以入门了,可以做项目了,今天我们再给接口加个参数签名认证,之前的接口相当于赤果果的暴露在了网络上,只要知道接口地址、接口调用方式和传参就可以畅所欲为的调用接口了,这给我们写的webapi带来了很大的安全隐患,所以这篇教程是给webapi加上一层保护措施,可能算不上最优解决方案,但起码能起到一定的保护措施。

    保护思路

    1.接口调用采用POST的方式,可以屏蔽一部分小白,增加接口调用的难度。
    2.接口调用参数增加签名字段,一可以防止数据被篡改,二还可以防止其它人非法调用我们的接口。

    接口签名算法

    签名生成的通用步骤如下:

    第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。

    特别注意以下重要规则:

    ◆ 参数名ASCII码从小到大排序(字典序);
    ◆ 如果参数的值为空不参与签名;
    ◆ 参数名区分大小写;
    ◆ 验证调用返回或主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。

    第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。

    ◆ key设置:将key设置在接口配置文件中,当key发生泄露时可第一时间通过修改配置文件来更改key值。

    举例:

    假设传送的参数如下:

    a:  aa
    b:  bb
    c:  cc
    

    第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下:
    stringA="a=aa&b=bb&c=cc";

    第二步:拼接API密钥:
    stringSignTemp=stringA+"&key=afwfsfwexwegw" //注:key为用户在配置文件中自行设置的
    sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A9CF3B7" //注:MD5签名方式

    代码部分

    第一步,在配置文件增加签名的key
    appsettings.json

        
    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
        }
      },
      "AllowedHosts": "*",
      //接口配置参数设置
      "AppSettings": {
        //数据库连接字符串
        "xxxDB": "Server=ROBERT-PC\\SQLEXPRESS;User Id=xiaozhao;Password=xz123789;Database=XXX;",
        //接口是否需要签名
        "IsSign": "false",
        //16位MD5签名key
        "Md5Key": "5ShiCeShiAAAAAAA"
      }
    
    }
    

    第二步,在Common增加SignMgr.cs类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using XXX.Models;
    
    namespace XXX.Common
    {
        /// <summary>
        /// 签名管理
        /// </summary>
        public class SignMgr
        {
            /// <summary>
            /// 验证用户请求参数
            /// </summary>
            /// <param name="p">参数中需要包含sign字段,用来验证签名是否正确</param>
            /// <returns></returns>
            public static bool ParamVerify(Object p)
            {
                //获取是否签名字段
                string isSign = AppSettings.GetAppSeting("IsSign");
                //获取MD5签名字段
                string secretKey = AppSettings.GetAppSeting("Md5Key");
                if (isSign == "false")
                {
                    return true;
                }
                try
                {
                    Type t = p.GetType();
                    var propertys = t.GetProperties();
                    string sign = "";
                    string temp = "";
                    var orderPropertys = propertys.OrderBy(p => p.Name); //ASCII码从小到大排序(字典序)
                    foreach (var item in orderPropertys)
                    {
                        string name = item.Name;
                        object oValue = item.GetValue(p);
                        string value = "";
                        if (oValue != null)//如果参数不为空则拼接参数
                        {
                            value = oValue.ToString();
                            //判断参数是否为sign,sign不参与签名
                            if (name != "sign")
                            {
                                temp += name + "=" + value + "&";
                            }
                            else
                            {
                                sign = value;
                            }
                        }
                    }
    
                    temp +="key=" +secretKey;
                    string md = Md5Encrypt.MD5(temp);
                    if (sign != "" && sign.ToUpper() == md.ToUpper())
                    {
                        //签名验证成功
                        return true;
                    }
                    else
                    {
                        //签名失败
                        return false;
                    }
                }
                catch (Exception ex)
                {
                    //签名异常信息
                    return false;
                }
            }
    
            
        }
    }
    

    第三步,验证

    using System.Linq;
    
    namespace XXX.Bo
    {
        public class UserBo
        {
            public static XXXContext db = new XXXContext();
            /// <summary>
            /// 增加一个用户数据
            /// </summary>
            /// <param name="model"></param>
            public static Models.User.AddUserR AddUser(Models.User.AddUserP model)
            {
                var r = new Models.User.AddUserR();
                if (Common.SignMgr.ParamVerify(model))//验证用户参数签名是否合法
                {
                    Models.XXXEntities.User userSearch = (from u in db.User where u.Phone == model.phone select u).FirstOrDefault();
                    if (userSearch == null)
                    {
                        Models.XXXEntities.User user = new Models.XXXEntities.User();
                        user.Phone = model.phone;
                        user.Password = model.password;
                        user.NickName = model.nickName;
                        user.State = model.state;
                        db.User.Add(user);
                        int i = db.SaveChanges();
                        if (i > 0)
                        {
                            r.code = 1;
                            r.message = "数据插入成功";
                        }
                        else
                        {
                            r.code = 0;
                            r.message = "数据插入成功";
                        }
                    }
                    else
                    {
                        r.code = 0;
                        r.message = "手机号已经存在";
                    }
                }
                else
                {
                    r.code = 0;
                    r.message = "签名失败";
                }
                return r;
            }
        }
    }
    

    项目已经上传github,看自行下载。
    NetCore3.0-WebApi

    求赞

    创作不易,喜欢的请给个免费的赞吧!

    相关文章

      网友评论

        本文标题:Asp.netCore3.0 WebApi从0到1手摸手教你写【

        本文链接:https://www.haomeiwen.com/subject/oforvctx.html