﻿
{"id":26775,"date":"2023-12-07T20:57:01","date_gmt":"2023-12-07T20:57:01","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=26775"},"modified":"2023-12-07T20:57:45","modified_gmt":"2023-12-07T20:57:45","slug":"net-8-identity-api-endpoints","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/net-8-identity-api-endpoints\/","title":{"rendered":".NET 8 &#8211; Identity API Endpoints"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bu i\u00e7eri\u011fimizde kanaatim odur ki Asp.NET Core a\u00e7\u0131s\u0131ndan .NET 8 ile gelen en g\u00fczel \u00f6zelliklerden birini, <em>Identity API Endpoints<\/em> \u00f6zelli\u011fini inceleyece\u011fiz. Bu \u00f6zellik sayesinde uygulamalar\u0131m\u0131zdaki temel kullan\u0131c\u0131 i\u015flemlerini ger\u00e7ekle\u015ftirdi\u011fimiz <a href=\"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-identity-yazi-dizisi\/\" rel=\"noopener\" target=\"_blank\">Identity mekanizmas\u0131<\/a>n\u0131n art\u0131k daha pratik ve etkin bir \u015fekilde kullan\u0131labildi\u011fini ve \u00f6zellikle API dostu bir alternatif y\u00f6ntemin olabilece\u011fini g\u00f6zlemliyor olaca\u011f\u0131z. O halde buyurun ba\u015flayal\u0131m&#8230;<\/p>\n<h3>Asp.NET Core Identity Nedir?<\/h3>\n<p>Asp.NET Core Identity, geli\u015ftirdi\u011fimiz uygulamalarda kullan\u0131c\u0131 yetkilendirme, kimlik do\u011frulama ve rol y\u00f6netimi sa\u011flayan bir framework&#8217;t\u00fcr. Bu framework sayesinde kullan\u0131c\u0131 kaydetme, giri\u015f yapma, rol atama, \u015fifre s\u0131f\u0131rlama ve Google, Facebook gibi external identity provider&#8217;larla entegrayon vs. gibi temel kimlik y\u00f6netimi i\u015flemlerini kolayl\u0131kla ger\u00e7ekle\u015ftirebilmekteyiz.<\/p>\n<p>Identity mekanizmas\u0131n\u0131n \u00e7ekirde\u011fi <em>Data model<\/em>, <em>Stores<\/em> ve <em>Managers<\/em> olmak \u00fczere \u00fc\u00e7 ana soyutlamaya dayanmaktad\u0131r.<\/p>\n<ul>\n<li><strong><em>Data model<\/em><\/strong><br \/>\nIdentity mekanizmas\u0131nda temel t\u00fcrlerini tarif eden modellerdir. Bu modeller, <code>IdentityUser<\/code> ve <code>IdentityRole<\/code> interface&#8217;leri \u00fczerinden implementasyonlarla sa\u011flan\u0131r.\n<\/li>\n<li><strong><em>Stores<\/em><\/strong><br \/>\nVeri modellerini fiziksel olarak depolamak ve sorgulamak i\u00e7in kullan\u0131lan katmand\u0131r. <code>IUserStore<\/code> ve <code>IRoleStore<\/code> gibi interface&#8217;ler i\u00e7ermektedir.\n<\/li>\n<li><strong><em>Managers<\/em><\/strong><br \/>\nKullan\u0131c\u0131 y\u00f6netimi i\u00e7in Stores \u00fcst\u00fcnde bir service katman\u0131 sa\u011flayan s\u0131n\u0131flard\u0131r. Bu servisler; <code>UserManager<\/code>, <code>RoleManager<\/code> ve <code>SignInManager<\/code>&#8216;d\u0131r.\n<\/li>\n<\/ul>\n<blockquote style=\"color:purple;\"><p><em>Bu g\u00fcne kadar Asp.NET Core mimarisinde mevcut olan Identity mekanizmas\u0131na dair tam teferruatl\u0131 bilgi edinmek i\u00e7in <a href=\"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-identity-yazi-dizisi\/\" rel=\"noopener\" target=\"_blank\">Asp.NET Core Identity \u2013 Yaz\u0131 Dizisi<\/a>ni takip etmenizi \u00f6neririm.<\/em><\/p><\/blockquote>\n<h3>Neden Identity API Endpoint&#8217;e \u0130htiyac\u0131m\u0131z Var?<\/h3>\n<p>Identity mekanizmas\u0131n\u0131n data modelleri \u00fczerinden kullan\u0131c\u0131 ile ilgili gerekli modellemeyi h\u0131zl\u0131ca ger\u00e7ekle\u015ftirebiliyor ve y\u00f6netici(managers) s\u0131n\u0131flar\u0131 sayesinde de kullan\u0131c\u0131 i\u015flemlerini rahatl\u0131kla yapabiliyoruz. Ancak bu kolayl\u0131\u011f\u0131n yan\u0131nda; kullan\u0131c\u0131 ekleme, listeleme, oturum a\u00e7ma, \u015fifre yenileme, iki a\u015famal\u0131 do\u011frulama vs. gibi i\u015flemlerin ger\u00e7ekle\u015ftirilebilmesi i\u00e7in de kullan\u0131c\u0131 aray\u00fcz\u00fcn\u00fcn tasarlanmas\u0131 ve bu tasar\u0131mlar\u0131n kodlanmas\u0131 gerekmektedir. Her ne kadar bu tasar\u0131mlar\u0131n h\u0131zl\u0131 bir \u015fekilde halledilebilmesi i\u00e7in Microsoft taraf\u0131ndan belli ba\u015fl\u0131 UI k\u00fct\u00fcphaneleri olu\u015fturulup, hizmetimize sunulmu\u015f olsa da(<span style=\"font-size:12px;\"><a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.AspNetCore.Identity.UI\" rel=\"noopener\" target=\"_blank\">Microsoft.AspNetCore.Identity.UI<\/a><\/span>) bunlar\u0131n \u00f6zelle\u015ftirilebilmesi i\u00e7in de ayr\u0131 bir maliyet durumu s\u00f6z konusu olabilmektedir. T\u00fcm bunlar\u0131n d\u0131\u015f\u0131nda uygulaman\u0131n frontend k\u0131sm\u0131 bir SPA teknolojisine sahipse i\u015fte bu taktirde bu k\u00fct\u00fcphanelerde bir anlam ifade etmemekte ve el mahkum t\u00fcm \u00e7al\u0131\u015fmalar\u0131 manuel bir \u015fekilde ger\u00e7ekle\u015ftirmek mecburiyetindeyiz. Hal b\u00f6yleyken identity API endpoint sayesinde, API&#8217;ler i\u00e7in de identity mekanizmas\u0131n\u0131n nimetlerini olduk\u00e7a h\u0131zl\u0131 ve basit bir \u015fekilde kullan\u0131labilir hale getirebilmekteyiz.<\/p>\n<p>Hele hele, SPA&#8217;ler de token authentication&#8217;\u0131n kullan\u0131ld\u0131\u011f\u0131 senaryolarda s\u0131kl\u0131kla ihtiya\u00e7 duyulan access token de\u011ferini alabilmek bir endpoint&#8217;e istek g\u00f6ndermek gibi olduk\u00e7a basit bir hale getirilmi\u015f vaziyettedir. Evet, identity API endpoint \u00f6zelli\u011fini kulland\u0131\u011f\u0131m\u0131z taktirde username ve password bilgileri e\u015fli\u011finde a\u015fa\u011f\u0131daki gibi bir iste\u011fin yap\u0131lmas\u0131 g\u00f6rseldeki gibi bir JSON yan\u0131t\u0131n\u0131n h\u0131zl\u0131ca al\u0131nmas\u0131n\u0131 sa\u011flayacakt\u0131r.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n$url = &quot;https:\/\/localhost:7196\/myapp\/login&quot;\r\n$headers = @{\r\n    &quot;Content-Type&quot; = &quot;application\/json&quot;\r\n}\r\n\r\n$body = @{\r\n    email    = &quot;gyildizmail@gmail.com&quot;\r\n    password = &quot;1q2w3e4r'S&quot;\r\n} | ConvertTo-Json\r\n\r\n$response = Invoke-WebRequest -Uri $url -Method Post -Headers $headers -Body $body\r\n\r\n# \u0130stek sonucunu g\u00f6r\u00fcnt\u00fcle\r\n$response.content\r\n<\/pre>\n<\/div>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2023\/12\/NET-8-Identity-API-Endpoints-2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2023\/12\/NET-8-Identity-API-Endpoints-2.png\" alt=\".NET 8 - Identity API Endpoints\" width=\"435\" height=\"254\" class=\"aligncenter size-full wp-image-26785\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2023\/12\/NET-8-Identity-API-Endpoints-2.png 435w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2023\/12\/NET-8-Identity-API-Endpoints-2-300x175.png 300w\" sizes=\"auto, (max-width: 435px) 100vw, 435px\" \/><\/a><\/p>\n<h3>Identity API&#8217;lar\u0131n Kullan\u0131m\u0131<\/h3>\n<p>Identity API Endpoint mekanizmas\u0131n\u0131 kullanabilmek i\u00e7in \u00f6ncelikle <code>IdentityDbContext<\/code> s\u0131n\u0131f\u0131ndan t\u00fcreyen <code>DbContext<\/code> s\u0131n\u0131f\u0131n\u0131n a\u015fa\u011f\u0131daki gibi tasarlanmas\u0131 gerekmektedir. <\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class AppDbContext : IdentityDbContext&lt;AppUser&gt;\r\n    {\r\n        public AppDbContext(DbContextOptions options) : base(options)\r\n        {\r\n        }\r\n    }\r\n<\/pre>\n<\/div>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class AppUser : IdentityUser\r\n    {\r\n    }\r\n<\/pre>\n<\/div>\n<p>Ard\u0131ndan bu context s\u0131n\u0131f\u0131n\u0131n uygulamaya a\u015fa\u011f\u0131daki gibi yap\u0131land\u0131r\u0131lmas\u0131 gerekmektedir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar builder = WebApplication.CreateBuilder(args);\r\n\r\n.\r\n.\r\n.\r\n\r\nbuilder.Services.AddDbContext&lt;AppDbContext&gt;(options =&gt; options.UseSqlServer(&quot;...&quot;));\r\n\r\nvar app = builder.Build();\r\n<\/pre>\n<\/div>\n<p>Ve son olarak da a\u015fa\u011f\u0131daki talimatlar e\u015fli\u011finde migration olu\u015fturulup, hedef veritaban\u0131na migrate edilmelidir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\ndotnet ef migrations add mig_1\r\ndotnet ef database update\r\n<\/pre>\n<\/div>\n<p>Evet, \u015fimdi identity&#8217;i kullanabilmek i\u00e7in gerekli altyap\u0131 haz\u0131r diyebiliriz.<\/p>\n<p>Bu a\u015famadan sonra <code>AddIdentityApiEndpoints<\/code> metodu e\u015fli\u011finde identity servisleri uygulamaya ekleyebiliriz. Bunun i\u00e7in a\u015fa\u011f\u0131daki gibi yap\u0131land\u0131rma bulunal\u0131m;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nbuilder.Services.AddIdentityApiEndpoints&lt;AppUser&gt;()\r\n                .AddEntityFrameworkStores&lt;AppDbContext&gt;();\r\n<\/pre>\n<\/div>\n<p>Bu yap\u0131land\u0131rma neticesinde; bearer ve cookie authentication yap\u0131land\u0131r\u0131lmakta, temel kullan\u0131c\u0131 i\u015flemlerinden sorumlu olan <code>UserManager<\/code> ile birlikte <code>SignInManager<\/code> ve <code>IEmailSender<\/code> gibi servisler IoC container&#8217;a eklenmektedir.<\/p>\n<p>Ve \u015fimdide de t\u00fcm identity API&#8217;leri uygulamaya ekleyebilmek i\u00e7in <code>MapIdentityApi<\/code> middleware&#8217;ini a\u015fa\u011f\u0131daki gibi \u00e7a\u011f\u0131ral\u0131m;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar app = builder.Build();\r\n.\r\n.\r\n.\r\napp.MapIdentityApi&lt;AppUser&gt;();\r\n\r\napp.Run();\r\n<\/pre>\n<\/div>\n<p>Uygulamay\u0131 bu vaziyette derleyip aya\u011fa kald\u0131r\u0131rsak e\u011fer \u00f6zellikle swagger \u00fczerinde a\u015fa\u011f\u0131daki g\u00f6rselde oldu\u011fu gibi identity API endpoints \u00f6zelli\u011finin getirisi olan t\u00fcm endpoint&#8217;leri g\u00f6rmekteyiz.<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2023\/12\/NET-8-Identity-API-Endpoints.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2023\/12\/NET-8-Identity-API-Endpoints.png\" alt=\".NET 8 - Identity API Endpoints\" width=\"629\" height=\"715\" class=\"aligncenter size-full wp-image-26782\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2023\/12\/NET-8-Identity-API-Endpoints.png 629w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2023\/12\/NET-8-Identity-API-Endpoints-264x300.png 264w\" sizes=\"auto, (max-width: 629px) 100vw, 629px\" \/><\/a>Dikkat ederseniz identity API endpoints \u00f6zelli\u011fi ile kullan\u0131c\u0131 kayd\u0131(register) ve giri\u015fi(login) gibi temel d\u00fczey kullan\u0131c\u0131 i\u015flemlerinin d\u0131\u015f\u0131nda; refresh token, \u015fifremi unuttum(forgotPassword) ve hatta \u00e7ift fakt\u00f6rl\u00fc do\u011frulama(2FA) gibi t\u00fcm davran\u0131\u015flara kar\u015f\u0131l\u0131k gelen API&#8217;ler de hali haz\u0131rda eklenmi\u015f vaziyettedir. E\u011fer ki bu API&#8217;lerin kapsam\u0131n\u0131 farkl\u0131 bir path ile ba\u015flatmak isterseniz a\u015fa\u011f\u0131daki gibi <code>MapGroup<\/code> metoduyla \u00e7al\u0131\u015fma yapman\u0131z gerekmektedir;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\napp.MapGroup(&quot;\/myapp&quot;).MapIdentityApi&lt;AppUser&gt;();\r\n<\/pre>\n<\/div>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2023\/12\/NET-8-Identity-API-Endpoints-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2023\/12\/NET-8-Identity-API-Endpoints-1.png\" alt=\".NET 8 - Identity API Endpoints\" width=\"384\" height=\"592\" class=\"alignleft size-full wp-image-26783\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2023\/12\/NET-8-Identity-API-Endpoints-1.png 384w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2023\/12\/NET-8-Identity-API-Endpoints-1-195x300.png 195w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/><\/a><br \/>\nUnutmamak laz\u0131md\u0131r ki; identity API endpoints de, <a href=\"https:\/\/www.gencayyildiz.com\/blog\/identityserver4-yazi-serisi\/\" rel=\"noopener\" target=\"_blank\">IdentityServer<\/a> veya <a href=\"https:\/\/www.gencayyildiz.com\/blog\/openiddict-1-openiddict-nedir-ve-authorization-server-nasil-kurulur\/\" rel=\"noopener\" target=\"_blank\">OpenIddict<\/a> k\u00fct\u00fcphanelerinin yerini almak ama\u00e7lanmam\u0131\u015ft\u0131r! Bilakis sade ve sadece kullan\u0131ld\u0131\u011f\u0131 uygulaman\u0131n kullan\u0131c\u0131 y\u00f6netimi ama\u00e7lanm\u0131\u015ft\u0131r. Ayr\u0131ca machine-to-machine ileti\u015fimden ziyade etkile\u015fime girebilecek olan ger\u00e7ek kullan\u0131c\u0131lar taraf\u0131ndan kullan\u0131lmak \u00fczere tasarlanm\u0131\u015ft\u0131r. Yani anlayaca\u011f\u0131n\u0131z basit bir backend taraf\u0131ndan beslenen SPA senaryolar\u0131ndaki kullan\u0131c\u0131 ve rol i\u015flemleri i\u00e7in identity API endpoint kolay bir se\u00e7imdir diyebiliriz.<\/p>\n<h3>Kullan\u0131c\u0131 User &#038; Password Kriterlerini \u00d6zelle\u015ftirme<\/h3>\n<p>Identity API Endpoints \u00f6zelli\u011fi ile gelen hali haz\u0131rdaki user ve password kriterlerine <code>AddIdentityApiEndpoints<\/code> metodu \u00fczerinden a\u015fa\u011f\u0131daki gibi m\u00fcdahalede bulunulabilmektedir.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nbuilder.Services.AddIdentityApiEndpoints&lt;AppUser&gt;(options =&gt;\r\n{\r\n    options.User...     \/\/\ud83d\udc48User'la ilgili \u00f6zelle\u015ftirme\r\n    options.Password... \/\/\ud83d\udc48Password'le ilgili \u00f6zelle\u015ftirme\r\n})\r\n<\/pre>\n<\/div>\n<p>Nihai olarak;<br \/>\nIdentity API Endpoints \u00f6zelli\u011fi sayesinde uygulamalar\u0131m\u0131zda identity mekanizmas\u0131n\u0131 olduk\u00e7a pratik ve etkili bir \u015fekilde kullanabildi\u011fimizi ve bir\u00e7ok backend i\u015fleminden de \u00e7al\u0131\u015fmalar\u0131m\u0131z\u0131 ar\u0131nd\u0131rabildi\u011fimizi tecr\u00fcbe etmi\u015f bulunuyor ve kod maliyeti ile birlikte zamansal a\u00e7\u0131dan da inan\u0131lmaz bir avantaj\u0131n s\u00f6z konusu oldu\u011funu g\u00f6zlemlemi\u015f oluyoruz. \u0130htiya\u00e7 noktalar\u0131nda kullanmay\u0131 heyecanla bekliyor olaca\u011f\u0131m \ud83d\ude42<\/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<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Bu i\u00e7eri\u011fimizde kanaatim odur ki Asp.NET Core a\u00e7\u0131s\u0131ndan .NET 8 ile gelen en g\u00fczel \u00f6zelliklerden birini, Identity API Endpoints \u00f6zelli\u011fini inceleyece\u011fiz. Bu \u00f6zellik sayesinde uygulamalar\u0131m\u0131zdaki temel kullan\u0131c\u0131 i\u015flemlerini ger\u00e7ekle\u015ftirdi\u011fimiz Identity mekanizmas\u0131n\u0131n art\u0131k daha&#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":26539,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4912,3102],"tags":[4915,4985,4984],"class_list":["post-26775","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net-8","category-asp-net-core","tag-net-8","tag-net-8-identity-api-endpoints","tag-identity-api-endpoints"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/26775","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=26775"}],"version-history":[{"count":9,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/26775\/revisions"}],"predecessor-version":[{"id":26787,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/26775\/revisions\/26787"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/26539"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=26775"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=26775"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=26775"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}