Bu yazı dizimizde asp.net core web api projemizde jwt kullanarak aşağıdaki işlemleri gerçekleştireceğiz.
- 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.
- Refresh Token sistemi: bu bölümde uygulamamıza refresh token sistemini ekleyeceğiz
- 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
dotnet new webapi -n JwtAuthDemoÖncelikle EF Core paketlerini projemize dahil edelim
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
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearerBununla birlikte gerekli paketleri kurmuş olduk
Şimdi sırada proje yapımız var, hedeflediğimiz proje yapısı şu şekilde olacak
JwtAuthDemo/
┣ Controllers/
┣ Data/
┣ Models/
┣ DTOs/
┣ Services/
┗ Program.csÖncelikle kullanıcı modeli ile başlayalım
Dosya: Models/User.cs
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
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
{
"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
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.
dotnet add package BCrypt.Net-NextDosya: Controllers/AuthController.cs
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
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ı
dotnet ef migrations add InitialCreate
dotnet ef database updateBuraya 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:

Bir yanıt yazın