您好,登錄后才能下訂單哦!
小編給大家分享一下ASP.NET MVC如何實現API接口驗證,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
1、WebApiConfig全局處理
/// <summary> /// WebApiConfig /// 路由基礎配置。 /// /// /// 修改記錄 /// /// 2016.11.01 版本:2.0 宋彪 對日期格式進行統一處理。 /// 2016.10.30 版本:2.0 宋彪 解決json序列化時的循環引用問題。 /// 2016.10.28 版本:2.0 宋彪 回傳響應格式 $format 支持。 /// 2016.09.01 版本:1.0 宋彪 創建。 /// /// 版本: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()); // 統一回傳格式 config.Filters.Add(new ApiResultAttribute()); // 發生異常時處理 config.Filters.Add(new ApiErrorHandleAttribute()); // ToKen身份驗證過濾器 更方便 不需要在這里了 具有改標簽的就會自動檢查 //config.Filters.Add(new ApiAuthFilterAttribute()); // 解決json序列化時的循環引用問題 config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; //對日期格式進行統一處理 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 創建文件。 /// /// <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> /// 未授權時的提示信息 /// </summary> private const string UnauthorizedMessage = "請求未授權,拒絕訪問。"; /// <summary> /// 權限進入 /// </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)) { //未驗證(登錄)的用戶, 而且是非匿名訪問,則轉向登錄頁面 //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、統一回傳格式
/// <summary> /// ApiResultAttribute /// 統一回傳格式 /// /// 修改紀錄 /// /// 2016-10-31 版本:1.0 宋彪 創建文件。 /// /// <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")) { // 若發生例外則不在這邊處理 在異常中處理 ApiErrorHandleAttribute if (actionExecutedContext.Exception != null) return; base.OnActionExecuted(actionExecutedContext); var result = new ApiResultModel(); // 取得由 API 返回的狀態碼 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 宋彪 創建文件。 /// /// <author> /// <name>宋彪</name> /// <date>2016-10-31</date> /// </author> /// </summary> public class ApiErrorHandleAttribute : System.Web.Http.Filters.ExceptionFilterAttribute { /// <summary> /// 異常統一處理 /// </summary> /// <param name="actionExecutedContext"></param> public override void OnException(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext) { base.OnException(actionExecutedContext); // 取得發生例外時的錯誤訊息 var errorMessage = actionExecutedContext.Exception.Message; // 異常記錄 string parameters = APIOperateContext.GetRequestParameters(); NLogHelper.Trace(actionExecutedContext.Exception, BaseSystemInfo.SystemCode + " ApiErrorHandleAttribute OnException 完整的請求地址及參數 : " + parameters); // 2016-11-01 加入異常郵件提醒 NLogHelper.InfoMail(actionExecutedContext.Exception, BaseSystemInfo.SystemCode + " ApiErrorHandleAttribute OnException 完整的請求地址及參數 : " + 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 宋彪 創建文件。 /// /// <author> /// <name>宋彪</name> /// <date>2016-10-31</date> /// </author> /// </summary> public class APIOperateContext { /// <summary> /// 獲取當前 操作上下文 (為每個處理瀏覽器請求的服務器線程 單獨創建 操作上下文) /// </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> /// 獲取全部請求參數,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 字符串中的參數信息 /// 針對get請求的 /// </summary> /// <param name="url">輸入的 URL</param> /// <param name="baseUrl">輸出 URL 的基礎部分</param> /// <param name="nvc">輸出分析后得到的 (參數名,參數值) 的集合</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); // 開始分析參數對 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> /// 系統編號 /// </summary> public string SystemCode { get { return Request["systemCode"] ?? "Base"; } } /// <summary> /// 權限編號 /// </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 業務庫連接 /// <summary> /// 業務庫連接 /// </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、統一回傳格式實體
/// <summary> /// ApiResultModel /// 統一回傳格式實體 /// /// 修改紀錄 /// /// 2016-10-31 版本:1.0 宋彪 創建文件。 /// /// <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 宋彪 創建文件。 /// /// <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參數不可為空"; } 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、接口調用方法
/// <summary> /// 測試留言接口調用 /// </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", "填寫您的留言內容吧"); 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", "官網"); byte[] responseArray = webClient.UploadValues(url, postValues); string response = Encoding.UTF8.GetString(responseArray); return Content(response); }
看完了這篇文章,相信你對“ASP.NET MVC如何實現API接口驗證”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。