اندازهی قلم متن
تخمین مدت زمان مطالعهی مطلب:
شش دقیقه
در پست قبلی نحوه سفارشی کردن پروفایل کاربران در ASP.NET Identity را مرور کردیم. اگر بیاد داشته باشید یک فیلد آدرس ایمیل به کلاس کاربر اضافه کردیم. در این پست از این فیلد استفاده میکنیم تا در پروسه ثبت نام ایمیلها را تصدیق کنیم. بدین منظور پس از ثبت نام کاربران یک ایمیل فعالسازی برای آنها ارسال میکنیم که حاوی یک لینک است. کاربران با کلیک کردن روی این لینک پروسه ثبت نام خود را تایید میکنند و میتوانند به سایت وارد شوند. پیش از تایید پروسه ثبت نام، کاربران قادر به ورود نیستند.
در ابتدا باید اطلاعات کلاس کاربر را تغییر دهید تا دو فیلد جدید را در بر گیرد. یک فیلد شناسه تایید (confirmation token) را ذخیره میکند، و دیگری فیلدی منطقی است که مشخص میکند پروسه ثبت نام تایید شده است یا خیر. پس کلاس ApplicationUser حالا باید بدین شکل باشد.
اگر پیش از این کلاس ApplicationUser را تغییر داده اید، باید مهاجرتها را فعال کنید و دیتابیس را بروز رسانی کنید. حالا میتوانیم از این اطلاعات جدید در پروسه ثبت نام استفاده کنیم و برای کاربران ایمیلهای تاییدیه را بفرستیم.
برای تولید شناسههای تایید (tokens) از کلاسی بنام ShortGuid استفاده شده است. این کلاس یک مقدار GUID را encode میکند که در نتیجه آن مقدار خروجی کوتاهتر بوده و برای استفاده در URLها ایمن است. کد این کلاس را از این وبلاگ گرفته ام. پس از ایجاد حساب کاربری باید شناسه تولید شده را به آن اضافه کنیم و مقدار فیلد IsConfirmed را به false تنظیم کنیم. برای تولید ایمیلها من از Postal استفاده میکنم. Postal برای ساختن ایمیلهای دینامیک شما از موتور Razor استفاده میکند. میتوانید ایمیلهای ساده (plain text) یا HTML بسازید، عکس و فایل در آن درج و ضمیمه کنید و امکانات بسیار خوب دیگر. اکشن متد RegisterStepTwo تنها کاربر را به یک View هدایت میکند که پیامی به او نشان داده میشود.
متد ConfirmAccount سعی میکند کاربری را در دیتابیس پیدا کند که شناسه تاییدش با مقدار دریافت شده از URL برابر است. اگر این کاربر پیدا شود، مقدار خاصیت IsConfirmed را به true تغییر میدهیم و همین مقدار را به تابع باز میگردانیم. در غیر اینصورت false بر میگردانیم. اگر کاربر تایید شده است، میتواند به سایت وارد شود. برای اینکه مطمئن شویم کاربران پیش از تایید ایمیل شان نمیتوانند وارد سایت شوند، باید اکشن متد Login را کمی تغییر دهیم.
تنها کاری که میکنیم این است که به دنبال کاربری میگردیم که فیلد IsConfirmed آن true باشد. اگر مقدار این فیلد false باشد کاربر را به سایت وارد نمیکنیم و پیغام خطایی نمایش میدهیم.
توضیحاتی درباره کار با Postal
public class ApplicationUser : IdentityUser { public string Email { get; set; } public string ConfirmationToken { get; set; } public bool IsConfirmed { get; set; } }
private string CreateConfirmationToken() { return ShortGuid.NewGuid(); } private void SendEmailConfirmation(string to, string username, string confirmationToken) { dynamic email = new Email("RegEmail"); email.To = to; email.UserName = username; email.ConfirmationToken = confirmationToken; email.Send(); } // // POST: /Account/Register [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Register(RegisterViewModel model) { if (ModelState.IsValid) { string confirmationToken = CreateConfirmationToken(); var user = new ApplicationUser() { UserName = model.UserName, Email = model.Email, ConfirmationToken = confirmationToken, IsConfirmed = false }; var result = await UserManager.CreateAsync(user, model.Password); if (result.Succeeded) { SendEmailConfirmation(model.Email, model.UserName, confirmationToken); return RedirectToAction("RegisterStepTwo", "Account"); } else { AddErrors(result); } } // If we got this far, something failed, redisplay form return View(model); }
بعد از اینکه کاربر ایمیل را دریافت کرد و روی لینک تایید کلیک کرد به اکشن متد RegisterConfirmation باز میگردیم.
private bool ConfirmAccount(string confirmationToken) { ApplicationDbContext context = new ApplicationDbContext(); ApplicationUser user = context.Users.SingleOrDefault(u => u.ConfirmationToken == confirmationToken); if (user != null) { user.IsConfirmed = true; DbSet<ApplicationUser> dbSet = context.Set<ApplicationUser>(); dbSet.Attach(user); context.Entry(user).State = EntityState.Modified; context.SaveChanges(); return true; } return false; } [AllowAnonymous] public ActionResult RegisterConfirmation(string Id) { if (ConfirmAccount(Id)) { return RedirectToAction("ConfirmationSuccess"); } return RedirectToAction("ConfirmationFailure"); }
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (ModelState.IsValid) { var user = await UserManager.FindAsync(model.UserName, model.Password); if (user != null && user.IsConfirmed) { await SignInAsync(user, model.RememberMe); return RedirectToLocal(returnUrl); } else { ModelState.AddModelError("", "Invalid username or password."); } } // If we got this far, something failed, redisplay form return View(model); }
همین. این تمام چیزی بود که برای اضافه کردن تصدیق ایمیل به اپلیکیشن خود نیاز دارید. از آنجا که سیستم ASP.NET Identity با Entity Framework مدیریت میشود و با مدل Code First ساخته شده، سفارشی کردن اطلاعات کاربران و سیستم عضویت سادهتر از همیشه است.
توضیحاتی درباره کار با Postal
اگر به متد SendEmailConfirmation دقت کنید خواهید دید که آبجکتی از نوع Email میسازیم (که در اسمبلیهای Postal وجود دارد) و از آن برای ارسال ایمیل استفاده میکنیم. عبارت "RegEmail" نام نمایی است که باید برای ساخت ایمیل استفاده شود. این متغیر از نوع dynamic است، مانند خاصیت ViewBag. بدین معنا که میتوانید مقادیر مورد نظر خود را بصورت خواص دینامیک روی این آبجکت تعریف کنید. از آنجا که Postal از موتور Razor استفاده میکند، بعدا در View ایمیل خود میتوانید به این مقادیر دسترسی داشته باشید.
در پوشه Views پوشه جدیدی بنام Emails بسازید. سپس یک فایل جدید با نام RegEmail.cshtml در آن ایجاد کنید. کد این فایل را با لیست زیر جایگزین کنید.
To: @ViewBag.To From: YOURNAME@gmail.com Subject: Confirm your registration Hello @ViewBag.UserName, Please confirm your registration by following the link bellow. @Html.ActionLink(Url.Action("RegisterConfirmation", "Account", new { id = @ViewBag.ConfirmationToken }), "RegisterConfirmation", "Account", new { id = @ViewBag.ConfirmationToken }, null)
این فایل، قالب ایمیلهای شما خواهد بود. ایمیلها در حال حاظر بصورت plain text ارسال میشوند. برای اطلاعات بیشتر درباره ایمیلهای HTML و امکانات پیشرفتهتر به سایت پروژه Postal مراجعه کنید.
همانطور که مشاهده میکنید در این نما همان خاصیتهای دینامیک تعریف شده را فراخوانی میکنیم تا مقادیر لازم را بدست آوریم.
- ViewBag.To آدرس ایمیل گیرنده را نشان میدهد.
- ViewBag.UserName نام کاربر جاری را نمایش میدهد.
- ViewBag.ConfirmationToken شناسه تولید شده برای تایید کاربر است.
در این قالب لینکی به متد RegisterConfirmation در کنترلر Account وجود دارد که شناسه تایید را نیز با پارامتری بنام id انتقال میدهد.
یک فایل ViewStart.cshtml_ هم در این پوشه بسازید و کد آن را با لیست زیر جایگزین کنید.
@{ Layout = null; /* Overrides the Layout set for regular page views. */ }