/IdentityExample

Primary LanguageC#MIT LicenseMIT

IdentityExample

ASP.NET Core Identity ile Üyelik Sistemi

Identity, sistem kullanıcılarına üyelik oluşturma, kimliklerini doğrulama ve yetkilendirme sağlayan bir sistemdir. Kullanıcılar identity yapısı sayesinde bilgileri ile bir hesap oluşturabilir ve oluşturulan hesaplar genellikle SQL Server olmak üzere PostgreSQL, MySQL, Azure Table Storage gibi veri tabanları üzerinde de depolanabilir. Kısaca identity için kullanıcı arayüzü (UI) giriş işlevini destekleyen bir API denebilir. .NET Core Identity Scaffolding bu üyelik sistemi için hem arayüz hem de kayıt, giriş gibi kısımlar için gerekli kod bloklarını Razor Pages ile oluşturur.

Bu örnek projede de Identity yapısı kullanılarak kimlik doğrulamasına sahip bir web uygulaması geliştirilmiştir.

Dokümanın devamında örnek adım adım anlatılacaktır.

Öncelikle Visual Studio ortamında yeni bir ASP.NET Core Web Application (C#) projesi oluşturalım. Karşımıza gelen ekranda "No Authentication" seçeneğini "Individual User Accounts" şeklinde değiştiriyor ve böylece projemizi oluşturuyoruz. Create Application

Identity sayfalarının tutulduğu Areas ve hazır DBContext ve Migration ın yerleştiği Data dosyaları bu yapıyla birlikte MVC projesi içerisine gelmiştir.

Bunlarla birlikte oluşan app.setting.json dosyasında otomatik olarak bir Connection String oluşturulmuştur.

{    
{  "ConnectionStrings": {  "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-IEExample-4FC24192-AEFC-4273-80AF-A4C1AD922062;Trusted_Connection=True;MultipleActiveResultSets=true"
  }

Startup.cs içerisinde Sql Server kullanılarak veritabanı ayarları ConfigureServices metotu içerisinde tanımlanmıştır.

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));
            services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
                .AddEntityFrameworkStores<ApplicationDbContext>();
            services.AddControllersWithViews();
            services.AddRazorPages();
        }

Buradaki AddDefaultIdentity IdentityUser sınıfı ile identity ayarlarını servise kaydetmeye yarar. Zaten otomatik olarak oluşturulmuş bu yapıların yanında yapılması gereken işlem migration ve ayarları veritabanına yansıtmak olacaktır. Bunun için Package Manager Console üzerinde update-database işlemi uygulanır. Böylece veritabanı ayarlarıyla birlikte oluşturulmuş olacaktır. Identity yapısı içerisindeki bütün tablolar veritabanı içerisine gelmiş olacaktır. - AspNetUsers tablosu kullanıcı bilgilerini tutar. - AspNetRoles tablosu sistemdeki rolleri tutar. - AspNetUserRoles tablosu kullanıcalara özelleştirilmiş şekilde atanan rolleri tutar. Programı bu aşamada çalıştırırsak kullanıcının mail adresi ve şifresi ile kayıt olup giriş yapmasını sağlayan Register ve Login ekranlarına ulaşabilir ve çalıştırabiliriz.

Bu adımdan sonra projemizin identity özelliklerini geliştirmek ve özelleştirmek istersek kullanıcının adresini, telefon numarasını, cinsiyetini, doğum tarihini, rolünü eklemek üzere adımları takip edebiliriz.

IdentityUser sınıfı içerisinde özellikleri tutuyor. IdentityRole sınıfında ise rollendirme işlemleri mevcut. Biz özelliklerine eklemeler yapmak istiyoruz. Bu nedenle yeni kullanıcı özelliklerini adını CustomUser verdiğimiz yeni bir sınıf içerisine tanımlıyoruz.

 public class CustomUser : IdentityUser
    {
        [Display(Name = "Adı & Soyadı")]
        public string Fullname { get; set; }
        
        [Display(Name = "Adres")]
        public string Address { get; set; }

        [Display(Name = "Cinsiyet")]

        public string  Gender { get; set; }

        [Display(Name = "Doğum Tarihi")]
        [DataType(DataType.DateTime)]

        public DateTime DateOfBirth { get; set; }
    }

IdentityDbContext default olarak IdentityUser sınıfını kullanırken biz özelleştirme yaparken CustomUser ile devam edeceğiz.

 public class ApplicationDbContext : IdentityDbContext<CustomUser>
    {

Startup.cs dosyasında da AddDefaultIdentity sınıfı içerisindeki IdentityUser sınıfını CustomUser olarak değiştireceğiz.

services.AddDefaultIdentity<CustomUser>(options => options.SignIn.RequireConfirmedAccount = false)

Bunlarla birlikte Shared dosyası içindeki _LoginPartial.cshtml dosyasında IdentityUser sınıfını CustomUser ile değiştiriyoruz.

@using Microsoft.AspNetCore.Identity
@inject SignInManager<CustomUser> SignInManager
@inject UserManager<CustomUser> UserManager

Değişiklilerin veritabanına yansıması için Package Manager Console üzerinde add-migration MigrationName ve update-database işlemleri uygulanır.

Identity içerisine bütün sayfalar API üzerinden gelir. Bu nedenle default bir sayfayı Pages içerisinde göremezsiniz. Bu nedenle yeni bir sayfa eklemek için herhangi bir klasörden sağ tıklayarak Add -> New Scaffolded Item diyoruz. Sol taraftan identity seçeneği ile istediğimiz, bizim için "Account/Login”, “Account/Register” ve “Account/Manage/Index", seçenekleri ekliyoruz. Default register ekranında yalnızca email ve şifre ile kayıt olurken biz InputModel içerisine, kullanıcı sınıfına eklediğimiz adı & soyadı, adres, cinsiyet ve doğum tarihi özelliklerini Register.cshtml.cs içerisine ekliyoruz.

public class InputModel
        {
            [Required]
            [EmailAddress]
            [Display(Name = "Email")]
            public string Email { get; set; }

            [Required]
            [Display(Name = "Kullanıcı Adı")]
            public string UserName { get; set; }

            [Required]
            [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
            [DataType(DataType.Password)]
            [Display(Name = "Password")]
            public string Password { get; set; }

            [DataType(DataType.Password)]
            [Display(Name = "Confirm password")]
            [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
            public string ConfirmPassword { get; set; }

            [Display(Name = "Adres")]
            public string Address { get; set; }

            [Display(Name = "Cinsiyet")]

            public string Gender { get; set; }

            [Display(Name = "Doğum Tarihi")]
            [DataType(DataType.DateTime)]

            public DateTime DateOfBirth { get; set; }
            public string Fullname { get; internal set; }
        }

Aynı zamanda Register.cshtml.cs içerisindeki OnPostAsync fonksiyonunda aşağıdaki gibi düzenlemeler yapalım.

var user = new CustomUser { UserName = Input.UserName, Email = Input.Email, Fullname = Input.Fullname, Address = Input.Address, Gender = Input.Gender, DateOfBirth = Input.DateOfBirth};
var result = await _userManager.CreateAsync(user, Input.Password);

_userManager.CreateAsync(user, Input.Password) kodu o kullanıcıyı ve şifresiyle sisteme kaydetmemize yarar. Register html tarafında ise düzenlemeler şu şekilde olmalıdır.

        <h4>Kayıt ol.</h4>
        <hr />
        <div asp-validation-summary="All" class="text-danger"></div>
        
        <div class="form-group">
            <label asp-for="Input.UserName"></label>
            <input asp-for="Input.UserName" class="form-control" />
            <span asp-validation-for="Input.UserName" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Input.Fullname"></label>
            <input asp-for="Input.Fullname" class="form-control" />
            <span asp-validation-for="Input.Fullname" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Input.Email"></label>
            <input asp-for="Input.Email" class="form-control" />
            <span asp-validation-for="Input.Email" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Input.Address"></label>
            <input asp-for="Input.Address" class="form-control" />
            <span asp-validation-for="Input.Address" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Input.Gender"></label>
            <select asp-for="Input.Gender">
                <option disabled>Cinsiyet Seçiniz</option>
                <option  value="Belirtmek istemiyorum">Belirtmek istemiyorum</option>
                <option  value="Kadın">Kadın</option>
                <option  value="Erkek">Erkek</option>
            </select>
            <span asp-validation-for="Input.Gender" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Input.DateOfBirth"></label>
            <input asp-for="Input.DateOfBirth" class="form-control" />
            <span asp-validation-for="Input.DateOfBirth" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Input.Password"></label>
            <input asp-for="Input.Password" class="form-control" />
            <span asp-validation-for="Input.Password" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Input.ConfirmPassword"></label>
            <input asp-for="Input.ConfirmPassword" class="form-control" />
            <span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
        </div>
        <button type="submit" class="btn btn-primary">Kaydol</button>
    
    </form>

Login.cshtml.cs ve Login.cshtml sayfalarında da benzeri benzeri yaparak arka plandaki düzenlemeleri tamamlayabiliriz. Son olarak eğer istenirse _LoginPartial kısmında kullanıcının sisteme giriş yaptığı sayfadakileri düzenleyebiliriz. ile

Identity ile kullanıcıdan istenen bilgiler ve giriş yapma aşamaları özelleştirilebilir ve çeşitlendirmeler ile geliştirilebilirler.

Kaynaklar