Last active
June 6, 2022 10:28
-
-
Save relyky/ba1f426e5b85381445ff0c1d45aadfc7 to your computer and use it in GitHub Desktop.
Angular/React, AntiForgeryToken, axios, Json, post header
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// | |
| /// ref → http://kevintsengtw.blogspot.com/2013/09/aspnet-mvc-csrf-ajax-antiforgerytoken.html | |
| /// | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Web; | |
| using System.Web.Helpers; | |
| using System.Web.Mvc; | |
| namespace YourProject.Filters | |
| { | |
| [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] | |
| public class AjaxValidateAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter | |
| { | |
| public void OnAuthorization(AuthorizationContext filterContext) | |
| { | |
| try | |
| { | |
| if (filterContext.HttpContext.Request.IsAjaxRequest()) | |
| { | |
| ValidateRequestHeader(filterContext.HttpContext.Request); | |
| } | |
| else | |
| { | |
| filterContext.HttpContext.Response.StatusCode = 404; | |
| filterContext.Result = new HttpNotFoundResult(); | |
| } | |
| } | |
| catch (HttpAntiForgeryException ex) | |
| { | |
| throw new HttpAntiForgeryException("Then anti-forgery token not found", ex); | |
| } | |
| } | |
| private void ValidateRequestHeader(HttpRequestBase request) | |
| { | |
| string antiForgeryToken = request.Headers["RequestVerificationToken"]; | |
| VerifyAntiForgeryToken(antiForgeryToken); | |
| } | |
| private void VerifyAntiForgeryToken(string antiForgeryToken) | |
| { | |
| string cookieToken = String.Empty; | |
| string formToken = String.Empty; | |
| if (!String.IsNullOrEmpty(antiForgeryToken)) | |
| { | |
| string[] tokens = antiForgeryToken.Split(':'); | |
| if (tokens.Length == 2) | |
| { | |
| cookieToken = tokens[0].Trim(); | |
| formToken = tokens[1].Trim(); | |
| } | |
| } | |
| AntiForgery.Validate(cookieToken, formToken); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// | |
| /// 前端呼叫關鍵原碼 of AjaxValidateAntiForgeryTokenAttribute | |
| /// | |
| import axios from 'axios' | |
| //axios.defaults.headers.common['Authorization'] = 'Bearer ' + AuthToken; | |
| axios.defaults.headers.common['RequestVerificationToken'] = @ViewFunctions.GetAntiForgeryToken(); | |
| axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; // mark as an ajax request | |
| axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; | |
| // 送出交易 | |
| axios.post(url, args).then((resp) => { | |
| const result = resp.data | |
| swal.fire('送件成功。') | |
| }).catch((xhr) => { | |
| swal.fire('送件失敗!') | |
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// ref → http://kevintsengtw.blogspot.tw/2013/09/aspnet-mvc-csrf-ajax-antiforgerytoken.html | |
| /// http://stackoverflow.com/questions/36941463/why-is-antiforgerytoken-validation-failing-when-using-angularjs-in-asp-net-mvc-a | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Net; | |
| using System.Web; | |
| using System.Web.Helpers; | |
| using System.Web.Mvc; | |
| using System.Diagnostics; | |
| namespace Mvc_Lab03.Filters | |
| { | |
| /*********************************************** | |
| * AuthorizeAttribute filter for JsonResult methods | |
| * | |
| * Validates AntiForgeryToken from header of AJAX request. | |
| * AntiForgeryToken must be placed into that header. | |
| ************************************************/ | |
| /* | |
| View | |
| @Html.AntiForgeryToken() | |
| <script> | |
| var headers = {}; | |
| headers["__RequestVerificationToken"] = $('[name=__RequestVerificationToken]').val(); | |
| $.ajax({ | |
| type: "POST", //Type must be POST | |
| url: url, | |
| dataType: "json", | |
| headers: headers, | |
| /// e.g. ng-service to call WEBAPI | |
| app.service('apiSvc', function ($http, $log) { | |
| this.addData = function (data) { | |
| $log.info('on: addData...'); | |
| return $http.post('/NgProduct/AddData', data, { | |
| headers: { __RequestVerificationToken: $('input[name=__RequestVerificationToken]').val() } | |
| }); | |
| }; | |
| }); | |
| Controller | |
| [ValidateJsonAntiForgeryToken] | |
| public JsonResult Method() { } | |
| */ | |
| [AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] | |
| public sealed class ValidateJsonAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter | |
| { | |
| public void OnAuthorization(AuthorizationContext filterContext) | |
| { | |
| Debug.WriteLine("ON : OnAuthorization()..."); | |
| var request = filterContext.HttpContext.Request; | |
| if (request.HttpMethod == WebRequestMethods.Http.Post && request.Headers["__RequestVerificationToken"] != null) | |
| { | |
| AntiForgery.Validate(CookieToken(request), request.Headers["__RequestVerificationToken"]); | |
| } | |
| else | |
| { | |
| this.HandleUnauthorizedRequest(filterContext); | |
| } | |
| } | |
| private void HandleUnauthorizedRequest(AuthorizationContext filterContext) | |
| { | |
| Debug.WriteLine("ON : HandleUnauthorizedRequest()..."); | |
| filterContext.Result = new JsonResult() | |
| { | |
| // denied-result | |
| JsonRequestBehavior = JsonRequestBehavior.AllowGet, | |
| Data = new { StatusCode = HttpStatusCode.InternalServerError, Error = "Access Denied" } | |
| }; | |
| throw new HttpAntiForgeryException("ValidateJsonAntiForgeryTokenAttribute FAIL!"); | |
| } | |
| private string CookieToken(HttpRequestBase request) | |
| { | |
| var cookie = request.Cookies[AntiForgeryConfig.CookieName]; | |
| return cookie != null ? cookie.Value : null; | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @functions { | |
| public static string GetAntiForgeryToken() | |
| { | |
| string cookieToken, formToken; | |
| AntiForgery.GetTokens(null, out cookieToken, out formToken); | |
| return string.Concat(cookieToken, ":", formToken); | |
| } | |
| /// <summary> | |
| /// C# object → json → JavaScript object | |
| /// </summary> | |
| /// <example>identityList: @Html.Raw(ViewFunctions.ObjectAsJson(TempData["ImmCpIdentityList"]))</example> | |
| /// <see cref="https://stackoverflow.com/questions/20667730/json-from-newtonsoft-to-javascript"/> | |
| public static string ObjectAsJson(object value) | |
| { | |
| if (value == null) | |
| return "undefined"; | |
| string json = Newtonsoft.Json.JsonConvert.SerializeObject(value, Newtonsoft.Json.Formatting.None); | |
| return json; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment