ASP.NET Core JWT 1. Bölüm: Kurulum

Bu yazı dizimizde asp.net core web api projemizde jwt kullanarak aşağıdaki işlemleri gerçekleştireceğiz.

  1. Kurulum(Bu yazı): Bu kısımda temel EF Core configurasyonunu ve JWT configurasyonunu yapacağız ve amacımız ilk olarak JWT kısmını çalışır hale getirmek.
  2. Refresh Token sistemi: bu bölümde uygulamamıza refresh token sistemini ekleyeceğiz
  3. Policy & Role bazlı yetkilendirme: Bu bölümde yetkilendirmeye ve rollere odaklanacağız, bu sistemi nasıl daha performanslı hale getirebileceğiz buna kafa yoracağız.

Konumuza JWT Nedir? Sorusu ile başlayalım bununile ilgili daha ayrıntılı bir yazı da yazacağız ama şimdilik kısaca değinelim

Her yazının kodlarının son haline github üzerinden ulaşabilirsiniz : https://github.com/gokhancelebi/jwt-tutorial

JWT Nedir?

JWT’nin açılımı Json Web Token, aslında bildiğimiz bir string’den ibaret ama amacı kullanıcı hakkınca server’a bilgi vermek.

JWT kimliği doğrulanmış kullanıcılar için server tarafından oluşturulan bir string’dir bu string içinde server’in eklediği bilgileri içerir ve kullanııcya iletilir.

Kullanıcı her istek attığında kimliğini doğrulamak için bu tokeni de istekle birlikte sunucuya göndermelidir.

Sunucu tarafında şifrelenmiş olan bu tokenin anahtarı sadece sunucuda vardır ve sunucu açar içini bakar bu token içerisinde kullanıcı ile ilgili hangi bilgiler var.

Ardından eğer valid yani geçerli bir token ise kullanıcının kimliği ve yetlikeri doğrulanır ve bu çerçevede istekler atmasına izin verilir.

Geçersiz ise oturumun geçersiz olduğu kullanıcıya bildirilir.

JWT’nin Faydaları

JWT’nin faydaları saymakla bitmez ama en önemli faydası stateless bir yapıya sahip olmasıdır, ölçeklediğiniz bir sistemde hangi sunucuya istek attığınızın bir önemi kalmaz çünkü jwt her node tarafından doğrulanabilir. Bu JWT nin en önemli faydasıdır, bunun dışında performans konusunda da bizlere yardımcı olur çünkü token valid ise ve cachelenmiş şekilde geçerli olduğunu sorgulayabiliyorsam tekrar veritabanına gitmeme kullanıcının yetkilerini ve kimliğini sorgulamama gerek kalmaz.

Yani hem stateless hem de performanslı bir yapı kurmamızı sağlar.

JWT’nin ne olduğunu ve faydalarını bilmemiz bizim açımızdan önemliydi, bilmediğimiz bir şeyi sistemimize dahil edersek karmaşa dışında bir işe hizmet etmeyecektir.

JWT sistemini anladığımıza göre şimdi yavaştan ASP.NET Core projemizde JWT kurulumuna başlayalım!

JWT KURULUMU

JWT kurulumu için öncelikle bir webapi projesi oluşturuyoruz. Ben konsol üzerinden anlatacağım işlemleri siz isteseniz Visual Studio ile de aynı işlemleri gerçekleştirebilirsiniz.

Proje oluşturma komutu

PowerShell
dotnet new webapi -n JwtAuthDemo

Öncelikle EF Core paketlerini projemize dahil edelim

PowerShell
dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools

Şimdi sırada JWT için gerekli paket var

PowerShell
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

Bununla birlikte gerekli paketleri kurmuş olduk

Şimdi sırada proje yapımız var, hedeflediğimiz proje yapısı şu şekilde olacak

PowerShell
JwtAuthDemo/
 ┣ Controllers/
Data/
 ┣ Models/
 ┣ DTOs/
 ┣ Services/
 ┗ Program.cs

Öncelikle kullanıcı modeli ile başlayalım

Dosya: Models/User.cs

C#
namespace JwtAuthDemo.Models
{
    public class User
    {
        public int Id { get; set; }

        public string Username { get; set; } = string.Empty;

        public string PasswordHash { get; set; } = string.Empty;

        public string Role { get; set; } = "User"; // Admin / User gibi roller
    }
}

Sırada DBContext var EF Core ile kullanmak için DBContext sınıfımızı oluşturalım

Dosya: Data/AppDbContext.cs

C#
using Microsoft.EntityFrameworkCore;
using JwtAuthDemo.Models;

namespace JwtAuthDemo.Data
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options)
            : base(options)
        {
        }

        public DbSet<User> Users => Set<User>();
    }
}

JWT sistemimizin çalışabilir olması için bazı gerekli configurasyonlar var bunları appsettings.json’a ekleyelim.

appsettings.json

JSON
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost;Database=JwtDemoDb;Trusted_Connection=True;TrustServerCertificate=True"
  },
  "Jwt": {
    "Key": "supersecretkey!123",
    "Issuer": "JwtAuthDemo",
    "Audience": "JwtAuthDemoUsers",
    "ExpireMinutes": 60
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

EF Core DB Context ve JWT yapılandırmamızı Program.cs dosyamıza ekleyelim

Dosya: Program.cs

C#
using JwtAuthDemo.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

// EF Core
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

// Controller
builder.Services.AddControllers();

// JWT Authentication
var jwtSettings = builder.Configuration.GetSection("Jwt");
var key = Encoding.UTF8.GetBytes(jwtSettings["Key"]);

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = jwtSettings["Issuer"],
        ValidAudience = jwtSettings["Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(key)
    };
});

builder.Services.AddAuthorization();

var app = builder.Build();

app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

Buraya kadar her şey tamam şimdi sırada token üretimi ve kontrolü için AuthController oluşturmak var

Token oluşturmak için gerekli paketimizi projemize yükleyelim.

PowerShell
dotnet add package BCrypt.Net-Next

Dosya: Controllers/AuthController.cs

C#
using JwtAuthDemo.Data;
using JwtAuthDemo.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace JwtAuthDemo.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class AuthController : ControllerBase
    {
        private readonly AppDbContext _context;
        private readonly IConfiguration _config;

        public AuthController(AppDbContext context, IConfiguration config)
        {
            _context = context;
            _config = config;
        }

        [HttpPost("register")]
        public async Task<IActionResult> Register(User user)
        {
            user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(user.PasswordHash); // hashle
            _context.Users.Add(user);
            await _context.SaveChangesAsync();
            return Ok(new { message = "User registered" });
        }

        [HttpPost("login")]
        public async Task<IActionResult> Login(User login)
        {
            var user = await _context.Users.FirstOrDefaultAsync(u => u.Username == login.Username);
            if (user == null || !BCrypt.Net.BCrypt.Verify(login.PasswordHash, user.PasswordHash))
                return Unauthorized("Invalid credentials");

            var token = GenerateJwtToken(user);
            return Ok(new { token });
        }

        private string GenerateJwtToken(User user)
        {
            var jwtSettings = _config.GetSection("Jwt");
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings["Key"]));

            var claims = new[]
            {
                new Claim(JwtRegisteredClaimNames.Sub, user.Username),
                new Claim("role", user.Role),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
            };

            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            var token = new JwtSecurityToken(
                issuer: jwtSettings["Issuer"],
                audience: jwtSettings["Audience"],
                claims: claims,
                expires: DateTime.Now.AddMinutes(double.Parse(jwtSettings["ExpireMinutes"])),
                signingCredentials: creds
            );

            return new JwtSecurityTokenHandler().WriteToken(token);
        }
    }
}

AuthController sayesinde token oluşturma login/register işlemleri için gerekli endpointlerimizi oluşturmuş olduk.

JWT mizi test etmek için bir test controller oluşturalım

Dosya: Controllers/TestController.cs

C#
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace JwtAuthDemo.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class TestController : ControllerBase
    {
        [Authorize]
        [HttpGet("secure")]
        public IActionResult SecureEndpoint()
        {
            return Ok(new { message = "You are authorized!" });
        }

        [AllowAnonymous]
        [HttpGet("public")]
        public IActionResult PublicEndpoint()
        {
            return Ok(new { message = "Anyone can access this" });
        }
    }
}

Deploy etmeye hazır olsun diye migration larımızı oluşturalımı

PowerShell
dotnet ef migrations add InitialCreate
dotnet ef database update

Buraya kadar geldiyseniz artık projemiz hazır ve test edilebilir durumda Postman veya direk tarayıcı üzerinden sistemimizi test edebilirsiniz.

Özet

Bu yazıda sıfırdan bir projeye JWT ile kullanıcı kimliğini doğrulamayı entegre ettik. Herkese açık ve token korumalı endpointler oluşturarak bu özelliğimizi test ettik.

Bir sonraki yazımızda Refresh Token Sistemini bu projemize ekleyeceğiz.

Eğer swagger kullanarak JWT testi yapmak isterseniz:

Yorumlar

“ASP.NET Core JWT 1. Bölüm: Kurulum” için bir yanıt

  1. […] ASP.NET Core JWT 1. Bölüm: Kurulum ←AutoMapper Nedir, Nasıl Kullanılır ASP.NET CORE + EF CORE Örnek Anlatım […]

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir