Skip to content

Instantly share code, notes, and snippets.

@relyky
Last active June 6, 2022 10:28
Show Gist options
  • Select an option

  • Save relyky/ba1f426e5b85381445ff0c1d45aadfc7 to your computer and use it in GitHub Desktop.

Select an option

Save relyky/ba1f426e5b85381445ff0c1d45aadfc7 to your computer and use it in GitHub Desktop.
Angular/React, AntiForgeryToken, axios, Json, post header
///
/// 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);
}
}
}
///
/// 前端呼叫關鍵原碼 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('送件失敗!')
})
/// 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;
}
}
}
@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