溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ASP.NET MVC如何實現(xiàn)API接口驗證

發(fā)布時間:2021-07-21 09:24:05 來源:億速云 閱讀:119 作者:小新 欄目:開發(fā)技術(shù)

小編給大家分享一下ASP.NET MVC如何實現(xiàn)API接口驗證,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

1、WebApiConfig全局處理

/// <summary>
  /// WebApiConfig 
  /// 路由基礎配置。
  /// 
  /// 
  /// 修改記錄
  /// 
  ///    2016.11.01 版本:2.0 宋彪 對日期格式進行統(tǒng)一處理。
  ///    2016.10.30 版本:2.0 宋彪 解決json序列化時的循環(huán)引用問題。
  ///    2016.10.28 版本:2.0 宋彪 回傳響應格式 $format 支持。
  ///    2016.09.01 版本:1.0 宋彪  創(chuàng)建。
  /// 
  /// 版本:1.0
  /// 
  /// <author>
  ///    <name>宋彪</name>
  ///    <date>2016.09.01</date>
  /// </author> 
  /// </summary>
  public static class WebApiConfig
  {
    /// <summary>
    /// 注冊全局配置服務
    /// </summary>
    /// <param name="config"></param>
    public static void Register(HttpConfiguration config)
    {
      // Web API configuration and services

      //強制https訪問
      //config.Filters.Add(new ForceHttpsAttribute());
      // 統(tǒng)一回傳格式
      config.Filters.Add(new ApiResultAttribute());
      // 發(fā)生異常時處理
      config.Filters.Add(new ApiErrorHandleAttribute());
      // ToKen身份驗證過濾器 更方便 不需要在這里了 具有改標簽的就會自動檢查
      //config.Filters.Add(new ApiAuthFilterAttribute());
      // 解決json序列化時的循環(huán)引用問題
      config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
      //對日期格式進行統(tǒng)一處理
      config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(
      new IsoDateTimeConverter()
      {
        DateTimeFormat = "yyyy-MM-dd hh:mm:ss"
      }
      );

      // Web API routes 路由
      config.MapHttpAttributeRoutes();

      config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: new { id = RouteParameter.Optional }
      );

      // 干掉XML序列化器
      //config.Formatters.Remove(config.Formatters.XmlFormatter);
      //在請求的Url加上 ?$format=xml,便可以指定響應格式
      config.Formatters.XmlFormatter.AddQueryStringMapping("$format", "xml", "application/xml");
      config.Formatters.JsonFormatter.AddQueryStringMapping("$format", "json", "application/json");
    }
  }

2、身份驗證過濾器

  using DotNet.Business;
  using DotNet.Utilities;
  using DotNet.Tracking.API.Common;

  /// <summary>
  /// ApiAuthFilterAttribute
  /// 身份驗證過濾器,具有ApiAuthFilterAttribute標簽屬性的方法會自動檢查
  /// 
  /// 
  /// 修改紀錄
  /// 
  /// 2016-10-11 版本:1.0 SongBiao 創(chuàng)建文件。  
  /// 
  /// <author>
  ///   <name>SongBiao</name>
  ///   <date>2016-10-11</date>
  /// </author>
  /// </summary>
  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
  public class ApiAuthFilterAttribute : AuthorizationFilterAttribute
  {
    /// <summary>
    /// 未授權(quán)時的提示信息
    /// </summary>
    private const string UnauthorizedMessage = "請求未授權(quán),拒絕訪問。";

    /// <summary>
    /// 權(quán)限進入
    /// </summary>
    /// <param name="actionContext"></param>
    public override void OnAuthorization(HttpActionContext actionContext)
    {
      base.OnAuthorization(actionContext);
      // 允許匿名訪問
      if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Count > 0) 
      {
        return;
      }

      string systemCode = APIOperateContext.Current.SystemCode;
      string permissionCode = APIOperateContext.Current.PermissionCode;
      string appKey = APIOperateContext.Current.AppKey;
      string appSecret = APIOperateContext.Current.AppSecret;      
      if (string.IsNullOrWhiteSpace(appKey) || string.IsNullOrWhiteSpace(appSecret))
      {
        //未驗證(登錄)的用戶, 而且是非匿名訪問,則轉(zhuǎn)向登錄頁面 
        //actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
        //actionContext.Response.Content = new StringContent("<p>Unauthorized</p>", Encoding.UTF8, "text/html");
        var response = actionContext.Response= actionContext.Response?? new HttpResponseMessage();
        response.StatusCode = HttpStatusCode.Unauthorized;
        BaseResult result = new BaseResult
        {
          Status = false,
          StatusMessage = UnauthorizedMessage
        };
        response.Content = new StringContent(result.ToJson(), Encoding.UTF8, "application/json");
      }
      else
      {
        // 檢查 AppKey 和 AppSecret
        BaseResult result = BaseServicesLicenseManager.CheckService(appKey, appSecret, false, 0, 0, systemCode, permissionCode);
        if (!result.Status)
        {
          var response = actionContext.Response = actionContext.Response?? new HttpResponseMessage();
          response.Content = new StringContent(result.ToJson(), Encoding.UTF8, "application/json");
        }
      }
           
    }
  }

3、統(tǒng)一回傳格式

  /// <summary>
  /// ApiResultAttribute
  /// 統(tǒng)一回傳格式
  /// 
  /// 修改紀錄
  /// 
  /// 2016-10-31 版本:1.0 宋彪 創(chuàng)建文件。
  /// 
  /// <author>
  ///   <name>宋彪</name>
  ///   <date>2016-10-31</date>
  /// </author>
  /// </summary>
  public class ApiResultAttribute : ActionFilterAttribute
  {
    /// <summary>
    /// 重寫回傳的處理
    /// </summary>
    /// <param name="actionExecutedContext"></param>
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
      // 快件跟蹤接口傳的是format,不用走這里
      if (actionExecutedContext.Request.Properties.ContainsKey("format"))
      {
        // 若發(fā)生例外則不在這邊處理 在異常中處理 ApiErrorHandleAttribute
        if (actionExecutedContext.Exception != null)
          return;
        base.OnActionExecuted(actionExecutedContext);
        var result = new ApiResultModel();
        // 取得由 API 返回的狀態(tài)碼
        result.Status = actionExecutedContext.ActionContext.Response.StatusCode;
        // 取得由 API 返回的資料
        result.Data = actionExecutedContext.ActionContext.Response.Content.ReadAsAsync<object>().Result;
        // 重新封裝回傳格式
        actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(result.Status, result);
      }
    }
  }

4、全局異常處理

  using DotNet.Utilities;
  using DotNet.Tracking.API.Common;
  using DotNet.Tracking.API.Controllers;
  using DotNet.Tracking.API.Models;

  /// <summary>
  /// ApiErrorHandleAttribute
  /// 全局異常處理
  /// 
  /// 修改紀錄
  /// 
  /// 2016-10-31 版本:1.0 宋彪 創(chuàng)建文件。
  /// 
  /// <author>
  ///   <name>宋彪</name>
  ///   <date>2016-10-31</date>
  /// </author>
  /// </summary>

  public class ApiErrorHandleAttribute : System.Web.Http.Filters.ExceptionFilterAttribute
  {
    /// <summary>
    /// 異常統(tǒng)一處理
    /// </summary>
    /// <param name="actionExecutedContext"></param>
    public override void OnException(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
    {
      base.OnException(actionExecutedContext);
      // 取得發(fā)生例外時的錯誤訊息
      var errorMessage = actionExecutedContext.Exception.Message;

      // 異常記錄
      string parameters = APIOperateContext.GetRequestParameters();
      NLogHelper.Trace(actionExecutedContext.Exception, BaseSystemInfo.SystemCode + " ApiErrorHandleAttribute OnException 完整的請求地址及參數(shù) : " + parameters);
      // 2016-11-01 加入異常郵件提醒
      NLogHelper.InfoMail(actionExecutedContext.Exception, BaseSystemInfo.SystemCode + " ApiErrorHandleAttribute OnException 完整的請求地址及參數(shù) : " + parameters);

      var result = new ApiResultModel()
      {
        Status = HttpStatusCode.BadRequest,
        ErrorMessage = errorMessage
      };
      // 重新打包回傳的訊息
      actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(result.Status, result);
    }
  }

5、接口操作的上下文

  using DotNet.Business;
  using DotNet.Model;
  using DotNet.Utilities;

  /// <summary>
  /// APIOperateContext
  /// 接口操作的上下文
  /// 跟上下文有關的一些通用的東西放在這里處理
  /// 
  /// 修改紀錄
  /// 
  /// 2016-10-31 版本:1.0 宋彪 創(chuàng)建文件。
  /// 
  /// <author>
  ///   <name>宋彪</name>
  ///   <date>2016-10-31</date>
  /// </author>
  /// </summary>
  public class APIOperateContext
  {
    /// <summary>
    /// 獲取當前 操作上下文 (為每個處理瀏覽器請求的服務器線程 單獨創(chuàng)建 操作上下文)
    /// </summary>
    public static APIOperateContext Current
    {
      get
      {
        APIOperateContext oContext = CallContext.GetData(typeof(APIOperateContext).Name) as APIOperateContext;
        if (oContext == null)
        {
          oContext = new APIOperateContext();
          CallContext.SetData(typeof(APIOperateContext).Name, oContext);
        }
        return oContext;
      }
    }

    #region Http上下文 及 相關屬性
    /// <summary>
    /// Http上下文
    /// </summary>
    public HttpContext ContextHttp
    {
      get
      {
        return HttpContext.Current;
      }
    }

    /// <summary>
    /// 輸出對象
    /// </summary>
    public HttpResponse Response
    {
      get
      {
        return ContextHttp.Response;
      }
    }

    /// <summary>
    /// 請求對象
    /// </summary>
    public HttpRequest Request
    {
      get
      {
        return ContextHttp.Request;
      }
    }

    /// <summary>
    /// Session對象
    /// </summary>
    System.Web.SessionState.HttpSessionState Session
    {
      get
      {
        return ContextHttp.Session;
      }
    }
    #endregion

    /// <summary>
    /// 獲取全部請求參數(shù),get和post的 簡化版
    /// </summary>
    public static string GetRequestParameters()
    {
      string query = HttpContext.Current.Request.Url.Query;
      NameValueCollection nvc;
      string baseUrl;
      ParseUrl(query, out baseUrl, out nvc);
      List<string> list = new List<string>() { };
      foreach (var key in nvc.AllKeys)
      {
        list.Add(key + "=" + nvc[key]);
      }

      var form = HttpContext.Current.Request.Form;
      foreach (var key in form.AllKeys)
      {
        list.Add(key + "=" + form[key]);
      }
      string result = HttpContext.Current.Request.Url.AbsoluteUri + "?" + string.Join("&", list);

      return result;
    }

    /// <summary>
    /// 分析 url 字符串中的參數(shù)信息
    /// 針對get請求的
    /// </summary>
    /// <param name="url">輸入的 URL</param>
    /// <param name="baseUrl">輸出 URL 的基礎部分</param>
    /// <param name="nvc">輸出分析后得到的 (參數(shù)名,參數(shù)值) 的集合</param>
    public static void ParseUrl(string url, out string baseUrl, out NameValueCollection nvc)
    {
      if (url == null)
      {
        throw new ArgumentNullException("url");
      }
      nvc = new NameValueCollection();
      baseUrl = "";
      if (url == "")
      {
        return;
      }
      int questionMarkIndex = url.IndexOf('?');
      if (questionMarkIndex == -1)
      {
        baseUrl = url;
        return;
      }
      baseUrl = url.Substring(0, questionMarkIndex);
      if (questionMarkIndex == url.Length - 1)
      {
        return;
      }
      string ps = url.Substring(questionMarkIndex + 1);
      // 開始分析參數(shù)對 
      Regex re = new Regex(@"(^|&)?(\w+)=([^&]+)(&|$)?", RegexOptions.Compiled);
      MatchCollection mc = re.Matches(ps);
      foreach (Match m in mc)
      {
        nvc.Add(m.Result("$2").ToLower(), m.Result("$3"));
      }
    }

    /// <summary>
    /// 系統(tǒng)編號
    /// </summary>
    public string SystemCode
    {
      get
      {
        return Request["systemCode"] ?? "Base";
      }
    }

    /// <summary>
    /// 權(quán)限編號
    /// </summary>
    public string PermissionCode
    {
      get
      {
        return Request["permissionCode"];
      }
    }

    /// <summary>
    /// 訪問接口的應用傳來AppKey
    /// </summary>
    public string AppKey
    {
      get
      {
        return Request["appKey"];
      }
    }

    /// <summary>
    /// 訪問接口的應用傳來AppSecret
    /// </summary>
    public string AppSecret
    {
      get
      {
        return Request["appSecret"];
      }
    }

    private BaseUserInfo _userInfo = null;
    /// <summary>
    /// 獲取當前用戶
    /// 通過接口AppKey和AppSecret獲取的用戶
    /// </summary>
    /// <returns></returns>
    public BaseUserInfo UserInfo
    {
      get
      {
        BaseUserInfo userInfo = null;
        BaseUserEntity userEntity = BaseUserManager.GetObjectByCodeByCache(AppKey);
        if (userEntity != null)
        {
          if (BaseServicesLicenseManager.CheckServiceByCache(userEntity.Id, AppSecret))
          {
            userInfo = new BaseUserInfo();
            userInfo.Id = userEntity.Id;
            userInfo.RealName = userEntity.RealName;
            userInfo.UserName = userEntity.UserName;
            userInfo.IPAddress = Utilities.GetIPAddress(true);
          }
        }
        return userInfo;
      }
    }

    #region 業(yè)務庫連接
    /// <summary>
    /// 業(yè)務庫連接
    /// </summary>
    public static IDbHelper BusinessDbHelper
    {
      get
      {
        return DbHelperFactory.GetHelper(BaseSystemInfo.BusinessDbType, BaseSystemInfo.BusinessDbConnection);
      }
    }
    #endregion

    #region 用戶中心庫連接
    /// <summary>
    /// 用戶中心庫連接
    /// </summary>
    public static IDbHelper UserCenterDbHelper
    {
      get
      {
        return DbHelperFactory.GetHelper(BaseSystemInfo.UserCenterDbType, BaseSystemInfo.UserCenterDbConnection);
      }
    }
    #endregion


  }

7、統(tǒng)一回傳格式實體

  /// <summary>
  /// ApiResultModel
  /// 統(tǒng)一回傳格式實體
  /// 
  /// 修改紀錄
  /// 
  /// 2016-10-31 版本:1.0 宋彪 創(chuàng)建文件。
  /// 
  /// <author>
  ///   <name>宋彪</name>
  ///   <date>2016-10-31</date>
  /// </author>
  /// </summary>
  public class ApiResultModel
  {
    public HttpStatusCode Status { get; set; }

    //public JsonResult<T> Data { get; set; }
    public object Data { get; set; }
    public string ErrorMessage { get; set; }
  }

8、留言相關接口

  /// <summary>
  /// MessageBookController
  /// 留言相關接口
  /// 
  /// 修改紀錄
  /// 
  /// 2016-10-31 版本:1.0 宋彪 創(chuàng)建文件。
  /// 
  /// <author>
  ///   <name>宋彪</name>
  ///   <date>2016-10-31</date>
  /// </author>
  /// </summary>
  [ApiAuthFilter]
  public class CustomerMessageController : ApiController
  {
    /// <summary>
    /// 保存單號留言信息
    /// </summary>
    /// <param name="messageBook"></param>
    /// <returns></returns>
    [HttpPost]
    //[AllowAnonymous] 不需要驗證的就加這個標簽
    public IHttpActionResult Add([FromBody]MsgbookCusEntity messageBook)
    {
      BaseResult baseResult = new BaseResult();
      if (string.IsNullOrWhiteSpace(messageBook.SystemFrom))
      {
        baseResult.Status = false;
        baseResult.StatusMessage = "SystemFrom參數(shù)不可為空";
      }
      else
      {
        try
        {
          MsgbookCusManager manager = new MsgbookCusManager(APIOperateContext.BusinessDbHelper, APIOperateContext.Current.UserInfo);
          MsgbookCusEntity model = new MsgbookCusEntity();
          model.Id = Guid.NewGuid().ToString("N");
          model.Message = messageBook.Message;
          model.SendEmail = messageBook.SendEmail;
          model.SendTelephone = messageBook.SendTelephone;
          model.Message = messageBook.Message;
          model.BillCode = messageBook.BillCode;
          model.SystemFrom = messageBook.SystemFrom;
          model.DeletionStateCode = 0;
          manager.Add(model, false, false);

          baseResult.Status = true;
          baseResult.StatusMessage = "添加成功。";
        }
        catch (Exception ex)
        {
          NLogHelper.Warn(ex, "CustomerMessageController AddBillMessage 異常");
          baseResult.Status = false;
          baseResult.StatusMessage = "異常:" + ex.Message;
        }
      }

      return Ok(baseResult);
    }

    /// <summary>
    /// 獲取某個單號的留言
    /// </summary>
    /// <param name="billCode"></param>
    /// <returns></returns>
    [HttpGet]
    public IHttpActionResult GetList(string billCode)
    {
      JsonResult<List<MsgbookCusEntity>> jsonResult = new JsonResult<List<MsgbookCusEntity>>();
      try
      {
        MsgbookCusManager manager = new MsgbookCusManager(APIOperateContext.BusinessDbHelper, APIOperateContext.Current.UserInfo);
        List<MsgbookCusEntity> list = new List<MsgbookCusEntity>();
        list = manager.GetList<MsgbookCusEntity>(new KeyValuePair<string, object>(MsgbookCusEntity.FieldBillCode, billCode)
        , new KeyValuePair<string, object>(MsgbookCusEntity.FieldDeletionStateCode, 0));

        jsonResult.Status = true;
        jsonResult.RecordCount = list.Count;
        jsonResult.Data = list;
        jsonResult.StatusMessage = "獲取成功";
      }
      catch (Exception ex)
      {
        NLogHelper.Warn(ex, "CustomerMessageController AddBillMessage 異常");
        jsonResult.Status = false;
        jsonResult.StatusMessage = "異常:" + ex.Message;
      }

      return Ok(jsonResult);
    }
  }

9、接口調(diào)用方法

/// <summary>
    /// 測試留言接口調(diào)用
    /// </summary>
    /// <returns></returns>
    public ActionResult AddCustomerMessage()
    {
      string url = "http://192.168.1.88:808/api/CustomerMessage/Add?";
      WebClient webClient = new WebClient();
      NameValueCollection postValues = new NameValueCollection();

      postValues.Add("Message", "填寫您的留言內(nèi)容吧");
      postValues.Add("SendEmail", "youemail@qq.com");
      postValues.Add("SendTelephone", "021-60375335");
      postValues.Add("Code", "661137858");
      postValues.Add("AppKey", "wssavbcn");
      postValues.Add("AppSecret", "350e66b1e6564b0a817163erwwwwe8");
      postValues.Add("SystemFrom", "官網(wǎng)");

      byte[] responseArray = webClient.UploadValues(url, postValues);
      string response = Encoding.UTF8.GetString(responseArray);

      return Content(response);
    }

看完了這篇文章,相信你對“ASP.NET MVC如何實現(xiàn)API接口驗證”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI