Skip to content

Commit

Permalink
Cross-Site Request Forgery (CSRF)
Browse files Browse the repository at this point in the history
  • Loading branch information
SeriaWei committed Jul 29, 2021
1 parent c3db339 commit 5c871cc
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 15 deletions.
22 changes: 12 additions & 10 deletions src/ZKEACMS.Shop/Controllers/BasketController.cs
Expand Up @@ -16,29 +16,31 @@ namespace ZKEACMS.Shop.Controllers
[CustomLoginCheck]
public class BasketController : Controller
{
private CMSApplicationContext applicationContext;
private readonly IBasketService _basketService;
public BasketController(IBasketService basketService, IApplicationContextAccessor applicationContextAccessor)
public BasketController(IBasketService basketService)
{
_basketService = basketService;
applicationContext = applicationContextAccessor.Current;

}
[HttpPost]
[HttpPost, ValidateAntiForgeryToken]
public IActionResult Index()
{
return View(new BasketData(_basketService.Get()));
}
[HttpPost]
[HttpPost, ValidateAntiForgeryToken]
public IActionResult Add(int productId, int? quantity, string tags)
{
if (quantity.HasValue && quantity.Value < 1) return BadRequest();

var basket = new Basket { ProductId = productId, Quantity = quantity ?? 1, Description = tags };
_basketService.Add(basket);
return Json(new AjaxResult { Status = AjaxStatus.Normal, Data = new BasketData(_basketService.Get()) });
}
[HttpPost]
[HttpPost, ValidateAntiForgeryToken]
public IActionResult Update(int basketId, int quantity)
{
if (quantity < 1) return BadRequest();

var basket = _basketService.Get(basketId);
if (basket != null)
{
Expand All @@ -47,18 +49,18 @@ public IActionResult Update(int basketId, int quantity)
}
return Json(new AjaxResult { Status = AjaxStatus.Normal, Data = new BasketData(_basketService.Get()) });
}
[HttpPost]
[HttpPost, ValidateAntiForgeryToken]
public IActionResult Remove(int basketId)
{
_basketService.Remove(basketId);
return Json(new AjaxResult { Status = AjaxStatus.Normal, Data = new BasketData(_basketService.Get()) });
}
[HttpPost]
[HttpPost, ValidateAntiForgeryToken]
public IActionResult GetBaskets()
{
return Json(new AjaxResult { Status = AjaxStatus.Normal, Data = new BasketData(_basketService.Get()) });
}
[HttpPost]
[HttpPost, ValidateAntiForgeryToken]
public IActionResult CheckOut()
{
var basket = _basketService.Get();
Expand All @@ -68,7 +70,7 @@ public IActionResult CheckOut()
}
return View("Index", new BasketData(basket));
}
[HttpPost]
[HttpPost, ValidateAntiForgeryToken]
public IActionResult ConfirmOrder(Order order)
{
order = _basketService.CheckOut(order);
Expand Down
10 changes: 6 additions & 4 deletions src/ZKEACMS.Shop/Scripts/ZKEACMS.Basket.js
Expand Up @@ -5,6 +5,7 @@
var ZKEACMS = ZKEACMS || {};
ZKEACMS.Basket = {
Add: function (product, callBack) {
Object.assign(product, ZKEACMS.AntiToken);
$.post("/Basket/Add", product, function (data) {
if (data.location) {
window.location = data.location;
Expand All @@ -16,6 +17,7 @@ ZKEACMS.Basket = {
});
},
Update: function (basket, callBack) {
Object.assign(basket, ZKEACMS.AntiToken);
$.post("/Basket/Update", basket, function (data) {
if (data.location) {
window.location = data.location;
Expand All @@ -27,7 +29,7 @@ ZKEACMS.Basket = {
});
},
Remove: function (basketId, callBack) {
$.post("/Basket/Remove", { basketId: basketId }, function (data) {
$.post("/Basket/Remove", Object.assign({ basketId: basketId }, ZKEACMS.AntiToken), function (data) {
if (data.location) {
window.location = data.location;
} else {
Expand All @@ -38,14 +40,14 @@ ZKEACMS.Basket = {
});
},
Get: function (callBack) {
$.post("/Basket/GetBaskets", function (data) {
$.post("/Basket/GetBaskets", Object.assign({}, ZKEACMS.AntiToken), function (data) {
if (callBack) {
callBack.call(data);
}
});
},
ShowBasket: function () {
$.post("/Basket/Index", function (data) {
$.post("/Basket/Index", Object.assign({}, ZKEACMS.AntiToken), function (data) {
if (data.location) {
window.location = data.location;
} else {
Expand Down Expand Up @@ -123,7 +125,7 @@ $(function () {
});
});
$(document).on("click", ".basket .ckeck-out", function () {
$.post("/Basket/CheckOut", function (data) {
$.post("/Basket/CheckOut", Object.assign({}, ZKEACMS.AntiToken), function (data) {
if (data.location) {
window.location = data.location;
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/ZKEACMS.Shop/Scripts/ZKEACMS.Basket.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/ZKEACMS.WebHost/DefaultResourceManager.cs
Expand Up @@ -103,6 +103,10 @@ protected override void InitScript(Func<string, ResourceHelper> script)
script("list-editor")
.Include($"{LibraryPath}/jquery-ui/jquery-ui-sortable.js", $"{LibraryPath}/jquery-ui/jquery-ui-sortable.min.js")
.Include($"{ScriptPath}/list-editor.js", $"{ScriptPath}/list-editor.min.js");

script("Antiforgery")
.Include("~/js/antiforgery/tokenset.js")
.RequiredAtFoot();
}

protected override void InitStyle(Func<string, ResourceHelper> style)
Expand Down
25 changes: 25 additions & 0 deletions src/ZKEACMS/Controllers/AntiforgeryController.cs
@@ -0,0 +1,25 @@
/* http://www.zkea.net/
* Copyright (c) ZKEASOFT. All rights reserved.
* http://www.zkea.net/licenses */

using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Mvc;

namespace ZKEACMS.Controllers
{
public class AntiforgeryController : Controller
{
private readonly IAntiforgery _antiforgery;

public AntiforgeryController(IAntiforgery antiforgery)
{
_antiforgery = antiforgery;
}
public IActionResult GetTokenSet()
{
var tokenSet = _antiforgery.GetAndStoreTokens(HttpContext);
string content = $"/*! http://www.zkea.net/ Copyright (c) ZKEASOFT. All rights reserved. http://www.zkea.net/licenses */ var ZKEACMS = ZKEACMS || {{}}; ZKEACMS.AntiToken = {{ '{tokenSet.FormFieldName}': '{tokenSet.RequestToken}' }};";
return Content(content, "application/javascript");
}
}
}
7 changes: 7 additions & 0 deletions src/ZKEACMS/Route/RouteDescriptors.cs
Expand Up @@ -37,6 +37,13 @@ public static class RouteDescriptors
Priority = 11
},
new RouteDescriptor
{
RouteName = "Antiforgery",
Template = "js/antiforgery/tokenset.js",
Defaults = new { controller = "Antiforgery",action="GetTokenSet" },
Priority = 11
},
new RouteDescriptor
{
RouteName = "error",
Template = "error/{action}/{code?}",
Expand Down

0 comments on commit 5c871cc

Please sign in to comment.