احراز هویت در فرم ها با استفاده از Cookie در MVC
شنبه 27 خرداد 1396در این مقاله به کمک یک مثال عملی نحوه پیاده سازی مکانیزم احرازهویت برای فرم ها با استفاده از FormsAuthenticationTicket (Cookie) در ASP.Net MVC Razor را آموزش می دهیم.
در این مقاله نحوه احراز هویت فرم ها به کمک یک روش سفارشی شده و استفاده از Entity Framework در داخل برنامه هایASP.Net MVC Razor توضیح داده شده است.
پیکربندی Bundle ها و فعال کردن اعتبار سنجی در سمت Client
فرم لاگین برای احراز هویت کاربر در سمت Client به کمک جی کوئری و Model Data Annotations اجرا خواهد شد. برای پیکربندی Bundle ها و فعال کردن Client Side validation، مقاله های موجود در سایت در این رابطه را مطالعه کنید.
نکته: به طور پیش فرض اعتبارسنجی توسط صفت های Data Annotation در سمت سرور انجام می شود. بنابراین اگر بخواهیم این عملیات در سمت Client انجام شود، باید Client Side validation را فعال کنیم.
Database
در داخل دیتابیس یک جدول مربوط به کاربر خواهیم داشت.
نکته: فایل SQL دیتابیس در فایل ضمیمه مقاله موجود است.
ساخت یک Stored Procedure برای اعتبارسنجی اطلاعات کاربر
stored procedure معرفی شده در پایین، برای اعتبارسنجی اطلاعات کاربر مورد استفاده قرار می گیرد. این stored procedure ابتدا بررسی می کند که نام کاربری و رمز عبور درست هستند یا خیر و در صورت مشکل داشتن مقدار -1 برمی گرداند.
اگر نام کاربری و رمز عبور درست بودند ولی کاربر هنوز فعال نشده باشد، پس مقدار -2 برگردانده داده می شود.
اگر نام کاربری و رمز عبور درست باشد و کاربر فعال هم باشد مقدار UserId کاربر به عنوان خروجی، برگردانده می شود.
CREATE PROCEDURE [dbo].[Validate_User] @Username NVARCHAR(20), @Password NVARCHAR(20) AS BEGIN SET NOCOUNT ON; DECLARE @UserId INT, @LastLoginDate DATETIME SELECT @UserId = UserId, @LastLoginDate = LastLoginDate FROM Users WHERE Username = @Username AND [Password] = @Password IF @UserId IS NOT NULL BEGIN IF NOT EXISTS(SELECT UserId FROM UserActivation WHERE UserId = @UserId) BEGIN UPDATE Users SET LastLoginDate = GETDATE() WHERE UserId = @UserId SELECT @UserId [UserId] -- User Valid END ELSE BEGIN SELECT -2 -- User not activated. END END ELSE BEGIN SELECT -1 -- User invalid. END END
افزودن یک Stored Procedure جدید به Entity Framework Data Model
نحوه تنظیمات و پیکربندی Entity Framework را در مقالات قبلی توضیح داده ایم، پس وارد مرحله بعدی می شویم. در این مرحله قصد اضافه کردن یک Stored Procedure به یک Entity Framework Data Model را داریم.
برای این کار، ابتدا User Data Model را باز کنید و روی جدول User Table راست کلیک کنید و از منو باز شده گزینه Update Model from Database را انتخاب کنید.
عملی که در بالا انجام دادیم باعث می شود که پنجره Update Wizard باز شود و در آن پنجره شما باید Stored Procedure جدید را انتخاب کنید و گزینه Finish را انتخاب کنید.
بعد از اینکه Stored Procedure اضافه شد، لازم است که دوباره روی User Table راست کلیک کرده و گزینه Add New را بزنید و سپس از منو نمایش داده شده گزینه Function Import را انتخاب کنید.
کاری که در بالا انجام دادیم باعث می شود پنجره Add Function Import باز شود.
1- Function Import Name: مشخص کردن نام متدی که قرار است Stored Procedure را اجرا کند.
2-Stored Procedure / Function Name: انتخاب Stored Procedure / Function که قصد انتقال آن را داریم.
3-Returns a Collection Of: در این مقاله از Stored Procedure استفاده شده است که خروجی آن یک مقدار عددی است و به این دلیل گزینه Int32 انتخاب شده است.
در آخر که تمامی مراحل بالا را انجام دادید کلید OK را بزنید.
Model
کلاس User.cs از روی جدول کاربران که در دیتابیس ساخته ایم ایجاد شده است.
namespace User_Login_MVC { using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; public partial class User { public int UserId { get; set; } [Required(ErrorMessage = "Required.")] public string Username { get; set; } [Required(ErrorMessage = "Required.")] public string Password { get; set; } [Required(ErrorMessage = "Required.")] [Compare("Password", ErrorMessage = "Passwords do not match.")] public string ConfirmPassword { get; set; } [Required(ErrorMessage = "Required.")] [EmailAddress(ErrorMessage = "Invalid email address.")] public string Email { get; set; } public System.DateTime CreatedDate { get; set; } public Nullable<System.DateTime> LastLoginDate { get; set; } public bool RememberMe { get; set; } } }
Namespaces
شما باید namespace زیر را به پروژه اضافه کنید.
using System.Web.Security;
Controller
کنترلر ما شامل 4 اکشن متد است.
اکشن متد برای لاگین که مسئول مدیریت عملیات های GET است
در داخل این اکشن متد، یک View به عنوان خروجی فرستاده می شود. این اکشن متد دارای صفت [AllowAnonymous] است که به معنای این است که کاربرانی که احراز هویت نشده اند هم قابلیت دسترسی به این متد را دارند.
اکشن متد برای پروفایل که مسئول مدیریت عملیات های GET است
در داخل این اکشن متد، یک View به عنوان خروجی فرستاده می شود. این اکشن متد دارای صفت [Authorize] است که به معنای این است که فقط کاربرانی که احرازهویت شده اند قابلیت دسترسی به این متد را دارند.
اکشن متد برای لاگین که مسئول مدیریت عملیات های POST است
در داخل این اکشن متد، متد ValidateUser فراخوانی می شود که باعث می شود آن Stored Procedure که وظیفه تعیین اعتبار کاربر را داشت، اجرا شود.
وضعیت خروجی از این Stored Procedure دریافت می شود و اگر مقدار آن -1 بود به معنای آن است نام کاربری یا رمزعبور نادرست است و اگر مقدار آن -2 بود یعنی اطلاعات درست است ولی کاربر هنوزی فعال سازی اکانت را انجام نداده است و اگر مقدار دیگری بود به معنای صحت اطلاعات است و این اطلاعات در کوکی ذخیره می شود و کاربر به صفحه Profile فرستاده می شود. برای مقادیر -1 و -2 یک پیغام خطا به کاربر نمایش داده می شود.
اکشن متد برای Logout که مسئول مدیریت عملیات های POST است
در داخل این اکشن متد، متد Signout از FormsAuthentication فراخوانی می شود که با این عمل تمامی اطلاعات مربوط به احراز هویت از کوکی پاک شده و کابر به صفحه Index منتقل می شود.
public class HomeController : Controller { [AllowAnonymous] public ActionResult Index() { return View(); } [Authorize] public ActionResult Profile() { return View(); } [HttpPost] [AllowAnonymous] public ActionResult Index(User user) { UsersEntities usersEntities = new UsersEntities(); int? userId = usersEntities.ValidateUser(user.Username, user.Password).FirstOrDefault(); string message = string.Empty; switch (userId.Value) { case -1: message = "Username and/or password is incorrect."; break; case -2: message = "Account has not been activated."; break; default: FormsAuthentication.SetAuthCookie(user.Username, user.RememberMe); return RedirectToAction("Profile"); } ViewBag.Message = message; return View(user); } [HttpPost] [Authorize] public ActionResult Logout() { FormsAuthentication.SignOut(); return RedirectToAction("Index"); } }
View ها
Index
در داخل این View، در همان خط اول کلاس User Model به عنوان Model برای این View تعیین شده است.
این View دارای یک فرم Html است که به وسیله متد Html.BeginForm ساخته شده است و دارای پارامتر های زیر است.
ActionName – نام اکشن، در این مثال می شود همان Index
ControllerName – نام کنترلر که در این مثال می شود Home
FormMethod – مشخص کننده نوع متد است مثلا GET یا POST که در این مثال می شود POST
در داخل این View از 4 دستور HTML Helper که در پایین آمده اند استفاده شده است.
1- Html.TextBoxFor- یک تکست باکس برای خصوصیت Model می سازد.
2- Html.PasswordFor- یک تکست باکس مخصوص رمز عبور برای خصوصیت Model می سازد.
3- Html.ValidationMessageFor – نمایش پیام اعتبارسنجی برای خصوصیت های Model
4- . Html.CheckBoxFor- یک چک باکس برای خصوصیت Model می سازد.
همچنین یک کلید Submit وجود دارد که با کلیک بر روی آن محتویات فرم به شکل GET فرستاده می شود.
اسکریپت های jQuery و jQuery Validation در آخر به کمک تابع Scripts.Render به صفحه اضافه شده اند.
مقدار Message که در ViewBag است را ابتدا بررسی می کنیم که Null نباشد و اگر Null نبود، مقدار message را به کمک دستور جاوا اسکریپتی Alert نمایش می دهیم.
@model User_Login_MVC.User @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width"/> <title>Index</title> <style type="text/css"> body { font-family: Arial; font-size: 10pt; } table { border: 1px solid #ccc; border-collapse: collapse; } table th { background-color: #F7F7F7; color: #333; font-weight: bold; } table th, table td { padding: 5px; border: 1px solid #ccc; } .error { color: red; } </style> </head> <body> @using (Html.BeginForm("Index", "Home", FormMethod.Post)) { <table border="0" cellpadding="0" cellspacing="0"> <tr> <th colspan="3"> Login </th> </tr> <tr> <td> Username </td> <td> @Html.TextBoxFor(m => m.Username) </td> <td> @Html.ValidationMessageFor(m => m.Username, "", new { @class = "error" }) </td> </tr> <tr> <td> Password </td> <td> @Html.PasswordFor(m => m.Password) </td> <td> @Html.ValidationMessageFor(m => m.Password, "", new { @class = "error" }) </td> </tr> <tr> <td> Remember Me </td> <td> @Html.CheckBoxFor(m => m.RememberMe) </td> <td> </td> </tr> <tr> <td></td> <td> <input type="submit" value="Submit"/> </td> <td></td> </tr> </table> } @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/jqueryval") @if (@ViewBag.Message != null) { <script type="text/javascript"> $(function () { alert("@ViewBag.Message") }); </script> } </body> </html>
Profile
در داخل View مربوط به پروفایل، نام کاربری که لاگین کرده است را نمایش می دهد. همچنین یک لینک برای Logout در این صفحه قرار داده شده است.
وقتی که روی لینک Logout کلیک شود، فرم submit شده و اکشن متد Logout فراخوانی می شود.
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width"/> <title>Profile</title> <title>Index</title> <style type="text/css"> body { font-family: Arial; font-size: 10pt; } </style> </head> <body> <div> Welcome <b>@HttpContext.Current.User.Identity.Name</b> <br/> <br/> @using (Html.BeginForm("Logout", "Home", FormMethod.Post)) { <a href="javascript:;" onclick="document.forms[0].submit();">Logout</a> } </div> </body> </html>
تنظیماتWeb.Config
شما باید قطعه کد زیر را به فایل Web.Config در بخش <system.web> اضافه کنید.
<authentication mode="Forms"> <forms defaultUrl="/Home/Profile" loginUrl="/Home/Index" slidingExpiration="true" timeout="2880"></forms> </authentication>
خروجی
آموزش asp.net mvc
- ASP.net MVC
- 3k بازدید
- 5 تشکر