我想在專案上目前頁面再查看前增加一個權限登入的驗證如果沒登入就導頁至登入頁面,但又不想在每個Action都增加一個權限驗證的事件,我想在更有彈性且不想寫這麼多Code,那該怎麼做呢? 可以試著使用Filter的特性
說明一下,Filter 在.NET Core裡有五種:
1.Authorization filters: 在生命週期裡會最先執行,用來判斷使用者是否已針對要求取得授權。
2.Resource filters: 會在Authorization filters之後執行,會先執行 OnResourceExecuting事件; 在其他所有Filter執行完後再執行OnResourceExecuted;
3.Action filters:
OnActionExecuting — 在執行 Action 之前執行
OnActionExecuted — 在執行 Action 之後執行
4.Exception filters: 可以用來實作常見的錯誤處理原則; [注意]在Exception filters裡沒有之前和之後的事件。
5.Result filters:
OnResultExecuting — 在執行 Action Result 之前執行
OnResultExecuted — 在執行 Action Result 之後執行
Step1: 首先,先寫一個簡單的登入頁面與登入功能
<div>
<b>Cake my Blog</b><br/>
帳號:<input id="userName" /><br />
密碼:<input id="passWord" /><br />
<input id="loginBtn" type="button" value="Login" />
</div>
@section scripts {
<script>
$(document).ready(function () {
$("#loginBtn").click(function () {
var userName = $("#userName").val();
var passWord = $("#passWord").val();
$.ajax({
type: 'POST',
url: "@Url.Action("Login")",
data: {
userName: userName,
passWord: passWord
}, success: function () {
window.location.href = '@Url.Action("Index", "Home")';
}, error: function (response) {
alert(response.responseText);
}
});
});
});
</script>
}
using CakeMyBlog.Platform.Utilities;
using CakeMyBlog.Service;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace WebApplication.Controllers
{
public class AuthController : Controller
{
private readonly ILogger<AuthController> _logger;
MemberService memberService;
public AuthController(ILogger<AuthController> logger)
{
_logger = logger;
memberService = new MemberService();
}
/// <summary>
/// 登入頁面
/// </summary>
/// <returns></returns>
public IActionResult Index()
{
return View();
}
/// <summary>
/// 登入事件
/// </summary>
/// <param name="userName">帳號</param>
/// <param name="passWord">密碼</param>
/// <returns></returns>
[HttpPost]
public IActionResult Login(string userName, string passWord)
{
var getMemberResult = memberService.GetUserByUserNamePassWord(userName, passWord);
if (getMemberResult == null)
{
return BadRequest("查無會員。");
}
HttpContext.Session.SetString(MySession.SessionUserName, getMemberResult.Name);
return Ok();
}
}
}
登入成功後將登入者名稱寫至Session
Step2: 在執行 Action 之前執行運作權限驗證並且無身分時就導頁至登入頁面,這邊需要寫一個BaseController.cs 做Filter處理並且增加一個override 的OnActionExecuting 事件( Action 之前執行)
using CakeMyBlog.Platform.Utilities;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace WebApplication.Controllers.Base
{
public class BaseController : Controller
{
/// <summary>
/// 執行Action之前運作
/// </summary>
/// <param name="filterContext"></param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var userName = filterContext.HttpContext.Session.GetString(MySession.SessionUserName);
if (userName == null)
{
filterContext.HttpContext.Response.Redirect("./Auth/Index");
}
}
}
}
Step3: 在需要登入後才能使用的Controller 裡去繼承BaseController
這樣就完成在進入Action前做身分驗證的動作了。
Conclusion: Filter 的作用可以在執行前或後做一些處理或驗證,執行順序略有不同,也可以試著運用各種Filter的特性來做加工,某種程度來說也有點像Middleware,好好的使用Filter 你可以少去很多程式,更集中的管理這些處理或驗證。
.Net Core Project GitHub:Link
下一篇 .Net Core Project 從零開始 —相依性注入 (Dependency Injection)
Source : .Net Core Project 從零開始 — 認識與實作Filter
參考文章