C#

Net 7 ile Gelen Yenilikleri İnceliyoruz

Selam dostlar, 

Uzun bir aradan sonra yazılarımıza, geçtiğimiz günlerde tazecik kullanıma sunulan .NET 7 ile devam ediyoruz. Birlikte; .NET 6 dan 7’ye neler değişmiş, neler eklenmiş bunları inceleyeceğiz. Dilerseniz sizler de bu konu hakkındaki Microsoft’un dokümanını kontrol edebilirsiniz. Kahvelerimizi aldıysak başlayalım.

 

RATE LIMITING

İlk olarak bizleri rate limiter karşılıyor. Öncelikle yeni bir web developersanız, nedir bu rate limiter diye düşünüyor olabilirsiniz. Şöyle izah edeyim:

Bir API nin görevi; müşteriden (client) gelen requestlere yani isteklere, bir cevap(response) üretmektir. Fakat gelgelelim ki; dünyada kötü niyetli kimseler de bulunmaktadır. Bu kötü niyetli kişiler bizim API’mızın kaldırabileceğinden daha fazla istek yollayabilmektedir. Bizler aramızda buna DOS veya DDOS saldırıları diyoruz. Bu sefer bizim uygulamamızın ölçeklenebilirliği bozulacak bazı kullanıcılara 1 saniyede, bazılarına ise dakikalarca cevap veremeyecektir. Bu noktada biz gelen istekleri bir sınırlandırma yapmamız gerekir. Bu noktada bizlere artık güvenlik için gerekli olan Rate Limit devreye girer. Rate Limit; müşterinin belirli bir zaman diliminde yapabileceği istek sayısı için sabit bir sayı belirlemenizi sağlar. Bu durumda sistemin etkilenmemesi adına, client isteklerinin cevaplanma süresi o client özelinde düşürülür veya belli bir limitten yukarıdaki isteklerine cevap alamaz hale getirilir. Gelin bunu .Net 7 de nasıl uygulandığına bakalım.

Başlangıçta, bu davranışın Microsoft.AspNetCore.RateLimiting middleware yazılımı ile ekleneceğini söyleniyor. Web uygulamaları bu ilkeleri Program.cs içinde yapılandırabilir ve ardından bunları API uç noktalarıyla kullanabilir.

Aşağıdakiler dahil birkaç farklı rate limiting seçeneği vardır:

- Fixed window

- Sliding window

- Token bucket

- Concurrency

Burada tüm rate limiting seçeneğini incelememiz çok mümkün gözükmüyor. Bu nedenle Fixed Window özelliği üzerinden bir uygulama yapalım. Fixed Window seçeneğine daha ayrıntılı bakıldığında, istekleri sınırlamak için sabit bir süre kullanır. Süre dolduğunda istek limiti resetlenir.

Aşağıdaki örnekte, bir TestPolicy sabit pencere sınırlayıcısı oluşturduk. Politika, her 12 saniyede bir isteğe izin verir. Ayrıca 3'lük bir kuyruk sınırı belirledik, yani 3 istek işlenene kadar askıda kalacak. 3'ten fazla istek sıraya alınırsa, sonraki istekler 503 Hizmet Kullanılamıyor hatası verir.

 //Program.cs
builder.Services.AddRateLimiter(_ => _
    .AddFixedWindowLimiter(policyName: "TestPolicy", options =>
    {
        options.PermitLimit = 1;
        options.Window = TimeSpan.FromSeconds(12);
        options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
        options.QueueLimit = 3;
    }));
 
var app = builder.Build();

app.UseRateLimiter();
 

Bu ilkeyi bir API uç noktasıyla kullanmak için buna EnableRateLimiting özniteliği atanabilir. Politika adını o özniteliğin bir parametresi olarak bekler. Politikanın adı TestPolicy olduğundan, özniteliğe geçireceğimiz parametre budur.

 
// RateLimiterController.cs
[ApiController]
[Route("[controller]")]
public class RateLimiterController : ControllerBase
{
    [EnableRateLimiting("TestPolicy")]
    [HttpGet]
    public IEnumerable<int> Get()
    {
        return new List<int>
        {
            { 2 },
            { 4 },
            { 6 }
        };
    }
}

 

Arka arka ya tekrar request yollarsak bu sefer bizi beklemeye alacaktır.

Yalnız Olan Authentication şeması DefaultScheme Olarak Ayarlanır

Eğer ki daha önce bir web sitesi kullanmış iseniz. Login kısmını az çok bilirsiniz. Bunun adı aslında arka tarafta kimlik doğrulama olarak geçer. Mesela bu doğrulama ile birlikte biz bu kullanıcının kullanıcı mı yoksa admin mi olduğunu da pekala anlarız. Bu da yetkilendirme olarak karşımıza çıkar. 

Bunun için biz, web uygulamamızda program.cs içerisinde kimlik kontrolü için şöyle bir ara katman geliştiririz:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme,
        options => builder.Configuration.Bind("JwtSettings", options))
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
        options => builder.Configuration.Bind("CookieSettings", options));

AddAuthentication parametresi JwtBearerDefaults.AuthenticationScheme, belirli bir düzen istenmediğinde varsayılan olarak kullanılacak düzenin adıdır. Daha sonra ise;

Kimlik doğrulaması ara yazılımı Program.cs içinde UseAuthentication çağrılarak eklenir. UseAuthentication çağrısı, önceden kaydedilmiş kimlik doğrulaması düzenlerini kullanan ara yazılımı kaydeder. Kimlik doğrulaması yapılan kullanıcılara bağlı herhangi bir ara yazılımdan önce UseAuthentication çağrısı yapılır.

Ne demek abi bu der gibi bakabilirsiniz. Şöyle bizler kullanacağımız kimlik doğrulama yöntemimiz bir tane olsa bile aşağıdaki gibi tanımlamak zorundaydık: 

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer();

Net 7 ile artık kodumuzda tanımlı tek bir şema varsa ayrıca gidip bunu default şema olarak tanımlamaya gerek duymuyoruz. Otomatik olarak tek bir şema varsa bu default şemadır deniyor. Yani kullanımı böyle:

builder.Services.AddAuthentication().AddJwtBearer();

 Tabii olası durumlarda bu özelliği devre dışı bırakıp, eski özellikleri de kullanmaya devam edebiliyoruz.

MVC and Razor pages

 

MVC görünümlerinde ve Razor Sayfalarında null yapılabilir modeller için destek

Bu geliştirmede açıkçası anlam vermekte zorlandım. Çünkü; bu özelliği .net 5, 6 ve 7 de denememde herhangi bir hata almadım. Zaten kullanımda olan bir özellikti. Açıkçası tam olarak anlam veremesem de, önceki sürümlerde bu konular ile ilgili bir kaç tartışmada özelliğin tam çalışmadığı tartışılmış. Belki de geliştirmeler tamamlanmış olabilir. Yanlışsam veya neden olduğunu biliyorsanız; yanlışımı düzeltin lütfen.

Örnek bir uygulama: Net 6 da uygulama oluşturup null veri yollamaya çalışalım (Kod .Net 7’de de çalışmaktadır.):

// HomeController.cs
public IActionResult Index()
{
   Product? product = null;
   return View(product);
}
// index.cshtml
@model Product?
@if (Model is null)
{
   <p>
       No Content
   </p>
}
else
{
    <p>
       @Model.name
   </p>
}

 

MVC ve API Denetleyicilerinde IParsable<T>.TryParse ile Bağlanması

Bu özellik ise bizlere, querylerdeki girilen değerleri parse etmekte yardımcı olan bir interfacedir. Doğrudan kullanımına geçelim:

//UserController.cs
[HttpGet( "user")]
public IActionResult Get([FromQuery] User user)
{
   return Ok(user);
}
//User.cs
public class User : IParsable<User>
{
   public string? Name { get; set; }
   public int? BirthYear { get; set; }
   public static User Parse(string s, IFormatProvider? provider)
   {
       if (!TryParse(s,provider,out var result))
       {
           throw new ArgumentException("Tipler uyumlu değil.");
       }
       return result;
   }

   public static bool TryParse(string? s, IFormatProvider? provider, out User result)
   {
       var sagments = s?.Split(",");
       if (sagments?.Length == 2 && int.TryParse(sagments[1],provider, out var year))
       {
           result = new User
           {
               Name = sagments[0],
               BirthYear = year
           };
           return true;
       }
       result = new User()
       {
           Name = default,
           BirthYear = default
       };
       return false;
   }
}

Bizler “http://localhost:5008/api/user?user=batuhan,12” linkine bir request atığımızda otomatik olarak parse metoduna düşecek ve bizim özelleştirdiğimiz tryparse metodunda bu query’i parse etmeyi deneyecektir. 

 

Çerez Onay Değerinin Özelleştirilmesi

Hayatımıza GDRP’nin girmesi ile birlikte çerez onaylama işlemi ülkemizde de dahil tüm Avrupa Birliğinde bir standart haline getirildi. Eğer ki cookie’lere işiniz düştüyse GDRP’yi duymuş olmalısınız. GDRP nedir, sorusuna ise şöyle bir cevap verebiliriz.

General Data Protection Regulation (General Data Protection Regulation), Avrupa Birliği (EU) kapsamında, Avrupa Birliği vatandaşlarının kişisel verilerinin korunmasına yönelik olarak düzenlenmiş, doğrudan bağlayıcı ve uygulanabilir bir yönetmeliktir.

.Net, DGRP desteğini sunmaktadır. Gelin bunun uygulanmasını görelim.

//Program.cs
builder.Services.Configure<CookiePolicyOptions>(options =>
{
    // This lambda determines whether user consent for non-essential 
    // cookies is needed for a given request.
    options.CheckConsentNeeded = context => true;
    options.MinimumSameSitePolicy = SameSiteMode.None;
});
//Other operations
app.UseCookiePolicy();	

Şeklinde biz Cookie politakasını web uygulamamıza dahil edebiliyoruz. .Net 7 ile birlikte artık aşağıdaki kodda da olduğu gibi consent değerini customize edebileceğiz.

builder.Services.Configure<CookiePolicyOptions>(options =>
{
    options.CheckConsentNeeded = context => true;
    options.MinimumSameSitePolicy = SameSiteMode.None;
    options.ConsentCookieValue = "true";
});

 

Sonuç olarak, buradaki incelemelerimiz sadece küçük bir bölümünü oluşturuyor ama şunu söyleyebiliriz ki; .Net 7 de karşımıza kolay entegre edilebilir kimlik doğrulama, routing ve maping konuları üzerine yoğunlaşıldığını görmekteyim. Şu anda preview sürüm olarak karşımızda dursa da gelecek yıllarda LTS olarak kaşımıza çıkacak bu versiyona önceden aşina olmakta fayda görüyorum. Uzun bir değişiklikler listesi olduğundan dolayı bu konu hakkında bir kaç post atmaya karar verdim.

 

Gelecek postlarda tekrar görüşmek dileğiyle. Sağlıcakla…

0 Yorum
Yorum Yap
Batuhan Önder
Merhaba, Ben Batuhan Önder

Her zaman ilk olmak gibi bir zorunluluğumuz yoktur. Fakat en iyisi olmak gibi bir hedefimizin olması zorunluluktur.

Bizi takip edin!

Gelişmelerden daha hızlı haberdar olmak için sosyal medya hesaplarımızı takip edin.