درخواست های ارتباط
جستجو
    لیست دوستان من
    صندوق پیام
    همه را دیدم
    • در حال دریافت لیست پیام ها
    صندوق پیام
    رویدادها
    همه را دیدم
    • در حال دریافت لیست رویدادها
    همه رویدادهای من
    تخفیف های وب سایت
    همه تخفیف ها

    عضویت در

    کانال تلگرام

    توسینسو

    اطلاعات مطلب
      مدرس/نویسنده
      برنامه نویس
      امتیاز: 670
      رتبه:360
      0
      1
      1
      48

      سفارشی کردن ASP.NET Identity و استفاده در MVC 5

      تاریخ 25 ماه قبل
      نظرات 5
      بازدیدها 2042
      به نام او که هستی از آن اوست

      با سلام خدمت شما دوستان در این مقاله قصد دارم تا آموزش Identity با شما با اشتراک بگذارم

      در این مقاله قصد دارم تا با هم نحوه استفاده و کاربر Identity در MVC 5 آشناشویم.
      نکته: دراین آموزش علاوه بر یادگیری Identity با ساخت فرم ثبت نام و ورود در یک صفحه و کمی هم با کدفرست آشنا خواهید شد.
      پس از خواندن مطلب پیشنهاد میشود پروژه ضمیمه شده همین مقاله هم نگاه کنید.

      یک توضیح کوتاه درباره Asp.Net Identity : سیستم membership هست که روی ASP.NET 4.5 فعال هستش و برای تعریف role ها و تخصیص آن به کاربران می باشد.

      ابتدا یک پروژه با نام دلخواه ایجاد می کنیم
      ایجاد پروژه


      همان طور که در تصور مشاهده می فرمایید، ما یک پروژه MVC خواهیم ساخت که ChangeAuthentication آن را روی No Authentication قرار می دهیم.
      پروژه ما ساخته شد! حالا نوبت به طراحی دیتابیس می رسد.
      ما به 2 جدول نیاز داریم
      جدول اول که برای ثبت نام و ورود از آن استفاده میکنیم (جدول Users)
      جدول دوم که برای تعریف نقش ها (نقش های کاربری مانند ادمین و..) با نام Roles
      دامین مدل برای جدول کاربران


      همان طور که مشاهده می فرمایید ما یک دامین مدل برای جدول User ساختیم و پراپرتی های مورد نیازمان را ساختیم.(توجه کنید که ما پراپرتی با نام UserName نساختیم زیرا ما ایمیل کاربر را نام کاربریش در نظر میگیرم.)
      دامین مدل برای نقش ها

      همچنین یک دامین مدل دیگری هم برای نقش ها ساختیم.
      نکته قابل توجه این است که RoleName نام نقش ما برای نمایش (مثلا ادمین)و RoleInSystem نام برای استفاده درAttribute ها و کار با نقش ها می باشد.(در ادامه کاملا متوجه خواهید شد)


      جدول

      این هم تعریف جداول ما


      حال ما باید ابتدا یک کلاس RoleProvider بسازیم:
      ساخت کلاس provider

      خوب همانطور که از تصویر مشخص است ما یک کلاس با نام دلخواه (اما با معنی!) انتخاب کردیم که از کلاس RoleProvider ارث بری کرده است و ما می بایست اعضایش را پیاده سازی کنیم:
      پیاده سازی و کد نویسی اعضا

      همان طور که میبینید با پیاده سازی عناصر متد هایی اضافه می شود که کاملا نام آنها گویای کاربر آن می باشد و در صورت نیاز می توانید آنها را پیاده سازی کنید.
      متدی که خیلی مهم می باشد متد string[] GetRolesForUser(string username) است
      همانطور که قبلا گفتم نام متدها گویای کاربردش می باشد ، نقشها را برای کاربر میگیرد.
      دقت کنید ! این متد یک ورودی رشته با نام username می گیرد و درست در همین متد می باشد که ما تعیین خواهیم کرد کدام پراپرتی به عنوان نام کاربری انتخاب شود.
      حال کمی در مورد کد های بالا توضیح خواهم داد:
      ما یک کوئری بر روی جداول Users و Roles که قبلا با هم ساخته بوده ایم زدیم (join) و کاربری که RoleId آن با RoleId جدول Roles برابر است را پیدا می کنیم
      و یک شرط مهم قرار دادیم where u.UserMail == username ما با این شرط تعیین کردیم که ایمیل به عنوان نام کاربری انتخاب شود .
      شما می توانید با تغییر UserMail به هر پراپرتی در دامین مدل User آن پراپرتی را به عنوان نام کاربری انتخاب کنید ! به همین راحتی × اما در انتخاب پراپرتی مناسب دقت لازمه را مبذول فرمایید!
      ودر آخر هم RoleInSystem را بر میگردانیم.
      این کار برای تمام کاربرها انجام میشود و در آخر به صورت آرایه رشته ای برگردانده می شود
      دقت کنید که من در بالای متد ها شی Context ساختم.

      خوب حالا کار دیگری هم مانده ؟ بله آخرین کار یعنی معرفی به فایل WebConfig

      تنظیمات Webconfig


      Authentication به معنای احراز هویت می باشد که بر روی Forms قرار داده ایم.
      در خط بعد ما یک نام قرار دادیم یک timeout زمانی می باشد که

      loginUrl آدرس صفحه ورود می باشد که کنترلر و اکشن ان را بعدا خواهیم ساخت و کاربرانی که بدون احراز هویت وارد صفحه محافظت شده ،شوند به طور خودکار وارد این صفحه خواهند شد
      defaultUrl آدرس صفحه می باشد که کاربر بعد از احراز هویت به طور خودکار وارد آنجا خواهد شد.
      رول منیجر Enable کرده و نام کلاس RoleProvider ای که ساختیم را معرفی خواهیم کرد.
      در آخرهم نام همان کلاس فراهم کننده که ساختیم و آدرس مکانی که آن کلاس در آن قرار دارد.
      تمام!
      هرآنچه تا کنون انجام داده ایم پیاده سازی سفارشی asp.net Identity بودحال می خواهیم از asp.net Identity در پروژه استفاده کنیم:
      بگذارید ابتدا برای سایتمان صفحه ورود و عضویت درست کنیم هردو در یک صفحه ×
      خوب این که هر دو را در یک صفحه پیاده کنیم یا خیر در روند کدنویسی فقطی ندارد پس شما اگر لازم داشتید به راحتی میتوانید صفحات را از هم جدا سازی کنید.
      خوب بریم سر اصل مطلب ابتدا یک کنترلر به نام Account می سازیم
      اما یک لحظه دست نگهدارد ! آیا می خواهید در صفحه عضویت کاربر تمام پراپرتی ها پر کند؟ ویا هنگام ورود کاربر به سایت تمام پراپرتی ها را درست پر کند ؟!(...درست کردن لیست بلند برایگرفتن تمام اطلاعات کاربر باعت ناراحتی و صرف زیاد وقت کاربر برای ثبت نام و وبود می شود...)
      چه می شود اگر ما برای ثبت نام فقط نام کاربری و کلمه عبور بگیریم و هنگام ورود کاربر از سایت فقط هم اطلاعات را از کاربر بگیریم ؟
      برای رفع این مشکل ما از ViewModel ها استفاده می کنیم
      درکل اگر بخواهم یک توضیح کوتاه دهم می توانم اینگونه بگویم که ViewModel ها برای ترکیب چند پراپرتی های چندمدل با هم یا گلچین کردن چند پراپرتی خاص می باشد.
      پس بیایید ابتدا 2 ViewModel درست کنیم اولی برای عضویت و دومی برای ورود
      برای ثبت نام Email و نام کاربر و Password را بگیریم کفایت می کند
      Register ViewModel

      یک کلاس با نام RegisterViewModel ساختیم و در آن پراپرتی هایی که برای ثبت نام لازم داریم را قرار داده ایم (بقیه مشخصات را می توانید در پروفایل یا موقع مثلا خرید از کاربر بگیرید)
      دقت کنید پراپرتی های ما باید حتما بدون غلط املایی و دقیقا همان پراپرتی های باشند که در دامین مدل User نوشته ایم.


      و حالا دامین مدل برای ورود کاربر به نام LoginViewModel
      LoginViewModel


      تصور گویای همه چیز می باشد و از توضیح اضافه خودداری میکنم.

      و حالا این شما و این کنترلر Account
      AccountController

      چون قرار هست هر دو صفحه ورود و عضویت با هم در یک صفحه باشد ما مدل های صفحاتمان را از طریق Viewbag به ویو پاس می دهیم در غیر این صورت بعدا با مشکل مواجه خواهیم شد.
      (اگر صفحات ورود-عضویت شما جدا هستند می توانید ویو را Strongly typed تعریف کنید به این معنا که ViewModel ها را مدل صفحه قرار دهید)
      خوب حالا برویم ویو را درست کنیم دو فرم برای ثبت نام و دیگری برای ورود می سازیم
      Account View

      چند نکته مهم
      1- چون ویو ما مدل ندارد پس ما مدلی تعریف نکردیم (@model)
      2- ما بجای تعریف مدل در ویو ما از ویوبگ ها استفاده کردیم از آنجایی که ویو بگ ها داینامیک هستند و Intlisens ندارند اما ابتدا ویوبگ ها را میگیریم و در متغییر می ریزیم و اینگونه است که Intlisinse دار میشوند !
      3- چون ما @model ندارم پس از متغییر ها استفاده میکنیم
      @Html.EditorFor(model => login.UserMail, new { htmlAttributes = new { @class = "form-control" } })
      4- به دکمه های ورود توجه کنید
      <input type="submit" value="ورود" class="btn btn-default" />
      <input type="submit" value="ثبت نام" class="btn btn-default"/>

      حالا بر میگریدم به کنترلر تا آن را تکمیل کنیم
      تکمیل کنترلر Account

      ما یک اکشن ساختیم که فقط Httppost میباشد با دو ورودی ، یک ورودی از جنس LoginViewModel و یک رشته که نام دکمه کلیک شده توسط کاربر را نمایش می دهد.
      در کنترلر چک میکنیم که اگر کاربر روی دکمه "ورود" کلیک کرده و مشخصات را پر کرده بود
      ابتدا کلمه عبور را میگیرم و رمزگذاری میکنیم (این نوع رمزنگاری یک طرفه می باشد و وفقط می توان رمز کرد-البته منسوخ شده نیز میباشد)
      بعد چک میکنیم اگر کاربری با ایمیل و کلمه عبور رمزگذاری شده در بانک اططلاعاتی ما وجود داشت
      کوکی مربوط به احرازهویست را ست کن و تیک مرابه خاطر بسپار را در آن قرار میدهیم
      و در آخر هم پس از احرازهویت به DefaultUrl ای که در Webconfig تنظیم نمیده ایم کاربر منتقل میشود.
      تکمیل کنترلر Account

      یک اکشن دیگر مانند قبلی میسازیم با این تفاوت که ورودی اول از جنس RegisterViewModel می باشد.
      اگر کاربر بر روی دکمه ثبت نام کلیک کرده بود اگر چنین کاربری وجود نداشت آن را می سازیم.
      و نقش آن را 2 ( نقش کاربر) قرار دادیم
      خوب حالا بریم Migration را بسازیم تا در متد seed آن مقدار Role آن را مقدار دهی کنیم(مقدار آزمایشی)
      برای این کار با دستورات زیر migration را فعال می کنیم
      Enable-Migrations
      Migration Seed Method

      من یک نقش ادمین ساختیم و یک نقش کاربر
      و دو کاربر با نقش های مختلف
      قبل از ادامه کار خوب است بدانید فرق authorize و authentication چیست؟
      به غیر از تشابه املایی
      Authorize به معنای اجاز دادن می باشد
      Authentication به معنای احراز هویت

      ما احراز هویت را در بخش ورود و ثبت نام انجام داده ایم حال نوبت به اجازه دادن میرسد
      چه نقشی اجازه دارد به چه صفحه ای دسترسی داشته باشد!
      این کار در بخش کنترلر ها به راحتی تعریف یک صفت (attribute) می باشد به این صورت
      قرار دادن صفت دسترسی

      به همین راحتی ! زمانی که روی کنترلر صفت اعمال کنیم روی تمامی متد های این کلاس اعمال میشود و در صورتی که می خواهید روی متدی صفت خاصی قرار بدهید فقط کافیست تا در بالای آن متد صفت مورد نظر را بنویسید.
      سفارشی کردن ASP.NET Identity و استفاده  در  MVC 5

      [AllowAnonymous] همه کاربران دسترسی به اکشن/کنترلر مورد نظر را دارند
      [Authorize] فقط کاربران احرازهویت شده دسترسی به اکشن/کنترلر مورد نظر را دارند
      [Authorize(Roles = "Admin")] فقط کاربران احرازهویت شده دسترسی به اکشن/کنترلر مورد نظر را دارند که نقش آنها Admin باشد
      [Authorize(Roles = "Admin , User")] مانند بالا می باشد فقط چند نقش را با هم تعریف کرده ایم

      گاهی در کنترلر و اکشن ها لازم است که ما بدانیم آیا کاربر که قرار است از این اکشن استفاده کند احرازهویت شده است یا نه ؟
      به عنوان مثال در همین کنترلر Account اگر کاربر احرازهویت شده بود نباید دوباره صفحه ورود و عضویت را ببیند . برای اینکار کافیست یک شرط را به ابتدای متد اضافه کنیم
      سفارشی کردن ASP.NET Identity و استفاده  در  MVC 5

      User :یک Iprincipal می باشد که کارش فقط گرفتن اطلاعات محرمانه کاربر از http request می باشد.
      User.IsInRole : یک یک نقش میگیرد و بررسی میکند که آیا کاربر این نقش را دارا میبباشد یا خیر

      سفارشی کردن ASP.NET Identity و استفاده  در  MVC 5

      کد بالا میگوید اگر کاربر وارد شده نقش ادمین را داشت وارد پنل ادمین شود در غیر این صورت وارد آدرس Home شود.

      User.Identity : Identity را از Iprincipal می گیرد.
      اعضای Identity :
      IsAuthenticated : بررسی می کند که آیا تصدیق هویت شده است یا خیر.
      در کد بالا ما گفتیم اگر کاربر تصدیق هویت شده بود برو به home
      حالا بگذارید به بقیه کد های Identity بپردازیم
      IsAuthenticated که بالا تعریف کردیم
      Name : این نام کاربری را برمیکرداند اگر بخاطر داشته باشید ما ایمیل را به عنوان نام کاربر قرار دادیم.
      در مثال ما استفاده از این کد User.Identity.Name ایمیل را بر میگرداند
      AuthenticationType : نوع احراز هویت را بر میگرداند که ما در webconfing آن را روی Form قرار داده ایم

      جالب است نه ؟ حالا جلب ترهم خواهد شد
      ما می توانید از همین کد هم سمت ویو استفاده کنیم!

      استفاده از Identity  سمت view


      ما در Webconfig نوع احرازهویت را روی Form قرار داده ایم، با این کار ما به کلاس FormsAuthentication درسترسی خواهیم داشت که این کلاس حاوی تعدادی متد و خواص مختلفی هست
      سفارشی کردن ASP.NET Identity و استفاده  در  MVC 5

      که شرح کامل آن زمان بر است اما با نگاه به عنوان و توضیحات متد ها کاملا کاربر آن مشخص می شود.
      به عنوان مثال FormsAuthentication.SignOut(); این متد خروج کاربر از حساب کاربری را فراهم میکند !


      و تمام.!

      لینک دانلود پروژه
      امیدوارم توانسته باشم کمی کمک کرده باشم
      مطالب مرتبط

      در حال دریافت اطلاعات

      نظرات
      • این پست حذف شده است
        دلیل حذف:

      • سلام و خسته نباشید
        من مقالتونو خوندم وخیلی عالی و خوب بود
        فقط اونطوری م من متوجه شدم شما خودتون identity رو پیاده سازی کردید و از کلاس خود مایکروسافت استفاده نکرید
        چون من تئ سایتای خارجی م دیدم اول 3 تا کتاب خونه از ناگیت میگیره و طبق اون 3 کتاب خونه کد میزنه
        ممنون میشم بیشتر توضیح بدید
        با تشکر

      • طبق اطلاعات من identity به همراه خود asp.net هست مایکروسافت این امکان را به جای asp.net Membership قرار داده
        و ما آن را بازنویسی کردیم تا به صورت دلخواه بنویسیم. شاید فیلم ها آموزش MemberShip بوده که من با اون کار نکردم
        این آموزش Identity 2 هست که در core نسخه 3 فراهم شده
      • سلام.سپاس دوست عزیز بابت گذاشتن مطلب خوبت.
        چند ایراد.
        اول اینکه در ابتدا که کلاس RoleProvider را گفتید باید بسازیم.در صورتی که این کلاس در دات نت وجود دارد.آیا ساخته اید و نگفته اید یا از همان کلاس roleProvider دات نت استفاده شده.
        دوم اینکه کلاس EspiarRoleProvider که از roleprovider ارث بری شدند،مشخص نیست که چرا Override تعریف شده اند.چون زمانی override میکنید که متدی با همان رفتار وجود دارد و شما میخواهید متد شما جایگزین شود.پس override نبایستی باشد.

        !! مگر اینکه کلاس RoleProvider که ساختید را اصلا نگذاشته اید._اگر از کلاس RoleProvider خود دات نت استفاده کردید پست را Edit کنید و نیازی به ساختن این کلاس نیست.در اینصورت override شما معنا دار خواهد شد._

        سوم اینکه Enabled-migration هم بایستی در package manager console فعال کنیم.
        چهار اینکه کلاس configuration که در آن دیتای و role و.. را دادید توضیح کوتاهی میدادید.
        پنچ اینکه در ویو ها آدرس کنترلر واکشن مربوطه را در beginform بایستی بدهید.
        @using (Html.BeginForm("Login", "Account", FormMethod.Post))
        @using (Html.BeginForm("Register", "Account", FormMethod.Post))
        وآخر اینکه شرط if شما که Value submit را میگیرد باور بفرمایید بسیار ناخوشایند هست.چون کاراکترها فارسی هستند وشرط if روی این کاراکترها در 90 درصد مواقع مشکل دار هستند.اگر شرط را مثلا روی id ویا name قرار دهید قابل هضم تر خواهد بود.
        با کمال سپاس وعذر از شما
        ممنون.خسته نباشید دوست من.
      • باتشکر از مقاله خوبتون
        یه سوال
        چرا وقتی لاگین میشم با پروژه شما در این صفحه"http://localhost:3213AccountLogin" به صفحه خاصی انتقال داده نمیشم؟ حتی قسمت رجیستر هم همین مشکل را دارم
        ممنون میشم راهنمایی کنید
      • دیتابیستون چک کنید ببینید دیتابیس ایجاد کرده یا خیر

      برای ارسال نظر ابتدا به سایت وارد شوید