.Net Core Middleware Nasıl Kullanılır ?
Middleware’ın ne olduğu, ne işe yaradığı hakkında önceki “.Net Core Middleware Nedir ?” yazımda bahsetmiştim.
Kendi ihtiyacımıza göre Middleware oluşturabiliriz. Basit bir örnek ile kendimize özel middlewaremızı oluşturalım. Örneğimizde gelen requesti ve response içeriği değiştirme gibi konulara değineceğiz.
Senaryomuz şu şekilde olsun. Kullanıcımız şifrelenmiş bir sayı göndersin middleware ile bu sayının şifresini çözelim sonra Controllerımız bu sayıyı iki rakamı ile çarpsın response olurken de sayıyı değiştirip şifreleyelim
- Şifrelenmiş sayı
- Şiflemeyi middleware ile çözme
- Controllerda çözülen sayı ile işlem
- Response dönerken içeriği değiştirme ve tekrar şifreleme
EncryptionManager adında bir sınıf oluşturuyorum bu sınıfın içinde rakamları şifreleyeceğiz ve şifrelenmeyi çözeceğiz. Sanalkurst.net’te ki metotları kullanacağız.
public class EncryptionManager
{
public string hash = "sifreliRakamlar";
public string Encrypt(string unencryptedText)
{
byte[] data = UTF8Encoding.UTF8.GetBytes(unencryptedText);
using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
{
byte[] keys = md5.ComputeHash(UTF8Encoding.UTF8.GetBytes(hash));
using (TripleDESCryptoServiceProvider tripDes = new TripleDESCryptoServiceProvider() { Key = keys, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 })
{
ICryptoTransform transform = tripDes.CreateEncryptor();
byte[] results = transform.TransformFinalBlock(data, 0, data.Length);
return Convert.ToBase64String(results, 0, results.Length);
}
}
}
public string Decrypt(string encryptedText)
{
byte[] data = Convert.FromBase64String(encryptedText);
using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
{
byte[] keys = md5.ComputeHash(UTF8Encoding.UTF8.GetBytes(hash));
using (TripleDESCryptoServiceProvider tripDes = new TripleDESCryptoServiceProvider() { Key = keys, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 })
{
ICryptoTransform transform = tripDes.CreateDecryptor();
byte[] results = transform.TransformFinalBlock(data, 0, data.Length);
return UTF8Encoding.UTF8.GetString(results);
}
}
}
}
Infrastructure adında bir klasör oluşturuyorum, bu klasörün içerisinde middleware sınıflarımız olacak.
EncryptedNumberTransaction adında bir sınıf oluşturuyorum bu bizim middlewaremız olacak ve şifrelenmiş sayıları çözecek.
public class EncryptedNumberTransaction
{
//Önceki middleware'den gelen context'i alıyoruz.
private RequestDelegate _request;
public EncryptedNumberTransaction(RequestDelegate request)
{
_request = request;
}
public async Task Invoke(HttpContext httpContext)
{
//Query string üzerinden gelen şifreli sayımız
var item = httpContext.Request.Query["number"].ToString();
//Şifrelenmiş sayımızı çözüp numberDecrypt adında itemımıza aktarıyoruz.
EncryptionManager encryptionManager = new EncryptionManager();
httpContext.Items["numberDecrypt"] = encryptionManager.Decrypt(item);
//Sonraki middleware'e gönder
await _request.Invoke(httpContext);
}
}
Şimdi Middlewareımızı kullanalım bunun için Startup.cs sınıfımıza middlewareımızı ekleyelim.
app.UseAuthorization(); //Sonrasına Ekliyorumapp.UseMiddleware<EncryptedNumberTransaction>();
EncryptedNumbersController adında bir controller oluşturalım.
[HttpGet]
public IActionResult Get()
{
if (HttpContext.Items["numberDecrypt"] != null)
{
return Ok((Convert.ToInt32(HttpContext.Items["numberDecrypt"]) * 2).ToString());
}
return BadRequest();
}
Öncelikle dikkat ettiyseniz Get metodumuzda herhangi bir parametre isteği yok çünkü bunu middleware ile yakalayacağız. Projemizi çalıştırıp postman ile test edelim.
Varsayılan sayımız 10 şifrelenmiş hali aşağıdaki gibidir.
75BHtTt4clo=
Gördüğünüz gibi query stringimizde şifreli sayımızı middleware da yakalayıp şifresini çözüp controllerda iki ile çarparak işlem yapıp yanıt gönderdik.
Şimdi de başka bir middleware oluşturalım ve geri dönen değeri değiştirelim. Geri dönen sayıya 10 ekleyelim
Infrastructure klasörünün içerisine DecryptNumberTransaction sınıfını oluşturuyoruz içeriği aşağıdaki gibidir.
public class DecryptNumberTransaction
{
private RequestDelegate _request;
public DecryptNumberTransaction(RequestDelegate request)
{
_request = request;
}
public async Task Invoke(HttpContext httpContext)
{
var originBody = httpContext.Response.Body;
try
{
var memStream = new MemoryStream();
httpContext.Response.Body = memStream;
await _request(httpContext).ConfigureAwait(false);
memStream.Position = 0;
var responseBody = new StreamReader(memStream).ReadToEnd();
//Response Sonucuna +10 Ekle
string sonuc = (Convert.ToInt32(responseBody) + 10).ToString();
//Response Sonucunu Şifrele
EncryptionManager encryptionManager = new EncryptionManager();
responseBody = "Şifrelenmiş Sayı : '" + encryptionManager.Encrypt(sonuc) + "' Şifrelenmemiş Sayı '" + sonuc+"'";
var memoryStreamModified = new MemoryStream();
var sw = new StreamWriter(memoryStreamModified);
sw.Write(responseBody);
sw.Flush();
memoryStreamModified.Position = 0;
await memoryStreamModified.CopyToAsync(originBody).ConfigureAwait(false);
}
finally
{
httpContext.Response.Body = originBody;
}
}
}
Startup.cs dosyamıza ekliyoruz.
app.UseMiddleware<EncryptedNumberTransaction>(); //Sonrasına Ekliyorumapp.UseMiddleware<DecryptNumberTransaction>();
Gördüğünüz gibi response içeriğini değiştirerek sayımızın hem şifrelenmiş halini hem de kendisini döndürdük.
Neler Yaptık ?
- Gelen şifrelemeli request(istek) bilgisini özel middleware yaparak şifrelememizi çözdük. (Gelen Sayı: 10)
- Çözülen sayı ile controllerda işlem yaparak geri döndürdük (gelen sayı* 2 =20)
- Tekrar özel bir middleware yaparak response olan içeriğimizi değiştirdik ve şifreledik.(gelen sonuç 20 sayımıza 10 ekleyerek geri 30 sayımızı şifreleyerek döndürdük)