﻿
{"id":13245,"date":"2020-02-13T13:51:38","date_gmt":"2020-02-13T13:51:38","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=13245"},"modified":"2020-02-13T13:51:38","modified_gmt":"2020-02-13T13:51:38","slug":"asp-net-core-3-1-ile-token-bazli-kimlik-dogrulamasi-ve-refresh-token-kullanimijwt","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-3-1-ile-token-bazli-kimlik-dogrulamasi-ve-refresh-token-kullanimijwt\/","title":{"rendered":"Asp.NET Core 3.1 ile Token Bazl\u0131 Kimlik Do\u011frulamas\u0131 ve Refresh Token Kullan\u0131m\u0131(JWT)"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>G\u00fcn\u00fcm\u00fcz web uygulamalar\u0131nda veri g\u00fcvenli\u011fini sa\u011flayabilmek i\u00e7in kullan\u0131c\u0131 do\u011frulama y\u00f6ntemleri aras\u0131ndan en etkili ve \u00e7a\u011fda\u015f olanlar\u0131ndan kabul edebilece\u011fimiz <em>Token Bazl\u0131 Kimlik Do\u011frulama<\/em> y\u00f6ntemi ile sistemsel ve kullan\u0131c\u0131 a\u00e7\u0131s\u0131ndan en az maliyette en y\u00fcksek verimi elde edebilmekte ve g\u00fcvenli bir \u015fekilde gerekli authorization i\u015flemlerini ger\u00e7ekle\u015ftirebilmekteyiz.<\/p>\n<p>Bu makalemizde Asp.NET Core uygulamalar\u0131nda Token Bazl\u0131 Kimlik Do\u011frulama yap\u0131lanmas\u0131n\u0131 a&#8217;dan z&#8217;ye inceleyece\u011fiz. Esas\u0131nda daha \u00f6nceden bu konu \u00fczerine k\u00e2h Asp.NET mimarisi i\u00e7in olsun k\u00e2h Node.JS i\u00e7in olsun bir\u00e7ok makale karalam\u0131\u015f bulunmaktay\u0131m. \u0130lgili makaleleri a\u015fa\u011f\u0131da listelersek e\u011fer;<\/p>\n<ul>\n<li><a href=\"https:\/\/www.gencayyildiz.com\/blog\/asp-net-mvc-web-api-token-authentication\/\" rel=\"noopener noreferrer\" target=\"_blank\">Asp.NET MVC &#8211; Web Api Token Authentication<\/a><\/li>\n<li><a href=\"https:\/\/www.gencayyildiz.com\/blog\/angular-ile-token-authentication-uygulanan-web-api-tetikleme\/\" rel=\"noopener noreferrer\" target=\"_blank\">Angular \u0130le Token Authentication Uygulanan Web API Tetikleme<\/a><\/li>\n<li><a href=\"https:\/\/www.gencayyildiz.com\/blog\/ajax-ile-token-authentication-uygulanan-web-api-tetikleme\/\" rel=\"noopener noreferrer\" target=\"_blank\">Ajax \u0130le Token Authentication Uygulanan Web API Tetikleme<\/a><\/li>\n<li><a href=\"https:\/\/www.gencayyildiz.com\/blog\/json-web-tokenjwt-nedir\/\" rel=\"noopener noreferrer\" target=\"_blank\">JSON Web Token(JWT) Nedir?<\/a><\/li>\n<li><a href=\"https:\/\/www.gencayyildiz.com\/blog\/node-js-jwt-ile-token-olusturma\/\" rel=\"noopener noreferrer\" target=\"_blank\">Node.js \u2013 JWT \u0130le Token Olu\u015fturma<\/a><\/li>\n<li><a href=\"https:\/\/www.gencayyildiz.com\/blog\/node-js-jwt-token-kullanimi\/\" rel=\"noopener noreferrer\" target=\"_blank\">Node.js &#8211; JWT Token Kullan\u0131m\u0131<\/a><\/li>\n<li><a href=\"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-angular-7-web-api-token-authentication-kullanimi\/\" rel=\"noopener noreferrer\" target=\"_blank\">Asp.NET Core\/Angular 7 \u2013 Web Api Token Authentication Kullan\u0131m\u0131<\/a><\/li>\n<\/ul>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere konuya dair blo\u011fumuzda \u00f6nceden bir\u00e7ok kaynak mevcuttur. <strong><em>Peki hoca, madem konuya dair \u00f6nceden karalad\u0131klar\u0131n var. Ne diye tekrar ayn\u0131 konuda i\u00e7erik olu\u015fturuyorsun?<\/em><\/strong> sorunuzu duyar gibiyim. Biliyorsunuz ki son zamanlarda <a href=\"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-identity-yazi-dizisi\/\" rel=\"noopener noreferrer\" target=\"_blank\">Asp.NET Core Identity<\/a> \u00fczerine detayl\u0131 yaz\u0131 dizisi kaleme almaktay\u0131m. \u0130\u015fte bu yaz\u0131 dizisinde authentication y\u00f6ntemlerinden biri olarak yer alacak ve konuyu s\u0131f\u0131rdan ele al\u0131p ve ad\u0131m ad\u0131m kodlama standartlar\u0131n\u0131 belirleyecek bir i\u00e7erik ortaya koyma niyetindeyim. Ayriyetten di\u011fer makalelerde bulamayaca\u011f\u0131n\u0131z terminolojilerle birlikte farkl\u0131 tan\u0131mlamalar ve y\u00f6ntemlerde ele al\u0131nm\u0131\u015f olacakt\u0131r.<\/p>\n<p>\u0130\u015fte bu niyetle yeni bir minvalde yol alaca\u011f\u0131z&#8230; O halde haydi gelin ba\u015flayal\u0131m.<\/p>\n<h3>Ba\u015flarken<\/h3>\n<p>Makalemize ba\u015flarken bir adet Asp.NET Core Web API projesinin hali haz\u0131rda bulunmas\u0131yla birlikte gerekli authentication kontrol\u00fcnde bizlere e\u015flik edecek olan a\u015fa\u011f\u0131daki &#8220;Users&#8221; tablosunu tasarlamam\u0131z gerekmektedir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class User\r\n    {\r\n        public int Id { get; set; }\r\n        public string Name { get; set; }\r\n        public string Surname { get; set; }\r\n        public string Email { get; set; }\r\n        public string Password { get; set; }\r\n        public string RefreshToken { get; set; }\r\n        public DateTime? RefreshTokenEndDate { get; set; }\r\n    }\r\n<\/pre>\n<p><em style=\"font-size:12px;\">Users tablosunu <a href=\"https:\/\/www.gencayyildiz.com\/blog\/entity-framework-ile-code-first-yaklasimi\/\" rel=\"noopener noreferrer\" target=\"_blank\">Code First<\/a> yahut <a href=\"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-uygulamalarinda-database-first-yaklasimi-ile-mevcut-veritabaninda-calisma\/\" rel=\"noopener noreferrer\" target=\"_blank\">Database First<\/a> yakla\u015f\u0131mlar\u0131ndan herhangi biriyle tasarlay\u0131p, olu\u015fturabilirsiniz.<\/em><\/p>\n<p>Olu\u015fturulan &#8220;Users&#8221; tablosuna tekrar g\u00f6z atarsak e\u011fer standart kolonlar\u0131n d\u0131\u015f\u0131nda &#8220;RefreshToken&#8221; ve &#8220;RefreshTokenEndDate&#8221; kolonlar\u0131 mevcuttur. Bu kolonlar\u0131n ne ama\u00e7la olu\u015fturuldu\u011funa de\u011finebilmek i\u00e7in \u00f6ncelikle \u00fcretilecek token yap\u0131lanmas\u0131yla ilintili &#8220;Access Token&#8221; ve &#8220;Refresh Token&#8221; terimlerini a\u00e7\u0131klamam\u0131z gerekmektedir.<\/p>\n<ol>\n<li><strong>Access Token<\/strong><br \/>\nOAuth 2.0 protokol\u00fcne g\u00f6re RFC 7519 standart\u0131nda olan ve authorization neticesinde belirli bir expire s\u00fcresine ba\u011fl\u0131 bir \u015fekilde \u00fcretilip kullan\u0131c\u0131ya sunulan g\u00fcvenli bir anahtar de\u011feridir. Anlayaca\u011f\u0131n\u0131z token&#8217;\u0131n ta kendisidir \ud83d\ude42\n<\/li>\n<li><strong>Refresh Token<\/strong><br \/>\nAccess token&#8217;\u0131n expire s\u00fcresi sona ermeye yakla\u015ft\u0131\u011f\u0131nda veya sona erdi\u011finde yeni bir access token \u00fcretebilmek i\u00e7in kullan\u0131lan token de\u011feridir. Kullan\u0131c\u0131ya verilen access token de\u011feri yan\u0131nda refresh token de\u011feri verilerek, access token s\u00fcresi doldu\u011fu taktirde bu refresh token ile yeni token talebinde bulunabilecektir. B\u00f6ylece kullan\u0131c\u0131 token s\u00fcresi doldu\u011fu taktirde oturumdan d\u00fc\u015f\u00fcr\u00fclmeden yeni token elde edebilecek ve yoluna devam edecektir.\n<\/li>\n<\/ol>\n<blockquote><p><strong style=\"color:purple;\">Dikkat!!! Her zaman Refresh Token Expiration Access Token Expiration&#8217;dan fazla olmal\u0131d\u0131r!<\/strong><\/p><\/blockquote>\n<p>\u0130\u015fte &#8220;Users&#8221; tablosundaki &#8220;RefreshToken&#8221; kullan\u0131c\u0131 i\u00e7in \u00fcretilmi\u015f olan refresh token de\u011ferini tutacak olan kolondur. &#8220;RefreshTokenEndDate&#8221; kolonu ise \u00fcretilen refresh token de\u011ferinin i\u015flev\/kullan\u0131m s\u00fcresini belirleyecek olan zaman bilgisini tutan aland\u0131r.<\/p>\n<h3>Token Servisinin Uygulamaya Eklenmesi<\/h3>\n<p>Asp.NET Core uygulamas\u0131nda token ile authentication i\u015flemlerini ger\u00e7ekle\u015ftirebilmek i\u00e7in JWT Token servisini uygulamaya eklememiz gerekmektedir. Bunun i\u00e7in &#8220;Startup.cs&#8221; dosyas\u0131ndaki &#8220;ConfigureServices&#8221; metodu i\u00e7erisinde &#8220;AddAuthentication&#8221; middleware&#8217;i arac\u0131l\u0131\u011f\u0131yla bir \u015fema olu\u015fturarak i\u015fe ba\u015flamal\u0131y\u0131z. \u0130lgili metodu a\u015fa\u011f\u0131daki g\u00f6rselde oldu\u011fu gibi \u00e7a\u011f\u0131rarak ikinci overload\u0131na g\u00f6z atarsak e\u011fer;<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT.png\" alt=\"Asp.NET Core - Token Bazl\u0131 Kimlik Do\u011frulama(JWT)\" width=\"835\" height=\"85\" class=\"aligncenter size-full wp-image-13272\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT.png 835w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-300x31.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-768x78.png 768w\" sizes=\"auto, (max-width: 835px) 100vw, 835px\" \/><\/a><br \/>\ng\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere bir default scheme de\u011feri istemektedir.<br \/>\n<em><strong>Peki bizden istenen bu default scheme de\u011feri nedir?<\/strong><\/em><br \/>\nBir authentication i\u015flemini farkl\u0131 pozisyonlar i\u00e7in farkl\u0131 \u015fekilde tan\u0131mlamak isteyebiliriz.<br \/>\n\u00d6rne\u011fin; &#8216;<em>Bayi Authentication<\/em>&#8216; &#8211; &#8216;<em>Kullan\u0131c\u0131 Authentication<\/em>&#8216; gibi&#8230;<br \/>\n\u0130\u015fte bu mant\u0131kta bir isimlendirmeyle farkl\u0131 authentication \u015femas\u0131 tan\u0131mlanabilir. Bizler ister benzer \u015fekilde opsiyonel de\u011ferler tan\u0131mlayarak \u015fema belirleyebilir yahut default \u015fema ayar\u0131 vererek buradaki ihtiyaca daha spesifik \u00e7\u00f6z\u00fcm getirebiliriz. E\u011fer ki tercihimiz default \u015fema ayar\u0131 ise bunun i\u00e7in &#8220;<em style=\"font-size:12px;color:orange;\">Microsoft.AspNetCore.Authentication.JwtBearer<\/em>&#8221; k\u00fct\u00fcphanesindeki &#8220;JwtBearerDefaults&#8221; s\u0131n\u0131f\u0131n\u0131 kullanmam\u0131z gerekecektir.<\/p>\n<p>Velhas\u0131l, JWT Token servisini uygulamaya entegre edersek;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class Startup\r\n    {\r\n        public Startup(IConfiguration configuration)\r\n        {\r\n            Configuration = configuration;\r\n        }\r\n\r\n        public IConfiguration Configuration { get; }\r\n        public void ConfigureServices(IServiceCollection services)\r\n        {\r\n            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(option =&gt;\r\n            {\r\n                option.TokenValidationParameters = new TokenValidationParameters\r\n                {\r\n                    ValidateAudience = true,\r\n                    ValidateIssuer = true,\r\n                    ValidateLifetime = true,\r\n                    ValidateIssuerSigningKey = true,\r\n                    ValidIssuer = Configuration&#x5B;&quot;Token:Issuer&quot;],\r\n                    ValidAudience = Configuration&#x5B;&quot;Token:Audience&quot;],\r\n                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration&#x5B;&quot;Token:SecurityKey&quot;])),\r\n                    ClockSkew = TimeSpan.Zero\r\n                };\r\n            });\r\n            .\r\n            .\r\n            .\r\n            services.AddControllers();\r\n        }\r\n    }\r\n<\/pre>\n<p>\u015feklinde \u00e7al\u0131\u015fma yapmam\u0131z yeterli olacakt\u0131r. Burada dikkat ederseniz &#8220;Audience&#8221;, &#8220;Issuer&#8221;, &#8220;LifeTime&#8221;, &#8220;SigningKey&#8221; ve &#8220;ClockSkew&#8221; kavramlar\u0131 mevcuttur. Bu kavramlar\u0131n ne oldu\u011funa dair bir a\u00e7\u0131klama yapmam\u0131z gerekirse e\u011fer;<\/p>\n<ul>\n<li><strong>Audience<\/strong><br \/>\nOlu\u015fturulacak token de\u011ferini kimlerin\/hangi originlerin\/sitelerin kullanaca\u011f\u0131n\u0131 belirledi\u011fimiz aland\u0131r. <span style=\"font-size:12px;\">\u00d6rne\u011fin; &#8220;www.bilmemne.com&#8221;<\/span>\n<\/li>\n<li><strong>Issuer<\/strong><br \/>\nOlu\u015fturulacak token de\u011ferini kimin da\u011f\u0131tt\u0131\u011f\u0131n\u0131 ifade edece\u011fimiz aland\u0131r.  <span style=\"font-size:12px;\">\u00d6rne\u011fin; &#8220;www.myapi.com&#8221;<\/span>\n<\/li>\n<li><strong>LifeTime<\/strong><br \/>\nOlu\u015fturulan token de\u011ferinin s\u00fcresini kontrol edecek olan do\u011frulamad\u0131r.\n<\/li>\n<li><strong>SigningKey<\/strong><br \/>\n\u00dcretilecek token de\u011ferinin uygulamam\u0131za ait bir de\u011fer oldu\u011funu ifade eden security key verisinin do\u011frulamas\u0131d\u0131r.\n<\/li>\n<li><strong>ClockSkew<\/strong><br \/>\n\u00dcretilecek token de\u011ferinin expire s\u00fcresinin belirtildi\u011fi de\u011fer kadar uzat\u0131lmas\u0131n\u0131 sa\u011flayan \u00f6zelliktir. \u00d6rne\u011fin; kullan\u0131labilirlik s\u00fcresi 5 dakika olarak ayarlanan token de\u011ferinin ClockSkew de\u011ferine 3 dakika verilirse e\u011fer ilgili token 5 + 3 = 8 dakika kullan\u0131labilir olacakt\u0131r. Bunun nedeni, aralar\u0131nda zaman fark\u0131 olan farkl\u0131 lokasyonlardaki sunucularda yay\u0131n yapan bir uygulama \u00fczerinde elde edilen ortak token de\u011ferinin saati ileride olan sunucuda ge\u00e7erlili\u011fini daha erken yitirmemesi i\u00e7in ClockSkew propertysi sayesinde aradaki fark kadar zaman\u0131 tokena eklememiz gerekmektedir. B\u00f6ylece kullan\u0131m s\u00fcresi uzat\u0131lm\u0131\u015f ve t\u00fcm sunucularda token de\u011feri adil kullan\u0131labilir hale getirilmi\u015f olunacakt\u0131r.\n<\/li>\n<\/ul>\n<p>\u015eimdi y\u00f6n\u00fcm\u00fcz\u00fc tekrar yukar\u0131daki kod blo\u011funa \u00e7evirerek 15 ile 22. sat\u0131r aras\u0131ndaki yap\u0131lanlar\u0131 inceleyelim;<\/p>\n<ul>\n<li><em><strong>15. sat\u0131r<\/strong><\/em>; &#8216;ValidateAudience&#8217; ile token \u00fczerinde Audience do\u011frulamas\u0131n\u0131 aktifle\u015ftirdik.<\/li>\n<li><em><strong>16. sat\u0131r<\/strong><\/em>; &#8216;ValidateIssuer&#8217; ile token \u00fczerinde Issuer do\u011frulamas\u0131n\u0131 aktifle\u015ftirdik.<\/li>\n<li><em><strong>17. sat\u0131r<\/strong><\/em>; &#8216;ValidateLifetime&#8217; ile token de\u011ferinin kullan\u0131m s\u00fcresi do\u011frulamas\u0131n\u0131 aktifle\u015ftirdik.<\/li>\n<li><em><strong>18. sat\u0131r<\/strong><\/em>; &#8216;ValidateIssuerSigningKey&#8217; ile token de\u011ferinin bu uygulamaya ait olup olmad\u0131\u011f\u0131n\u0131 anlamam\u0131z\u0131 sa\u011flayan Security Key do\u011frulamas\u0131n\u0131 aktifle\u015ftirdik.<\/li>\n<li><em><strong>19. sat\u0131r<\/strong><\/em>; &#8216;ValidIssuer&#8217; ile uygulamadaki token\u0131n Issuer de\u011ferini belirledik.<\/li>\n<li><em><strong>20. sat\u0131r<\/strong><\/em>; &#8216;ValidAudience&#8217; ile uygulamadaki token\u0131n Audience de\u011ferini belirledik.<\/li>\n<li><em><strong>21. sat\u0131r<\/strong><\/em>; &#8216;IssuerSigningKey&#8217; ile Security Key do\u011frulamas\u0131 i\u00e7in <em>SymmetricSecurityKey<\/em> nesnesi arac\u0131l\u0131\u011f\u0131yla mevcut keyi belirtiyoruz.<\/li>\n<li><em><strong>22. sat\u0131r<\/strong><\/em>; &#8216;ClockSkew&#8217; ile <em>TimeSpan.Zero<\/em> de\u011feri ile token s\u00fcresinin \u00fczerine ekstra bir zaman eklemeksizin s\u0131f\u0131r de\u011ferini belirtiyoruz.<\/li>\n<\/ul>\n<p>Ayriyetten yukar\u0131daki kod blo\u011funda kullan\u0131lan de\u011ferler i\u00e7in Configuration propertysi kullan\u0131lmaktad\u0131r. Yani bu ilgili verileri &#8220;appsettings.json&#8221; dosyas\u0131ndan okuyoruz anlam\u0131na gelmektedir. Haliyle \u00f6rnek uygulamam\u0131zda verileri ilgili dosyada a\u015fa\u011f\u0131daki gibi tuttu\u011fumuzu ifade etmekte fayda var;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n{\r\n  &quot;Logging&quot;: {\r\n    &quot;LogLevel&quot;: {\r\n      &quot;Default&quot;: &quot;Information&quot;,\r\n      &quot;Microsoft&quot;: &quot;Warning&quot;,\r\n      &quot;Microsoft.Hosting.Lifetime&quot;: &quot;Information&quot;\r\n    }\r\n  },\r\n  &quot;AllowedHosts&quot;: &quot;*&quot;,\r\n  &quot;Token&quot;: {\r\n    &quot;Issuer&quot;: &quot;www.myapi.com&quot;,\r\n    &quot;Audience&quot;: &quot;www.bilmemne.com&quot;,\r\n    &quot;SecurityKey&quot;:  &quot;doldur be meyhaneci, bo\u015f kalmas\u0131n kadehim ...&quot;\r\n  }\r\n}\r\n<\/pre>\n<h3>Token Handler S\u0131n\u0131f\u0131n\u0131 Olu\u015fturma<\/h3>\n<p>JWT Token servisini uygulamaya entegre ettikten sonra s\u0131ra Token de\u011ferini olu\u015fturmaktan sorumlu olan Token Handler s\u0131n\u0131f\u0131n\u0131 in\u015fa etmeye geldi.<\/p>\n<p>\u0130lk olarak \u00fcretilecek token ve refresh token de\u011ferlerini ta\u015f\u0131yacak olan &#8220;Token&#8221; modelimizi tasarl\u0131yoruz.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class Token\r\n    {\r\n        public string AccessToken { get; set; }\r\n        public DateTime Expiration { get; set; }\r\n        public string RefreshToken { get; set; }\r\n    }\r\n<\/pre>\n<p>Ard\u0131ndan Token Handler s\u0131n\u0131f\u0131m\u0131z\u0131 in\u015fa edebiliriz;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class TokenHandler\r\n    {\r\n        public IConfiguration Configuration { get; set; }\r\n        public TokenHandler(IConfiguration configuration)\r\n        {\r\n            Configuration = configuration;\r\n        }\r\n        \/\/Token \u00fcretecek metot.\r\n        public TokenAuthentication.Models.Token CreateAccessToken(User user)\r\n        {\r\n            Models.Token tokenInstance = new Models.Token();\r\n\r\n            \/\/Security  Key'in simetri\u011fini al\u0131yoruz.\r\n            SymmetricSecurityKey securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration&#x5B;&quot;Token:SecurityKey&quot;]));\r\n\r\n            \/\/\u015eifrelenmi\u015f kimli\u011fi olu\u015fturuyoruz.\r\n            SigningCredentials signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);\r\n\r\n            \/\/Olu\u015fturulacak token ayarlar\u0131n\u0131 veriyoruz.\r\n            tokenInstance.Expiration = DateTime.Now.AddMinutes(5);\r\n            JwtSecurityToken securityToken = new JwtSecurityToken(\r\n                issuer: Configuration&#x5B;&quot;Token:Issuer&quot;],\r\n                audience: Configuration&#x5B;&quot;Token:Audience&quot;],\r\n                expires: tokenInstance.Expiration,\/\/Token s\u00fcresini 5 dk olarak belirliyorum\r\n                notBefore: DateTime.Now,\/\/Token \u00fcretildikten ne kadar s\u00fcre sonra devreye girsin ayarl\u0131youz.\r\n                signingCredentials: signingCredentials\r\n                );\r\n\r\n            \/\/Token olu\u015fturucu s\u0131n\u0131f\u0131nda bir \u00f6rnek al\u0131yoruz.\r\n            JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();\r\n\r\n            \/\/Token \u00fcretiyoruz.\r\n            tokenInstance.AccessToken = tokenHandler.WriteToken(securityToken);\r\n\r\n            \/\/Refresh Token \u00fcretiyoruz.\r\n            tokenInstance.RefreshToken = CreateRefreshToken();\r\n            return tokenInstance;\r\n        }\r\n\r\n        \/\/Refresh Token \u00fcretecek metot.\r\n        public string CreateRefreshToken()\r\n        {\r\n            byte&#x5B;] number = new byte&#x5B;32];\r\n            using (RandomNumberGenerator random = RandomNumberGenerator.Create())\r\n            {\r\n                random.GetBytes(number);\r\n                return Convert.ToBase64String(number);\r\n            }\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funu incelerseniz e\u011fer access token ile birlikte refresh token de\u011ferlerini \u00fcretecek bir s\u0131n\u0131f tasarlam\u0131\u015f bulunmaktay\u0131z. Burada &#8220;CreateRefreshToken&#8221; metodu i\u00e7erisinde refresh token de\u011feri i\u00e7in &#8220;RandomNumberGenerator&#8221; nesnesinin kullan\u0131ld\u0131\u011f\u0131na dikkatinizi \u00e7ekerim. Alternatif olarak burada isterseniz Guid tipinde bir de\u011fer d\u00f6nebilir yahut farkl\u0131 bir Token de\u011feri olu\u015fturup refresh token olarak kullanabilirsiniz.<\/p>\n<h3>Controller&#8217;lar\u0131n Olu\u015fturulmas\u0131<\/h3>\n<p>\u0130lk olarak kullan\u0131c\u0131lardan gelecek olan login istekleri i\u00e7in &#8220;UserLogin&#8221; view model&#8217;\u0131n\u0131 olu\u015ftural\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class UserLogin\r\n    {\r\n        public string Email { get; set; }\r\n        public string Password { get; set; }\r\n    }\r\n<\/pre>\n<p>Ard\u0131ndan kullan\u0131c\u0131lar taraf\u0131ndan yap\u0131lacak olan kay\u0131t yahut login isteklerini kar\u015f\u0131layacak olan &#8220;Login(Controller).cs&#8221; dosyas\u0131n\u0131 olu\u015ftural\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    &#x5B;ApiController]\r\n    &#x5B;Route(&quot;api\/&#x5B;controller]&quot;)]\r\n    public class LoginController : ControllerBase\r\n    {\r\n        readonly TokenExampleContext _context;\r\n        readonly IConfiguration _configuration;\r\n        public LoginController(TokenExampleContext content, IConfiguration configuration)\r\n        {\r\n            _context = content;\r\n            _configuration = configuration;\r\n        }\r\n        &#x5B;HttpPost(&quot;&#x5B;action]&quot;)]\r\n        public async Task&lt;bool&gt; Create(&#x5B;FromForm]User user)\r\n        {\r\n            _context.Users.Add(user);\r\n            await _context.SaveChangesAsync();\r\n            return true;\r\n        }\r\n        &#x5B;HttpPost(&quot;action&quot;)]\r\n        public async Task&lt;TokenAuthentication.Models.Token&gt; Login(&#x5B;FromForm]UserLogin userLogin)\r\n        {\r\n            User user = await _context.Users.FirstOrDefaultAsync(x =&gt; x.Email == userLogin.Email &amp;&amp; x.Password == userLogin.Password);\r\n            if (user != null)\r\n            {\r\n                \/\/Token \u00fcretiliyor.\r\n                TokenHandler tokenHandler = new TokenHandler(_configuration);\r\n                TokenAuthentication.Models.Token token = tokenHandler.CreateAccessToken(user);\r\n\r\n                \/\/Refresh token Users tablosuna i\u015fleniyor.\r\n                user.RefreshToken = token.RefreshToken;\r\n                user.RefreshTokenEndDate = token.Expiration.AddMinutes(3);\r\n                await _context.SaveChangesAsync();\r\n\r\n                return token;\r\n            }\r\n            return null;\r\n        }\r\n    }\r\n<\/pre>\n<p>Authorization i\u015flemlerini test edebilmek i\u00e7in kullan\u0131c\u0131 isteklerini kar\u015f\u0131layacak &#8220;Test(Controller).cs&#8221; dosyas\u0131n\u0131 olu\u015ftural\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    &#x5B;Authorize]\r\n    &#x5B;ApiController]\r\n    &#x5B;Route(&quot;api\/&#x5B;controller]&quot;)]\r\n    public class TestController : ControllerBase\r\n    {\r\n        public string Index()\r\n        {\r\n            return &quot;Yetkilendirme ba\u015far\u0131l\u0131...&quot;;\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki &#8220;Test(Controller).cs&#8221; s\u0131n\u0131f\u0131n\u0131 incelerseniz e\u011fer &#8220;Authorize&#8221; attribute&#8217;u ile i\u015faretlenerek yetkisiz eri\u015fim engellenir bir hale getirilmi\u015ftir.<\/p>\n<h3>Test Edelim<\/h3>\n<p>S\u0131ra olu\u015fturdu\u011fumuz yap\u0131lanmay\u0131 test etmeye gelmi\u015ftir. T\u00fcm yap\u0131lanmay\u0131 Postman vas\u0131tas\u0131yla test edece\u011fiz.<br \/>\n\u0130lk olarak kullan\u0131c\u0131 olu\u015ftural\u0131m.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-1.png\" alt=\"Asp.NET Core - Token Bazl\u0131 Kimlik Do\u011frulama(JWT)\" width=\"744\" height=\"429\" class=\"aligncenter size-full wp-image-13298\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-1.png 744w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-1-300x173.png 300w\" sizes=\"auto, (max-width: 744px) 100vw, 744px\" \/><\/a><br \/>\nArd\u0131ndan &#8220;Test(Controller)&#8221; controller&#8217;\u0131na bir istekte bulunal\u0131m.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-2.png\" alt=\"Asp.NET Core - Token Bazl\u0131 Kimlik Do\u011frulama(JWT)\" width=\"724\" height=\"290\" class=\"aligncenter size-full wp-image-13301\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-2.png 724w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-2-300x120.png 300w\" sizes=\"auto, (max-width: 724px) 100vw, 724px\" \/><\/a><br \/>\nG\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere ilgili istek neticesinde yetkisiz eri\u015fim yapmaya \u00e7al\u0131\u015f\u0131ld\u0131\u011f\u0131na dair &#8220;401 Unauthorized&#8221; durum kodunu d\u00f6nd\u00fcrmektedir.<\/p>\n<p>O halde token talebinde bulunal\u0131m.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-3.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-3.png\" alt=\"Asp.NET Core - Token Bazl\u0131 Kimlik Do\u011frulama(JWT)\" width=\"838\" height=\"470\" class=\"aligncenter size-full wp-image-13303\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-3.png 838w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-3-300x168.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-3-768x431.png 768w\" sizes=\"auto, (max-width: 838px) 100vw, 838px\" \/><\/a><br \/>\nG\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere token talebi neticesinde bizlere access token, expiration ve refresh token verilerini bar\u0131nd\u0131ran bir JSON verisi d\u00f6nd\u00fcr\u00fclm\u00fc\u015ft\u00fcr. Art\u0131k yapmam\u0131z gereken ilgili access token de\u011ferini kullan\u0131p bir \u00f6nceki &#8220;Test(Controller)&#8221; s\u0131n\u0131f\u0131na istekte bulunmakt\u0131r.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-4.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-4.png\" alt=\"Asp.NET Core - Token Bazl\u0131 Kimlik Do\u011frulama(JWT)\" width=\"767\" height=\"405\" class=\"aligncenter size-full wp-image-13307\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-4.png 767w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-4-300x158.png 300w\" sizes=\"auto, (max-width: 767px) 100vw, 767px\" \/><\/a><\/p>\n<p>Yukar\u0131daki ekran g\u00f6r\u00fcnt\u00fcs\u00fcn\u00fc incelerseniz e\u011fer &#8220;Headers&#8221; kategorisinde &#8220;Authorization&#8221; keyine kar\u015f\u0131l\u0131k verilen &#8220;Bearer {token}&#8221; de\u011feri ile yap\u0131lan istek neticesinde token de\u011ferimizin ba\u015far\u0131l\u0131 bir \u015fekilde do\u011fruland\u0131\u011f\u0131n\u0131 g\u00f6rmekteyiz.<\/p>\n<blockquote><p><strong style=\"color:green;\">Unutmay\u0131n!!! Token bazl\u0131 kimlik do\u011frulama senaryosunda sistemin \u00e7al\u0131\u015fmas\u0131 i\u00e7in &#8220;Startup.cs&#8221; dosyas\u0131ndaki &#8220;Configure&#8221; metodu i\u00e7erisinde &#8216;UseAuthorization&#8217; middleware&#8217;\u0131ndan \u00f6nce &#8216;UseAuthentication&#8217; middleware&#8217;inin \u00e7a\u011fr\u0131lmas\u0131 gerekmektedir. Aksi taktirde token ile yap\u0131lan istekler yine -401 Unauthorized- durum kodu olarak geri d\u00f6necektir.<\/strong><\/p><\/blockquote>\n<h3>Refresh Token Kullan\u0131m\u0131<\/h3>\n<p>\u00dcretilen token de\u011ferinin s\u00fcresi bitmeden yahut bitti\u011finde kullan\u0131c\u0131y\u0131 yeniden login i\u015flemleriyle me\u015fgul etmeden gerekli yetkilendirmeyi tekrar sa\u011flayabilmek i\u00e7in refresh token mekanizmas\u0131n\u0131 kullanaca\u011f\u0131z. Bu mekanizma temelde a\u015fa\u011f\u0131daki gibi bir stratejiden ibarettir.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT.jpg\" alt=\"Asp.NET Core - Token Bazl\u0131 Kimlik Do\u011frulama(JWT)\" width=\"914\" height=\"534\" class=\"aligncenter size-full wp-image-13314\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT.jpg 914w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-300x175.jpg 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-768x449.jpg 768w\" sizes=\"auto, (max-width: 914px) 100vw, 914px\" \/><\/a><br \/>\nYukar\u0131daki g\u00f6r\u00fcnt\u00fcde oldu\u011fu gibi client \u00f6ncelikle gerekli authorization i\u00e7in Authorization Server&#8217;a bir istekte bulunuyor ve bu istek neticesinde &#8220;Access Token&#8221; ile birlikte &#8220;Refresh Token&#8221; de\u011ferlerini elde ediyor. S\u00fcre\u00e7te Resource Server&#8217;a yap\u0131lan t\u00fcm istekler access token arac\u0131l\u0131\u011f\u0131yla ger\u00e7ekle\u015ftiriliyor&#8230; Taa ki access token&#8217;\u0131n s\u00fcresi bitip ge\u00e7ersiz oluncaya kadar&#8230; \u0130\u015fte bu durumda kullan\u0131c\u0131y\u0131 tekrardan login sayfas\u0131na y\u00f6nlendirerek kullan\u0131c\u0131 ad\u0131 ve \u015fifre kontrol\u00fc yapmak yerine kullan\u0131c\u0131ya \u00f6nceden g\u00f6nderilmi\u015f olan refresh token de\u011feri ile Authorization Server&#8217;a bir istekte daha bulunuluyor ve tekrar yeni bir access token \u00fcretilerek hi\u00e7 vakit kaybetmeksizin kullan\u0131c\u0131ya bu yeni token de\u011feri ile kald\u0131\u011f\u0131 yerden devam etme olana\u011f\u0131 tan\u0131n\u0131yor. Tabi bu arada refresh token kullan\u0131ld\u0131ktan sonra ge\u00e7erlili\u011fini yitirerek \u00fcretilen access token de\u011ferine e\u015flik edebilecek yenisi \u00fcretilmi\u015f oluyor.<\/p>\n<p>Bu mant\u0131kta refresh token de\u011ferini kullanarak yeni bir access token \u00fcretebilmek i\u00e7in gerekli istekleri kar\u015f\u0131layacak endpointi a\u015fa\u011f\u0131daki gibi tasarlayabiliriz.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    &#x5B;ApiController]\r\n    &#x5B;Route(&quot;api\/&#x5B;controller]&quot;)]\r\n    public class LoginController : ControllerBase\r\n    {\r\n        readonly TokenExampleContext _context;\r\n        readonly IConfiguration _configuration;\r\n        public LoginController(TokenExampleContext content, IConfiguration configuration)\r\n        {\r\n            _context = content;\r\n            _configuration = configuration;\r\n        }\r\n        .\r\n        .\r\n        .\r\n        &#x5B;HttpGet(&quot;&#x5B;action]&quot;)]\r\n        public async Task&lt;TokenAuthentication.Models.Token&gt; RefreshTokenLogin(&#x5B;FromForm] string refreshToken)\r\n        {\r\n            User user = await _context.Users.FirstOrDefaultAsync(x =&gt; x.RefreshToken == refreshToken);\r\n            if (user != null &amp;&amp; user?.RefreshTokenEndDate &gt; DateTime.Now)\r\n            {\r\n                TokenHandler tokenHandler = new TokenHandler(_configuration);\r\n                TokenAuthentication.Models.Token token = tokenHandler.CreateAccessToken(user);\r\n\r\n                user.RefreshToken = token.RefreshToken;\r\n                user.RefreshTokenEndDate = token.Expiration.AddMinutes(3);\r\n                await _context.SaveChangesAsync();\r\n\r\n                return token;\r\n            }\r\n            return null;\r\n        }\r\n    }\r\n<\/pre>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-5.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-5.png\" alt=\"Asp.NET Core - Token Bazl\u0131 Kimlik Do\u011frulama(JWT)\" width=\"1528\" height=\"399\" class=\"aligncenter size-full wp-image-13321\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-5.png 1528w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-5-300x78.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-5-1024x267.png 1024w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-5-768x201.png 768w\" sizes=\"auto, (max-width: 1528px) 100vw, 1528px\" \/><\/a><br \/>\nG\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere refresh token de\u011feri ile yap\u0131lan istek neticesinde yeni bir access token de\u011feri elde etmekte ve bu de\u011feri a\u015fa\u011f\u0131daki g\u00f6rselde oldu\u011fu gibi devam faaliyetlerimizde kullanabilmekteyiz.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-6.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-6.png\" alt=\"Asp.NET Core - Token Bazl\u0131 Kimlik Do\u011frulama(JWT)\" width=\"509\" height=\"340\" class=\"aligncenter size-full wp-image-13323\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-6.png 509w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/Asp.NET-Core-Token-Bazl\u0131-Kimlik-Do\u011frulamaJWT-6-300x200.png 300w\" sizes=\"auto, (max-width: 509px) 100vw, 509px\" \/><\/a><\/p>\n<p>Evet&#8230; G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere Refresh Token ile birlikte Token Bazl\u0131 Yetkilendirme i\u015flemi bu \u00e7abadan ibarettir diyebiliriz \ud83d\ude42 Sabredipte son noktas\u0131na kadar okudu\u011funuz i\u00e7in te\u015fekk\u00fcr ederim.<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<p>Not : \u00d6rnek projeyi indirmek i\u00e7in <a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/02\/TokenAuthentication.zip\">buraya<\/a> t\u0131klay\u0131n\u0131z.<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, G\u00fcn\u00fcm\u00fcz web uygulamalar\u0131nda veri g\u00fcvenli\u011fini sa\u011flayabilmek i\u00e7in kullan\u0131c\u0131 do\u011frulama y\u00f6ntemleri aras\u0131ndan en etkili ve \u00e7a\u011fda\u015f olanlar\u0131ndan kabul edebilece\u011fimiz Token Bazl\u0131 Kimlik Do\u011frulama y\u00f6ntemi ile sistemsel ve kullan\u0131c\u0131 a\u00e7\u0131s\u0131ndan en az maliyette en y\u00fcksek&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":13314,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2898,3103],"tags":[3133,2758,3148,3136,3145,3140,3137,3135,3138,3142,3134,3144,3143,3146,3139,3141,2406,3147],"class_list":["post-13245","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-asp-net-core-3-0","category-asp-net-core-3-1","tag-access-token","tag-asp-net-core-token","tag-asp-net-core-token-kullanimi","tag-audience","tag-authorization-server","tag-clockskew","tag-issuer","tag-jwtbearerdefaults","tag-lifetime","tag-randomnumbergenerator","tag-refresh-token","tag-refresh-token-nasil-kullanilir","tag-refresh-token-nedir","tag-resource-server","tag-signingkey","tag-symmetricsecuritykey","tag-token-authentication","tag-token-bazli-kimlik-dogrulamasi"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/13245","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=13245"}],"version-history":[{"count":67,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/13245\/revisions"}],"predecessor-version":[{"id":13326,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/13245\/revisions\/13326"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/13314"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=13245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=13245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=13245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}