{"id":31798,"date":"2025-10-14T04:01:28","date_gmt":"2025-10-14T01:01:28","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/"},"modified":"2025-10-14T04:01:28","modified_gmt":"2025-10-14T01:01:28","slug":"omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/","title":{"rendered":"omniauth-identity v3.1.5 Hanami ROM Entegrasyonu: Kimlik Y\u00f6netiminde Yeni Bir Boyut"},"content":{"rendered":"<p>Modern web uygulamalar\u0131 geli\u015ftirirken kullan\u0131c\u0131 kimlik do\u011frulama, uygulaman\u0131z\u0131n g\u00fcvenli\u011finin temelini olu\u015fturur. Peki, bu s\u00fcreci Hanami ve ROM gibi performans odakl\u0131 ara\u00e7larla entegre ederken kar\u015f\u0131la\u015f\u0131lan zorluklar\u0131 nas\u0131l a\u015far\u0131z? omniauth-identity v3.1.5, bu soruna g\u00fc\u00e7l\u00fc bir yan\u0131t sunarak Hanami ve ROM kullan\u0131c\u0131lar\u0131na sorunsuz bir yerel kimlik do\u011frulama deneyimi vaat ediyor.<\/p>\n<p>G\u00fcn\u00fcm\u00fcz dijital d\u00fcnyas\u0131nda, kullan\u0131c\u0131lar\u0131n ki\u015fisel verilerinin ve uygulamalar\u0131n hassas bilgilerinin korunmas\u0131, herhangi bir web uygulamas\u0131n\u0131n en \u00f6ncelikli konular\u0131ndan biridir. Kimlik do\u011frulama, bir kullan\u0131c\u0131n\u0131n ger\u00e7ekten iddia etti\u011fi ki\u015fi oldu\u011funu do\u011frulama s\u00fcrecidir ve bu s\u00fcre\u00e7, uygulaman\u0131z\u0131n g\u00fcvenlik mimarisinin temel ta\u015flar\u0131ndan birini olu\u015fturur. Yeterince g\u00fc\u00e7l\u00fc olmayan bir kimlik do\u011frulama sistemi, siber sald\u0131rganlar i\u00e7in kolay bir hedef haline gelebilir; bu da veri ihlallerine, itibar kayb\u0131na ve finansal zararlara yol a\u00e7abilir. \u00d6zellikle e-ticaret siteleri, bankac\u0131l\u0131k uygulamalar\u0131 veya ki\u015fisel verilerin yo\u011fun olarak i\u015flendi\u011fi platformlar i\u00e7in, kimlik do\u011frulama mekanizmalar\u0131n\u0131n sa\u011flaml\u0131\u011f\u0131 hayati \u00f6nem ta\u015f\u0131r. Kullan\u0131c\u0131lar, giri\u015f bilgilerini g\u00fcvende tuttu\u011funuzdan emin olmak isterler ve bu g\u00fcveni sa\u011flamak, uygulaman\u0131z\u0131n ba\u015far\u0131s\u0131 i\u00e7in kritik bir fakt\u00f6rd\u00fcr.<\/p>\n<p>Kimlik do\u011frulaman\u0131n kritik olmas\u0131n\u0131n bir di\u011fer nedeni de kullan\u0131c\u0131 deneyimidir. Kullan\u0131c\u0131lar, h\u0131zl\u0131, sezgisel ve sorunsuz bir giri\u015f\/kay\u0131t s\u00fcreci beklerler. Karma\u015f\u0131k veya yava\u015f \u00e7al\u0131\u015fan kimlik do\u011frulama ak\u0131\u015flar\u0131, kullan\u0131c\u0131lar\u0131n uygulaman\u0131z\u0131 terk etmesine neden olabilir. Bu nedenle, g\u00fcvenlikten \u00f6d\u00fcn vermeden kullan\u0131c\u0131 dostu bir deneyim sunmak, geli\u015ftiricilerin \u00fczerinde durmas\u0131 gereken \u00f6nemli bir denge noktas\u0131d\u0131r. Omniauth gibi pop\u00fcler Ruby kimlik do\u011frulama k\u00fct\u00fcphaneleri, farkl\u0131 kimlik sa\u011flay\u0131c\u0131lar\u0131n\u0131 (Google, Facebook, GitHub vb.) tek bir aray\u00fcz alt\u0131nda toplayarak bu karma\u015f\u0131kl\u0131\u011f\u0131 azaltmay\u0131 hedefler. Ancak, her uygulaman\u0131n harici sa\u011flay\u0131c\u0131lara ba\u011fl\u0131 kalmak istemedi\u011fi veya kendi kullan\u0131c\u0131 taban\u0131n\u0131 y\u00f6netmesi gerekti\u011fi senaryolar da mevcuttur. \u0130\u015fte tam da bu noktada, yerel kullan\u0131c\u0131 ad\u0131\/\u015fifre tabanl\u0131 kimlik do\u011frulama \u00e7\u00f6z\u00fcmleri devreye girer. omniauth-identity, bu yerel kimlik do\u011frulama ihtiyac\u0131n\u0131 Omniauth ekosistemi i\u00e7inde kar\u015f\u0131layarak, geli\u015ftiricilere tan\u0131d\u0131k bir API ve esnek bir yap\u0131 sunar. Bu, uygulaman\u0131z\u0131n hem g\u00fcvenli\u011fini art\u0131r\u0131rken hem de kullan\u0131c\u0131lar i\u00e7in ki\u015fiselle\u015ftirilmi\u015f bir deneyim sunmas\u0131na olanak tan\u0131r. Ruby on Rails veya Hanami gibi modern web framework&#8217;leri ile geli\u015ftirilen uygulamalarda, bu t\u00fcr \u00e7\u00f6z\u00fcmlerin entegrasyonu, geli\u015ftirme h\u0131z\u0131n\u0131 art\u0131rman\u0131n yan\u0131 s\u0131ra, uygulaman\u0131n uzun vadeli s\u00fcrd\u00fcr\u00fclebilirli\u011fi i\u00e7in de b\u00fcy\u00fck \u00f6nem ta\u015f\u0131r.<\/p>\n<div class=\"expert-tip\">\n  Uzman \u0130pucu: Kimlik do\u011frulama mekanizmalar\u0131n\u0131z\u0131 tasarlarken, gelecekteki g\u00fcvenlik tehditlerini ve \u00f6l\u00e7eklenebilirlik ihtiya\u00e7lar\u0131n\u0131 g\u00f6z \u00f6n\u00fcnde bulundurun. \u015eifrelerin tek y\u00f6nl\u00fc hash&#8217;lenmesi, brute-force korumas\u0131 ve oturum g\u00fcvenli\u011fi gibi temel pratikleri her zaman uygulay\u0131n.\n<\/div>\n<h2 id=\"omniauth-identity-v315-nedir-ve-neden-onemli\">omniauth-identity v3.1.5 Nedir ve Neden \u00d6nemli?<\/h2>\n<p><code>omniauth-identity<\/code>, pop\u00fcler Omniauth Ruby kimlik do\u011frulama \u00e7er\u00e7evesinin bir stratejisidir. Temel olarak, uygulamalar\u0131n harici kimlik sa\u011flay\u0131c\u0131lara (OAuth, OpenID Connect gibi) ba\u011f\u0131ml\u0131 olmadan, kendi veritabanlar\u0131nda saklad\u0131klar\u0131 kullan\u0131c\u0131 ad\u0131 ve \u015fifre bilgilerini kullanarak yerel kimlik do\u011frulama yapmalar\u0131n\u0131 sa\u011flar. Yani, &#8220;email ve \u015fifre ile giri\u015f yap&#8221; \u00f6zelli\u011fini kolayca uygulaman\u0131za entegre etmenize olanak tan\u0131r. Bu, \u00f6zellikle bir &#8220;ana hesap&#8221; sistemine ihtiya\u00e7 duyan veya kullan\u0131c\u0131 verilerini kendi kontrol\u00fcnde tutmak isteyen uygulamalar i\u00e7in vazge\u00e7ilmez bir ara\u00e7t\u0131r. Geli\u015ftiricilerin, kimlik do\u011frulama mant\u0131\u011f\u0131n\u0131 s\u0131f\u0131rdan yazma k\u00fclfetinden kurtularak, g\u00fcvenli\u011fi kan\u0131tlanm\u0131\u015f bir k\u00fct\u00fcphanenin avantajlar\u0131ndan faydalanmas\u0131n\u0131 sa\u011flar.<\/p>\n<p>Peki, <code>omniauth-identity v3.1.5<\/code>&#8216;i \u00f6zel k\u0131lan nedir? Bu s\u00fcr\u00fcm, Hanami ve ROM (Ruby Object Mapper) ekosistemlerine resmi deste\u011fini duyurarak \u00f6nemli bir ad\u0131m atm\u0131\u015ft\u0131r. Daha \u00f6nceki s\u00fcr\u00fcmler genellikle Rails&#8217;in ActiveRecord ORM&#8217;i ile sorunsuz \u00e7al\u0131\u015facak \u015fekilde tasarlanm\u0131\u015ft\u0131. Ancak Ruby ekosistemi geni\u015fledik\u00e7e, Hanami gibi daha hafif ve performans odakl\u0131 framework&#8217;ler ile ROM gibi ba\u011f\u0131ms\u0131z ve esnek veri eri\u015fim katmanlar\u0131 pop\u00fclerlik kazanmaya ba\u015flad\u0131. Bu durum, bu yeni nesil ara\u00e7lar\u0131 kullanan geli\u015ftiriciler i\u00e7in yerel kimlik do\u011frulama entegrasyonunda bo\u015fluklar yarat\u0131yordu. <code>v3.1.5<\/code> ile birlikte, Hanami ve ROM kullan\u0131c\u0131lar\u0131 art\u0131k bu bo\u015flu\u011fu doldurabiliyorlar. Bu destek, geli\u015ftiricilerin kendi tercihlerine g\u00f6re teknoloji y\u0131\u011f\u0131n\u0131 olu\u015ftururken kimlik do\u011frulama konusunda taviz vermemelerini sa\u011fl\u0131yor.<\/p>\n<p>Bu entegrasyonun \u00f6nemi birka\u00e7 noktada kendini g\u00f6sterir: \u0130lk olarak, Hanami ve ROM, mod\u00fclerlik, performans ve test edilebilirli\u011fe odaklanan projelerde s\u0131kl\u0131kla tercih edilir. <code>omniauth-identity<\/code>&#8216;nin bu ara\u00e7larla uyumlu \u00e7al\u0131\u015fmas\u0131, bu projelerde kimlik do\u011frulama katman\u0131n\u0131n da ayn\u0131 felsefeyle, yani esnek, bak\u0131m\u0131 kolay ve performansl\u0131 bir \u015fekilde in\u015fa edilebilece\u011fi anlam\u0131na gelir. \u0130kinci olarak, ROM&#8217;un ORM ba\u011f\u0131ms\u0131z yap\u0131s\u0131, geli\u015ftiricilere farkl\u0131 veritaban\u0131 t\u00fcrleriyle (PostgreSQL, MySQL vb.) \u00e7al\u0131\u015fma esnekli\u011fi sunarken, <code>omniauth-identity<\/code> bu yap\u0131y\u0131 do\u011frudan destekleyerek adaptasyon maliyetini d\u00fc\u015f\u00fcr\u00fcr. \u00dc\u00e7\u00fcnc\u00fc olarak, Ruby on Rails&#8217;e alternatif arayan veya daha minimalist bir yakla\u015f\u0131m\u0131 benimseyen geli\u015ftiriciler i\u00e7in, bu s\u00fcr\u00fcm, Hanami ve ROM ile birlikte sa\u011flam bir kimlik do\u011frulama \u00e7\u00f6z\u00fcm\u00fcne sahip olmalar\u0131n\u0131 sa\u011flar. Bu, Ruby ekosisteminin \u00e7e\u015fitlili\u011fini ve esnekli\u011fini vurgulayan, geli\u015ftiriciler i\u00e7in olduk\u00e7a de\u011ferli bir geli\u015fmedir. K\u0131sacas\u0131, <code>omniauth-identity v3.1.5<\/code>, modern Ruby web uygulamalar\u0131nda yerel kimlik do\u011frulama ihtiya\u00e7lar\u0131n\u0131, Hanami ve ROM gibi yenilik\u00e7i ara\u00e7larla m\u00fckemmel bir uyum i\u00e7inde kar\u015f\u0131layan bir k\u00f6pr\u00fc g\u00f6revi g\u00f6r\u00fcr.<\/p>\n<h3 id=\"hanami-ve-rom-gelistiriciler-icin-neler-sunuyor\">Hanami ve ROM: Geli\u015ftiriciler \u0130\u00e7in Neler Sunuyor?<\/h3>\n<p>Hanami ve ROM, Ruby ekosisteminde son y\u0131llarda pop\u00fclerlik kazanan iki \u00f6nemli projedir ve her ikisi de geleneksel Rails yakla\u015f\u0131m\u0131na alternatif arayan geli\u015ftiricilere hitap eder. Hanami, \u00f6zellikle temiz mimari, test edilebilirlik ve performans odakl\u0131 bir web framework&#8217;\u00fcd\u00fcr. Mod\u00fcler yap\u0131s\u0131 sayesinde, uygulaman\u0131n farkl\u0131 katmanlar\u0131 aras\u0131nda kat\u0131 bir ayr\u0131m sa\u011flar; bu da kod taban\u0131n\u0131n daha anla\u015f\u0131l\u0131r, bak\u0131m\u0131 kolay ve \u00f6l\u00e7eklenebilir olmas\u0131n\u0131 sa\u011flar. Her bir uygulama bile\u015feni (router, controller, view, model) ba\u011f\u0131ms\u0131z bir Ruby nesnesi olarak i\u015flev g\u00f6r\u00fcr, bu da birim testlerini \u00e7ok daha kolay hale getirir. Hanami, ba\u011f\u0131ml\u0131l\u0131k enjeksiyonunu do\u011fal bir \u015fekilde destekleyerek bile\u015fenler aras\u0131ndaki ba\u011f\u0131ml\u0131l\u0131klar\u0131 y\u00f6netmeyi basitle\u015ftirir. Bu yakla\u015f\u0131m, \u00f6zellikle b\u00fcy\u00fck ve karma\u015f\u0131k kurumsal uygulamalar geli\u015ftiren ekipler i\u00e7in \u00f6nemli avantajlar sunar, \u00e7\u00fcnk\u00fc uygulaman\u0131n her bir par\u00e7as\u0131n\u0131n tek bir sorumlulu\u011fu olmas\u0131n\u0131 sa\u011flar. Ayr\u0131ca, performans konusunda da olduk\u00e7a iddial\u0131d\u0131r, daha az kaynak t\u00fcketir ve daha h\u0131zl\u0131 yan\u0131t s\u00fcreleri sunar.<\/p>\n<p>ROM (Ruby Object Mapper) ise, ActiveRecord gibi monolitik ORM&#8217;lere alternatif olarak ortaya \u00e7\u0131kan, ba\u011f\u0131ms\u0131z bir veri eri\u015fim katman\u0131d\u0131r. ROM, veritaban\u0131 etkile\u015fimlerini daha i\u015flevsel ve veri odakl\u0131 bir yakla\u015f\u0131mla ele al\u0131r. Temel olarak, veritaban\u0131 \u015femas\u0131na dayal\u0131 tan\u0131mlanm\u0131\u015f &#8220;relation&#8221; (ili\u015fki) nesneleri, i\u015f mant\u0131\u011f\u0131ndan ayr\u0131 &#8220;repository&#8221; (depo) nesneleri ve veritaban\u0131ndan d\u00f6nen verileri temsil eden &#8220;struct&#8221; veya &#8220;entity&#8221; (varl\u0131k) nesnelerinden olu\u015fur. Bu ayr\u0131m, i\u015f mant\u0131\u011f\u0131n\u0131n veritaban\u0131 detaylar\u0131ndan ba\u011f\u0131ms\u0131z kalmas\u0131n\u0131 sa\u011flar ve bu da uygulamay\u0131 farkl\u0131 veritaban\u0131 sistemlerine (\u00f6rne\u011fin, PostgreSQL&#8217;den MySQL&#8217;e ge\u00e7i\u015f) daha kolay adapte etmenize olanak tan\u0131r. ROM&#8217;un bir di\u011fer g\u00fc\u00e7l\u00fc y\u00f6n\u00fc de, karma\u015f\u0131k sorgular\u0131 daha okunabilir ve y\u00f6netilebilir bir \u015fekilde olu\u015fturabilmesidir. Ayr\u0131ca, immutability (de\u011fi\u015fmezlik) prensibine \u00f6nem verir; bu da verilerin beklenmedik \u015fekillerde de\u011fi\u015ftirilmesini zorla\u015ft\u0131rarak hatalar\u0131 azaltmaya yard\u0131mc\u0131 olur. Hanami ile ROM&#8217;un birlikte kullan\u0131lmas\u0131, \u00f6zellikle veri yo\u011fun uygulamalarda, hem performans hem de mimari tutarl\u0131l\u0131k a\u00e7\u0131s\u0131ndan g\u00fc\u00e7l\u00fc bir kombinasyon sunar. omniauth-identity&#8217;nin bu iki ekosistemi desteklemesi, geli\u015ftiricilerin g\u00fcvenlik katmanlar\u0131n\u0131 da bu modern, esnek ve performans odakl\u0131 yakla\u015f\u0131mla entegre edebilmesini sa\u011flayarak, ba\u015ftan sona tutarl\u0131 bir geli\u015ftirme deneyimi sunar.<\/p>\n<h2 id=\"omniauth-identity-v315-hanami-projenize-nasil-entegre-edilir-adim-adim-kilavuz\">omniauth-identity v3.1.5 Hanami Projenize Nas\u0131l Entegre Edilir? (Ad\u0131m Ad\u0131m K\u0131lavuz)<\/h2>\n<p>Diyelim ki yeni bir Hanami uygulamas\u0131nda kullan\u0131c\u0131 giri\u015fi ve kayd\u0131 gibi temel kimlik do\u011frulama \u00f6zelliklerini hayata ge\u00e7irmek istiyorsunuz. Bu s\u00fcre\u00e7te <code>omniauth-identity v3.1.5<\/code> ve ROM&#8217;u nas\u0131l kullanaca\u011f\u0131m\u0131za dair ad\u0131m ad\u0131m bir k\u0131lavuz olu\u015ftural\u0131m. Bu vaka analizi, kullan\u0131c\u0131lar\u0131n e-posta ve \u015fifre ile sisteme kay\u0131t olup giri\u015f yapabilece\u011fi basit bir web uygulamas\u0131 \u00fczerine odaklanacakt\u0131r.<\/p>\n<h3>Ad\u0131m 1: Gemfile&#8217;a Gerekli K\u00fct\u00fcphaneleri Ekleme<\/h3>\n<p>\u0130lk olarak, Hanami projenizin <code>Gemfile<\/code> dosyas\u0131na <code>omniauth<\/code>, <code>omniauth-identity<\/code>, ROM ve veritaban\u0131 ba\u011fda\u015ft\u0131r\u0131c\u0131n\u0131z\u0131 (\u00f6rne\u011fin <code>rom-sql<\/code> ve <code>pg<\/code> PostgreSQL i\u00e7in) eklemeniz gerekir. Bu k\u00fct\u00fcphaneler, kimlik do\u011frulama ve veritaban\u0131 etkile\u015fimi i\u00e7in temel yap\u0131 ta\u015flar\u0131n\u0131 sa\u011flayacakt\u0131r.<\/p>\n<pre><code class=\"language-ruby\">\n# Gemfile\n\ngem 'hanami', '~> 2.1'\ngem 'hanami-webconsole', '~> 2.1' # Geli\u015ftirme ortam\u0131 i\u00e7in\ngem 'omniauth', '~> 2.1'\ngem 'omniauth-identity', '~> 3.1.5'\ngem 'bcrypt', '~> 3.1' # \u015eifre hash'leme i\u00e7in\n\n# ROM stack'i\ngem 'rom', '~> 5.0'\ngem 'rom-sql', '~> 5.0'\ngem 'pg', '~> 1.4' # PostgreSQL i\u00e7in, farkl\u0131 bir DB kullan\u0131yorsan\u0131z de\u011fi\u015ftirin\n\ngroup :development, :test do\n  gem 'hanami-rspec', '~> 2.1'\nend\n<\/pre>\n<p><\/code><\/p>\n<p>De\u011fi\u015fiklikleri kaydettikten sonra terminalde <code>bundle install<\/code> komutunu \u00e7al\u0131\u015ft\u0131rarak ba\u011f\u0131ml\u0131l\u0131klar\u0131 y\u00fckleyin.<\/p>\n<h3>Ad\u0131m 2: Hanami Uygulamas\u0131nda OmniAuth Yap\u0131land\u0131rmas\u0131<\/h3>\n<p>OmniAuth'u Hanami uygulaman\u0131za entegre etmek i\u00e7in \u00f6ncelikle bir OmniAuth yap\u0131land\u0131rma dosyas\u0131 olu\u015fturman\u0131z ve bunu Hanami uygulaman\u0131z\u0131n middleware'ine eklemeniz gerekir. Genellikle bu, <code>config\/environment.rb<\/code> dosyas\u0131 i\u00e7inde yap\u0131l\u0131r veya ayr\u0131 bir initializer dosyas\u0131na ta\u015f\u0131nabilir.<\/p>\n<pre><code class=\"language-ruby\">\n# config\/environment.rb\nrequire \"hanami\/application\"\nrequire \"hanami\/action\"\nrequire \"hanami\/action\/session\"\nrequire \"omniauth\"\nrequire \"omniauth-identity\"\n\nmodule MyHanamiApp\n  class Application < Hanami::Application\n    config.routes do\n      # OmniAuth callback rotalar\u0131n\u0131 ekleyin\n      post \"\/auth\/identity\/callback\", to: \"authentication.callback\"\n      get \"\/auth\/identity\/callback\", to: \"authentication.callback\"\n      get \"\/auth\/:provider\/callback\", to: \"authentication.callback\"\n      post \"\/auth\/:provider\/callback\", to: \"authentication.callback\"\n      get \"\/auth\/failure\", to: \"authentication.failure\"\n\n      # Di\u011fer rotalar\u0131n\u0131z\n      get \"\/\", to: \"home.index\"\n      get \"\/login\", to: \"authentication.new\"\n      post \"\/login\", to: \"authentication.create\"\n      get \"\/register\", to: \"registration.new\"\n      post \"\/register\", to: \"registration.create\"\n      get \"\/logout\", to: \"authentication.destroy\"\n    end\n\n    config.middleware.use :session, { secret: ENV[\"APP_SECRET\"] } # Oturum y\u00f6netimi i\u00e7in\n    config.middleware.use OmniAuth::Builder do\n      provider :identity, model: 'MyHanamiApp::IdentityRepository' # Identity modelinizin yolu\n    end\n  end\nend\n<\/pre>\n<p><\/code><\/p>\n<p><code>MyHanamiApp::IdentityRepository<\/code> k\u0131sm\u0131na dikkat edin; bu, OmniAuth'un kullan\u0131c\u0131lar\u0131 aramak ve do\u011frulamak i\u00e7in kullanaca\u011f\u0131 ROM repository s\u0131n\u0131f\u0131n\u0131z\u0131n ad\u0131n\u0131 belirtir. <code>ENV[\"APP_SECRET\"]<\/code>, oturum g\u00fcvenli\u011fi i\u00e7in g\u00fc\u00e7l\u00fc, rastgele bir s\u0131r olmal\u0131d\u0131r.<\/p>\n<h3>Ad\u0131m 3: ROM Deposu ve Varl\u0131klar\u0131 Tan\u0131mlama (Identity Model)<\/h3>\n<p>\u015eimdi OmniAuth'un kullanaca\u011f\u0131 <code>Identity<\/code> varl\u0131\u011f\u0131n\u0131 ve repository'sini ROM ile tan\u0131mlayal\u0131m. Bu, veritaban\u0131 etkile\u015fimini y\u00f6netecek katmand\u0131r.<\/p>\n<pre><code class=\"language-ruby\">\n# app\/relations\/identities.rb\nmodule MyHanamiApp\n  module Relations\n    class Identities < Hanami::ROM::Relation\n      schema(:identities, infer: true) do\n        attribute :id, Types::Integer\n        attribute :email, Types::String\n        attribute :password_digest, Types::String\n        attribute :created_at, Types::Time\n        attribute :updated_at, Types::Time\n\n        primary_key :id\n        index :email, unique: true\n      end\n    end\n  end\nend\n\n# app\/entities\/identity.rb\nrequire 'hanami\/entity'\nrequire 'bcrypt'\n\nmodule MyHanamiApp\n  module Entities\n    class Identity < Hanami::Entity\n      # \u015eifre do\u011frulama y\u00f6ntemi\n      def authenticate(unencrypted_password)\n        BCrypt::Password.new(password_digest) == unencrypted_password\n      end\n\n      # \u015eifreyi g\u00fcvenli bir \u015fekilde hash'lemek i\u00e7in yard\u0131mc\u0131 y\u00f6ntem\n      def password=(unencrypted_password)\n        self.password_digest = BCrypt::Password.create(unencrypted_password)\n      end\n    end\n  end\nend\n\n# app\/repositories\/identity_repository.rb\nrequire 'hanami\/repository'\nrequire 'bcrypt'\n\nmodule MyHanamiApp\n  class IdentityRepository < Hanami::Repository\n    relations :identities\n    struct_namespace MyHanamiApp::Entities\n\n    def find_by_email(email)\n      identities.where(email: email).one\n    end\n\n    def create_with_password(attrs)\n      # \u015eifreyi hash'lemeden \u00f6nce email'i k\u00fc\u00e7\u00fck harfe \u00e7evirme gibi \u00f6n i\u015flemler yapabilirsiniz.\n      attrs[:password_digest] = BCrypt::Password.create(attrs.delete(:password))\n      identities.changeset(:create, attrs).commit\n    end\n\n    # OmniAuth taraf\u0131ndan kullan\u0131lacak bir \"find_or_create\" benzeri metot\n    # omniauth-identity bu metodu varsay\u0131lan olarak bekler\n    def self.find_for_identity(auth_hash)\n      repo = new # Yeni bir repository \u00f6rne\u011fi olu\u015ftur\n      email = auth_hash[:info][:email]\n      identity = repo.find_by_email(email)\n\n      unless identity\n        # Yeni bir Identity kayd\u0131 olu\u015ftur\n        # Burada \u015fifre de hash'lenmeli, bu genellikle registration controller'\u0131nda yap\u0131l\u0131r\n        # Ancak omniauth-identity'nin varsay\u0131lan beklentisi, bu y\u00f6ntemin hem bulup hem de olu\u015fturabilmesidir.\n        # Basit bir \u00f6rnek i\u00e7in sadece bulma veya nil d\u00f6nd\u00fcrme yap\u0131yoruz.\n        # Ger\u00e7ek uygulamada, auth_hash'ten gelen bir \u015fifre yoksa (identity stratejisinde genellikle olmaz)\n        # burada bir hata f\u0131rlat\u0131l\u0131r veya farkl\u0131 bir ak\u0131\u015f tetiklenir.\n        # \u00d6rnekte basit tutmak i\u00e7in sadece bulma veya nil d\u00f6nme yap\u0131yoruz.\n        # As\u0131l kay\u0131t i\u015flemi <code>Registration::Create<\/code> aksiyonunda olacak.\n        nil\n      else\n        identity\n      end\n    end\n\n    def self.authenticate(email, password)\n      repo = new\n      identity = repo.find_by_email(email)\n      identity if identity&.authenticate(password)\n    end\n  end\nend\n<\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki kodda, <code>Identities<\/code> ili\u015fkisi veritaban\u0131 tablosunu, <code>Identity<\/code> entity'si veritaban\u0131ndan d\u00f6nen veriyi ve <code>IdentityRepository<\/code> ise veritaban\u0131 i\u015flemlerini y\u00f6neten katman\u0131 temsil eder. \u00d6zellikle <code>IdentityRepository.authenticate<\/code> metodu, OmniAuth'un kimlik do\u011frulama s\u0131ras\u0131nda \u00e7a\u011f\u0131raca\u011f\u0131 ana noktad\u0131r.<\/p>\n<h3>Ad\u0131m 4: Kimlik Do\u011frulama Aksiyonlar\u0131 ve G\u00f6r\u00fcn\u00fcmleri Olu\u015fturma<\/h3>\n<p>Son olarak, kullan\u0131c\u0131lar\u0131n kay\u0131t olabilece\u011fi, giri\u015f yapabilece\u011fi ve \u00e7\u0131k\u0131\u015f yapabilece\u011fi aksiyonlar\u0131 (controller) ve g\u00f6r\u00fcn\u00fcmleri olu\u015fturmal\u0131y\u0131z. Ayr\u0131ca OmniAuth'un geri d\u00f6n\u00fc\u015f (callback) noktas\u0131n\u0131 da ele almal\u0131y\u0131z.<\/p>\n<pre><code class=\"language-ruby\">\n# app\/actions\/authentication\/new.rb (Giri\u015f Formu)\nmodule MyHanamiApp\n  module Actions\n    module Authentication\n      class New < MyHanamiApp::Action\n        include Hanami::Action::Session\n\n        def handle(req, res)\n          res.body = \"\n            <h2>Giri\u015f Yap<\/h2>\n            <form action='\/auth\/identity' method='post'>\n              <label for='email'>E-posta:<\/label>\n              <input type='email' id='email' name='auth_key'><br><br>\n              <label for='password'>\u015eifre:<\/label>\n              <input type='password' id='password' name='password'><br><br>\n              <input type='submit' value='Giri\u015f Yap'>\n            <\/form>\n            <p>Hesab\u0131n\u0131z yok mu? <a href='\/register'>Kay\u0131t Ol<\/a><\/p>\n          \"\n        end\n      end\n    end\n  end\nend\n\n# app\/actions\/authentication\/callback.rb (OmniAuth Geri D\u00f6n\u00fc\u015f)\nmodule MyHanamiApp\n  module Actions\n    module Authentication\n      class Callback < MyHanamiApp::Action\n        include Hanami::Action::Session\n\n        def handle(req, res)\n          auth_hash = req.env['omniauth.auth']\n          identity = MyHanamiApp::IdentityRepository.new.find_by_email(auth_hash.info.email)\n\n          if identity\n            session[:user_id] = identity.id\n            flash[:notice] = \"Ba\u015far\u0131yla giri\u015f yapt\u0131n\u0131z!\"\n            res.redirect('\/') # Anasayfaya y\u00f6nlendir\n          else\n            flash[:alert] = \"Kimlik do\u011frulama ba\u015far\u0131s\u0131z.\"\n            res.redirect('\/login')\n          end\n        end\n      end\n    end\n  end\nend\n\n# app\/actions\/authentication\/failure.rb\nmodule MyHanamiApp\n  module Actions\n    module Authentication\n      class Failure < MyHanamiApp::Action\n        include Hanami::Action::Session\n\n        def handle(req, res)\n          flash[:alert] = \"Kimlik do\u011frulama ba\u015far\u0131s\u0131z oldu: #{req.params[:message]}\"\n          res.redirect('\/login')\n        end\n      end\n    end\n  end\nend\n\n# app\/actions\/authentication\/destroy.rb (\u00c7\u0131k\u0131\u015f Yapma)\nmodule MyHanamiApp\n  module Actions\n    module Authentication\n      class Destroy < MyHanamiApp::Action\n        include Hanami::Action::Session\n\n        def handle(req, res)\n          session[:user_id] = nil\n          flash[:notice] = \"Ba\u015far\u0131yla \u00e7\u0131k\u0131\u015f yapt\u0131n\u0131z.\"\n          res.redirect('\/')\n        end\n      end\n    end\n  end\nend\n\n# app\/actions\/registration\/new.rb (Kay\u0131t Formu)\nmodule MyHanamiApp\n  module Actions\n    module Registration\n      class New < MyHanamiApp::Action\n        def handle(req, res)\n          res.body = \"\n            <h2>Kay\u0131t Ol<\/h2>\n            <form action='\/register' method='post'>\n              <label for='email'>E-posta:<\/label>\n              <input type='email' id='email' name='user[email]'><br><br>\n              <label for='password'>\u015eifre:<\/label>\n              <input type='password' id='password' name='user[password]'><br><br>\n              <label for='password_confirmation'>\u015eifre Tekrar:<\/label>\n              <input type='password' id='password_confirmation' name='user[password_confirmation]'><br><br>\n              <input type='submit' value='Kay\u0131t Ol'>\n            <\/form>\n            <p>Zaten hesab\u0131n\u0131z var m\u0131? <a href='\/login'>Giri\u015f Yap<\/a><\/p>\n          \"\n        end\n      end\n    end\n  end\nend\n\n# app\/actions\/registration\/create.rb (Kay\u0131t \u0130\u015flemi)\nmodule MyHanamiApp\n  module Actions\n    module Registration\n      class Create < MyHanamiApp::Action\n        include Hanami::Action::Session\n\n        def handle(req, res)\n          user_params = req.params[:user]\n\n          if user_params[:password] != user_params[:password_confirmation]\n            flash[:alert] = \"\u015eifreler e\u015fle\u015fmiyor!\"\n            res.redirect('\/register')\n            return\n          end\n\n          repo = MyHanamiApp::IdentityRepository.new\n          existing_identity = repo.find_by_email(user_params[:email])\n\n          if existing_identity\n            flash[:alert] = \"Bu e-posta adresi zaten kay\u0131tl\u0131!\"\n            res.redirect('\/register')\n            return\n          end\n\n          # Yeni bir identity olu\u015ftur\n          identity = repo.create_with_password(email: user_params[:email], password: user_params[:password])\n\n          if identity\n            session[:user_id] = identity.id\n            flash[:notice] = \"Ba\u015far\u0131yla kay\u0131t oldunuz ve giri\u015f yapt\u0131n\u0131z!\"\n            res.redirect('\/')\n          else\n            flash[:alert] = \"Kay\u0131t i\u015flemi ba\u015far\u0131s\u0131z oldu.\"\n            res.redirect('\/register')\n          end\n        rescue ROM::SQL::UniqueConstraintError\n          flash[:alert] = \"Bu e-posta adresi zaten kay\u0131tl\u0131!\"\n          res.redirect('\/register')\n        end\n      end\n    end\n  end\nend\n<\/pre>\n<p><\/code><\/p>\n<p>Bu ad\u0131mlarla, Hanami uygulaman\u0131zda <code>omniauth-identity v3.1.5<\/code> ve ROM kullanarak temel kullan\u0131c\u0131 kayd\u0131 ve giri\u015f ak\u0131\u015f\u0131n\u0131 ba\u015far\u0131yla entegre etmi\u015f olursunuz. Unutmay\u0131n ki bu \u00f6rnekler basitle\u015ftirilmi\u015f HTML i\u00e7erir ve ger\u00e7ek bir projede Hanami'nin view katman\u0131n\u0131 (Template Engine) kullanman\u0131z daha uygun olacakt\u0131r.<\/p>\n<h2 id=\"rom-ile-veritabani-iliskileri-ve-kimlik-yonetimi-nasil-kurulur\">ROM ile Veritaban\u0131 \u0130li\u015fkileri ve Kimlik Y\u00f6netimi Nas\u0131l Kurulur?<\/h2>\n<p>ROM (Ruby Object Mapper), veritaban\u0131 etkile\u015fimleri i\u00e7in g\u00fc\u00e7l\u00fc ve esnek bir yap\u0131 sunar. <code>omniauth-identity<\/code> ile entegrasyonda, ROM'un sa\u011flad\u0131\u011f\u0131 bu yap\u0131 sayesinde kimlik verilerini y\u00f6netmek olduk\u00e7a d\u00fczenli hale gelir. ROM, veritaban\u0131 \u015femas\u0131, ili\u015fkiler (relations) ve veri eri\u015fim katman\u0131 (repositories) aras\u0131nda net bir ayr\u0131m yapar. Bu, kimlik y\u00f6netimi gibi kritik bir alanda kodun daha mod\u00fcler, test edilebilir ve s\u00fcrd\u00fcr\u00fclebilir olmas\u0131n\u0131 sa\u011flar.<\/p>\n<h3>Identity \u015eemas\u0131 ve \u0130li\u015fkileri Tan\u0131mlama<\/h3>\n<p>\u00d6ncelikle, kullan\u0131c\u0131 kimlik bilgilerini saklayaca\u011f\u0131m\u0131z veritaban\u0131 tablosunun \u015femas\u0131n\u0131 ROM'a tan\u0131mlamam\u0131z gerekiyor. Bu genellikle <code>app\/relations\/identities.rb<\/code> dosyas\u0131nda yap\u0131l\u0131r. Burada, <code>identities<\/code> tablosunun hangi s\u00fctunlara sahip olaca\u011f\u0131n\u0131, bu s\u00fctunlar\u0131n veri tiplerini ve k\u0131s\u0131tlamalar\u0131n\u0131 belirtiriz.<\/p>\n<pre><code class=\"language-ruby\">\n# app\/relations\/identities.rb\nmodule MyHanamiApp\n  module Relations\n    class Identities < Hanami::ROM::Relation\n      # <code>schema<\/code> metodu ile veritaban\u0131 \u015femas\u0131n\u0131 tan\u0131ml\u0131yoruz.\n      # <code>infer: true<\/code> kullanmak, mevcut bir tablo varsa s\u00fctunlar\u0131 otomatik alg\u0131lamas\u0131n\u0131 sa\u011flar.\n      # Ancak \u00fcretim ortam\u0131nda veya manuel kontrol i\u00e7in s\u00fctunlar\u0131 a\u00e7\u0131k\u00e7a belirtmek daha g\u00fcvenlidir.\n      schema(:identities, infer: true) do\n        # <code>Types<\/code> mod\u00fcl\u00fc, ROM'un sa\u011flad\u0131\u011f\u0131 zengin tip sistemidir.\n        # Bu tipler, veri do\u011frulama ve d\u00f6n\u00fc\u015f\u00fcm s\u00fcre\u00e7lerini kolayla\u015ft\u0131r\u0131r.\n        attribute :id, Types::Integer\n        attribute :email, Types::String.constrained(format: URI::MailTo::EMAIL_REGEXP) # E-posta format\u0131 k\u0131s\u0131tlamas\u0131\n        attribute :password_digest, Types::String # Hashlenmi\u015f \u015fifre saklan\u0131r\n        attribute :created_at, Types::Time.default { Time.now } # Kay\u0131t tarihi\n        attribute :updated_at, Types::Time.default { Time.now } # G\u00fcncelleme tarihi\n\n        # Birincil anahtar belirtmek, ROM'un kay\u0131tlar\u0131 benzersiz bir \u015fekilde tan\u0131mlamas\u0131na yard\u0131mc\u0131 olur.\n        primary_key :id\n\n        # E-posta adresinin benzersiz olmas\u0131n\u0131 sa\u011flamak i\u00e7in indeks ekliyoruz.\n        # Bu, ayn\u0131 e-posta ile birden fazla kay\u0131t olu\u015fturulmas\u0131n\u0131 engeller.\n        index :email, unique: true\n      end\n\n      # \u0130ste\u011fe ba\u011fl\u0131 olarak, Identity ile di\u011fer ili\u015fkiler tan\u0131mlanabilir.\n      # \u00d6rne\u011fin, bir Identity'nin birden fazla Role'e sahip olmas\u0131:\n      # define_view :with_roles do\n      #   left_join(:roles).select_append { [:roles[:name].as(:role_name)] }\n      # end\n    end\n  end\nend\n<\/pre>\n<p><\/code><\/p>\n<p>Burada <code>Types::String.constrained(format: URI::MailTo::EMAIL_REGEXP)<\/code> gibi ifadelerle, verilerin veritaban\u0131na kaydedilmeden \u00f6nce belirli kurallara uymas\u0131n\u0131 sa\u011flayabiliriz. Bu, uygulaman\u0131n veri b\u00fct\u00fcnl\u00fc\u011f\u00fcn\u00fc sa\u011flamas\u0131 a\u00e7\u0131s\u0131ndan olduk\u00e7a \u00f6nemlidir. <code>password_digest<\/code> s\u00fctunu ise do\u011frudan \u015fifrenin kendisini de\u011fil, kriptografik olarak g\u00fcvenli bir \u015fekilde hashlenmi\u015f halini saklar.<\/p>\n<h3>Identity Varl\u0131\u011f\u0131 (Entity) ve Davran\u0131\u015flar\u0131<\/h3>\n<p>Veritaban\u0131ndan \u00e7ekilen her bir kay\u0131t, ROM taraf\u0131ndan bir varl\u0131k (entity) nesnesine d\u00f6n\u00fc\u015ft\u00fcr\u00fcl\u00fcr. Bu varl\u0131klar, veritaban\u0131 kay\u0131tlar\u0131n\u0131n sadece veri de\u011fil, ayn\u0131 zamanda belirli davran\u0131\u015flar\u0131 da bar\u0131nd\u0131rabilece\u011fi yerlerdir. <code>Identity<\/code> varl\u0131\u011f\u0131m\u0131z i\u00e7in \u015fifre do\u011frulama gibi i\u015f mant\u0131\u011f\u0131n\u0131 burada tan\u0131mlar\u0131z.<\/p>\n<pre><code class=\"language-ruby\">\n# app\/entities\/identity.rb\nrequire 'hanami\/entity'\nrequire 'bcrypt' # \u015eifre hash'leme ve do\u011frulama i\u00e7in\n\nmodule MyHanamiApp\n  module Entities\n    class Identity < Hanami::Entity\n      # <code>authenticate<\/code> metodu, d\u00fcz metin \u015fifreyi al\u0131p,\n      # saklanan hash ile kar\u015f\u0131la\u015ft\u0131rarak kimlik do\u011frulamay\u0131 yapar.\n      def authenticate(unencrypted_password)\n        # <code>BCrypt::Password.new<\/code> ile hashlenmi\u015f \u015fifre nesnesini olu\u015ftururuz.\n        # Bu nesnenin <code>==<\/code> operat\u00f6r\u00fc, d\u00fcz metin \u015fifre ile hash'i otomatik olarak kar\u015f\u0131la\u015ft\u0131r\u0131r.\n        BCrypt::Password.new(password_digest) == unencrypted_password\n      rescue BCrypt::Errors::InvalidHash # Ge\u00e7ersiz hash durumunda hata yakala\n        false\n      end\n\n      # <code>password=<\/code> metodu, \u015fifre atan\u0131rken otomatik olarak hash'leme yapar.\n      # Bu, controller'dan veya repository'den <code>identity.password = &#039;abc&#039;<\/code> \u015feklinde kullan\u0131ld\u0131\u011f\u0131nda\n      # \u015fifrenin do\u011frudan hash'lenip <code>password_digest<\/code>'a atanmas\u0131n\u0131 sa\u011flar.\n      def password=(unencrypted_password)\n        self.password_digest = BCrypt::Password.create(unencrypted_password)\n      end\n    end\n  end\nend\n<\/pre>\n<p><\/code><\/p>\n<p>Bu varl\u0131k, sadece veri tutmakla kalmaz, ayn\u0131 zamanda <code>authenticate<\/code> metodu ile g\u00fcvenlik katman\u0131na katk\u0131da bulunur. <code>password=<\/code> metodu ise, \u015fifre atama i\u015flemini otomatize ederek geli\u015ftiricinin i\u015fini kolayla\u015ft\u0131r\u0131r ve \u015fifrenin her zaman hash'lenmi\u015f olarak kaydedilmesini sa\u011flar.<\/p>\n<h3>Identity Repository ve OmniAuth Entegrasyonu<\/h3>\n<p><code>IdentityRepository<\/code>, veritaban\u0131 ile etkile\u015fim kuran ve belirli i\u015f kurallar\u0131n\u0131 uygulayan bir katmand\u0131r. OmniAuth'un <code>omniauth-identity<\/code> stratejisi, kullan\u0131c\u0131lar\u0131 bulmak ve do\u011frulamak i\u00e7in bu repository'nin belirli metotlar\u0131n\u0131 \u00e7a\u011f\u0131r\u0131r. En kritik metotlar <code>self.find_for_identity(auth_hash)<\/code> ve <code>self.authenticate(email, password)<\/code>'dir.<\/p>\n<pre><code class=\"language-ruby\">\n# app\/repositories\/identity_repository.rb\nrequire 'hanami\/repository'\nrequire 'bcrypt'\n\nmodule MyHanamiApp\n  class IdentityRepository < Hanami::Repository\n    relations :identities # Bu repository'nin hangi ili\u015fkiyi y\u00f6netece\u011fini belirtir\n    struct_namespace MyHanamiApp::Entities # Varl\u0131klar\u0131m\u0131z\u0131n namespace'ini belirtiriz\n\n    # E-posta adresine g\u00f6re bir Identity kayd\u0131 bulur\n    def find_by_email(email)\n      identities.where(email: email.downcase).one # E-postay\u0131 k\u00fc\u00e7\u00fck harfe \u00e7evirerek arama yap\n    end\n\n    # Yeni bir Identity kayd\u0131 olu\u015fturur ve \u015fifreyi hash'ler\n    def create_with_password(attrs)\n      # Gelen attribute'lardan 'password'\u00fc al\u0131p hash'le ve 'password_digest' olarak ata\n      # attrs = { email: 'test@example.com', password: 'password123' }\n      # attrs[:password_digest] = BCrypt::Password.create(attrs.delete(:password))\n      # Sonu\u00e7: { email: 'test@example.com', password_digest: '$2a$12$...'}\n      attrs_for_creation = attrs.dup # attrs'\u0131 de\u011fi\u015ftirmemek i\u00e7in bir kopyas\u0131n\u0131 al\n      attrs_for_creation[:password_digest] = BCrypt::Password.create(attrs_for_creation.delete(:password))\n      attrs_for_creation[:email] = attrs_for_creation[:email].downcase # E-postay\u0131 k\u00fc\u00e7\u00fck harfe \u00e7evir\n\n      identities.changeset(:create, attrs_for_creation).commit\n    end\n\n    # OmniAuth taraf\u0131ndan \u00e7a\u011fr\u0131lan ana metotlardan biri.\n    # auth_hash genellikle kimlik sa\u011flay\u0131c\u0131s\u0131ndan gelen bilgileri i\u00e7erir.\n    # Identity stratejisi i\u00e7in bu genellikle kay\u0131tl\u0131 bir kullan\u0131c\u0131y\u0131 bulmak veya olu\u015fturmak i\u00e7indir.\n    # NOT: omniauth-identity stratejisi genellikle giri\u015f formu submit edildi\u011finde <code>authenticate<\/code> metodunu \u00e7a\u011f\u0131r\u0131r.\n    # <code>find_for_identity<\/code> daha \u00e7ok di\u011fer OmniAuth stratejilerinde (OAuth gibi) kullan\u0131l\u0131r.\n    # Ancak, custom bir identity stratejisi yaz\u0131yorsan\u0131z veya varsay\u0131lan davran\u0131\u015f\u0131 override ediyorsan\u0131z\n    # bu metodu da implemente etmeniz gerekebilir.\n    # Bu senaryoda, do\u011frudan <code>authenticate<\/code> metodunu kullan\u0131yoruz.\n    # Varsay\u0131lan omniauth-identity i\u00e7in bu metot zorunlu de\u011fildir, ancak di\u011fer OmniAuth stratejileriyle uyumluluk i\u00e7in burada b\u0131rak\u0131labilir.\n    def self.find_for_identity(auth_hash)\n      repo = new\n      repo.find_by_email(auth_hash.info.email)\n    end\n\n    # OmniAuth-identity stratejisinin do\u011frudan \u00e7a\u011f\u0131rd\u0131\u011f\u0131 kimlik do\u011frulama metodu.\n    # Kullan\u0131c\u0131 ad\u0131 (email) ve \u015fifreyi al\u0131r ve do\u011frulama yapar.\n    def self.authenticate(email, password)\n      repo = new\n      identity = repo.find_by_email(email) # E-postaya g\u00f6re kullan\u0131c\u0131y\u0131 bul\n      identity if identity&.authenticate(password) # Bulunan kullan\u0131c\u0131n\u0131n \u015fifresini do\u011frula\n    end\n  end\nend\n<\/pre>\n<p><\/code><\/p>\n<p><code>self.authenticate(email, password)<\/code> metodu, <code>omniauth-identity<\/code>'nin \u00e7ekirde\u011fidir. Giri\u015f formundan gelen e-posta ve \u015fifreyi al\u0131r, veritaban\u0131nda ilgili kullan\u0131c\u0131y\u0131 bulur ve ard\u0131ndan <code>Identity<\/code> varl\u0131\u011f\u0131n\u0131n <code>authenticate<\/code> metodunu kullanarak \u015fifreyi do\u011frular. E\u011fer her \u015fey yolundaysa, do\u011frulanm\u0131\u015f <code>Identity<\/code> nesnesi d\u00f6nd\u00fcr\u00fcl\u00fcr, aksi takdirde <code>nil<\/code> d\u00f6nd\u00fcr\u00fcl\u00fcr. Bu, OmniAuth'un kimlik do\u011frulama ak\u0131\u015f\u0131n\u0131n sorunsuz bir \u015fekilde i\u015flemesini sa\u011flar.<\/p>\n<p>ROM ile bu yap\u0131land\u0131rmay\u0131 kurmak, uygulaman\u0131z\u0131n veri eri\u015fim katman\u0131n\u0131 temiz, g\u00fc\u00e7l\u00fc ve ba\u011f\u0131ms\u0131z tutar. Bu sayede, gelecekte farkl\u0131 bir veritaban\u0131 veya ORM kullanma ihtiyac\u0131 do\u011fdu\u011funda bile, kimlik do\u011frulama mant\u0131\u011f\u0131n\u0131z\u0131 ve veritaban\u0131 etkile\u015fimlerinizi daha az \u00e7abayla adapte edebilirsiniz. Bu mod\u00fcler yap\u0131, \u00f6zellikle b\u00fcy\u00fck \u00f6l\u00e7ekli ve uzun \u00f6m\u00fcrl\u00fc projelerde geli\u015ftirme ve bak\u0131m s\u00fcre\u00e7lerini \u00f6nemli \u00f6l\u00e7\u00fcde kolayla\u015ft\u0131r\u0131r.<\/p>\n<h2 id=\"guvenligi-artirma-ve-ileri-duzey-kullanim-senaryolari-nelerdir\">G\u00fcvenli\u011fi Art\u0131rma ve \u0130leri D\u00fczey Kullan\u0131m Senaryolar\u0131 Nelerdir?<\/h2>\n<p><code>omniauth-identity v3.1.5<\/code> ve ROM entegrasyonuyla temel kimlik do\u011frulamas\u0131n\u0131 kurmu\u015f olsak da, modern bir uygulaman\u0131n sadece temel bir giri\u015f\/kay\u0131t sisteminden fazlas\u0131na ihtiyac\u0131 vard\u0131r. G\u00fcvenli\u011fi art\u0131rmak ve kullan\u0131c\u0131 deneyimini zenginle\u015ftirmek i\u00e7in bir dizi ileri d\u00fczey senaryo ve ek g\u00fcvenlik \u00f6nlemleri uygulamak kritik \u00f6neme sahiptir. Kurumsal bir uygulama geli\u015ftiriyorsan\u0131z, bu ek katmanlar uygulaman\u0131z\u0131n dayan\u0131kl\u0131l\u0131\u011f\u0131n\u0131 ve g\u00fcvenilirli\u011fini b\u00fcy\u00fck \u00f6l\u00e7\u00fcde art\u0131racakt\u0131r.<\/p>\n<h3>\u0130ki Fakt\u00f6rl\u00fc Kimlik Do\u011frulama (2FA) Entegrasyonu<\/h3>\n<p>\u0130ki fakt\u00f6rl\u00fc kimlik do\u011frulama, kullan\u0131c\u0131lar\u0131n sadece \u015fifreleriyle de\u011fil, ek bir do\u011frulama ad\u0131m\u0131yla (\u00f6rne\u011fin, SMS kodu, mobil uygulama tabanl\u0131 OTP) kimliklerini kan\u0131tlamalar\u0131n\u0131 gerektirir. Bu, \u015fifre \u00e7al\u0131nsa bile hesab\u0131n g\u00fcvenli\u011fini \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131r\u0131r. Ruby ekosisteminde <code>rotp<\/code> veya <code>devise-two-factor<\/code> gibi gem'ler 2FA uygulamak i\u00e7in kullan\u0131labilir. <code>omniauth-identity<\/code> ile 2FA entegrasyonu, kimlik do\u011frulama ba\u015far\u0131l\u0131 olduktan sonra ikinci bir do\u011frulama ad\u0131m\u0131n\u0131n tetiklenmesiyle sa\u011flanabilir. \u00d6rne\u011fin, kullan\u0131c\u0131 \u015fifresini girdikten sonra, sistem kullan\u0131c\u0131ya bir OTP (One-Time Password) g\u00f6nderir ve bu kodu girmesini ister. Bu ikinci ad\u0131m\u0131n do\u011fruluk kontrol\u00fc, Omniauth'un callback mekanizmas\u0131ndan sonra veya ayr\u0131 bir ara yaz\u0131l\u0131m (middleware) arac\u0131l\u0131\u011f\u0131yla yap\u0131labilir.<\/p>\n<pre><code class=\"language-ruby\">\n# \u00d6rnek: Basit bir 2FA ak\u0131\u015f\u0131 i\u00e7in kontrollerde de\u011fi\u015fiklikler\nmodule MyHanamiApp\n  module Actions\n    module Authentication\n      class Callback < MyHanamiApp::Action\n        include Hanami::Action::Session\n\n        def handle(req, res)\n          auth_hash = req.env['omniauth.auth']\n          identity = MyHanamiApp::IdentityRepository.new.find_by_email(auth_hash.info.email)\n\n          if identity\n            if identity.two_factor_enabled? # Identity varl\u0131\u011f\u0131n\u0131zda 2FA etkin mi kontrol\u00fc\n              session[:temp_user_id] = identity.id # Ge\u00e7ici olarak kullan\u0131c\u0131 ID'sini sakla\n              res.redirect('\/two_factor_auth') # 2FA giri\u015f sayfas\u0131na y\u00f6nlendir\n            else\n              session[:user_id] = identity.id\n              flash[:notice] = \"Ba\u015far\u0131yla giri\u015f yapt\u0131n\u0131z!\"\n              res.redirect('\/')\n            end\n          else\n            flash[:alert] = \"Kimlik do\u011frulama ba\u015far\u0131s\u0131z.\"\n            res.redirect('\/login')\n          end\n        end\n      end\n    end\n  end\nend\n\n# app\/actions\/two_factor_auth\/new.rb\n# ... 2FA giri\u015f formunu g\u00f6ster ...\n\n# app\/actions\/two_factor_auth\/verify.rb\n# ... OTP'yi do\u011frula, ba\u015far\u0131l\u0131ysa session[:user_id] ata ...\n<\/pre>\n<p><\/code><\/p>\n<p>Bu ak\u0131\u015fta, <code>Identity<\/code> varl\u0131\u011f\u0131n\u0131n 2FA durumunu y\u00f6neten ek s\u00fctunlara ve metotlara sahip olmas\u0131 gerekecektir (\u00f6rne\u011fin, <code>two_factor_secret<\/code>, <code>two_factor_enabled?<\/code>).<\/p>\n<h3>\u015eifre S\u0131f\u0131rlama Ak\u0131\u015flar\u0131<\/h3>\n<p>Kullan\u0131c\u0131lar\u0131n \u015fifrelerini unutmalar\u0131 durumunda g\u00fcvenli bir \u015fekilde s\u0131f\u0131rlayabilmeleri i\u00e7in bir mekanizma sunmak elzemdir. Bu genellikle \u015fu ad\u0131mlar\u0131 i\u00e7erir:<\/p>\n<ol>\n<li>Kullan\u0131c\u0131 e-postas\u0131n\u0131 girer.<\/li>\n<li>Sistem, benzersiz, zaman s\u0131n\u0131rl\u0131 bir token olu\u015fturur ve bu token'\u0131 veritaban\u0131nda saklar.<\/li>\n<li>Kullan\u0131c\u0131n\u0131n e-posta adresine bu token'\u0131 i\u00e7eren bir ba\u011flant\u0131 g\u00f6nderilir.<\/li>\n<li>Kullan\u0131c\u0131 ba\u011flant\u0131ya t\u0131klar ve token do\u011frulan\u0131r.<\/li>\n<li>Do\u011fruland\u0131ktan sonra kullan\u0131c\u0131 yeni \u015fifresini belirler.<\/li>\n<\/ol>\n<p>Bu ak\u0131\u015f i\u00e7in, ROM ile yeni bir <code>PasswordResetToken<\/code> ili\u015fkisi tan\u0131mlaman\u0131z ve token olu\u015fturma, do\u011frulama ve silme i\u015flemleri i\u00e7in repository metotlar\u0131 yazman\u0131z gerekecektir. E-posta g\u00f6nderme i\u00e7in <code>hanami-mail<\/code> gibi bir gem kullan\u0131labilir.<\/p>\n<h3>Brute-Force Sald\u0131r\u0131lar\u0131na Kar\u015f\u0131 Koruma (Rate Limiting)<\/h3>\n<p>Defalarca yanl\u0131\u015f \u015fifre denemeleri yapan k\u00f6t\u00fc niyetli kullan\u0131c\u0131lar\u0131 engellemek i\u00e7in h\u0131z s\u0131n\u0131rlamas\u0131 (rate limiting) uygulamak \u00f6nemlidir. Bu, belirli bir s\u00fcre i\u00e7inde belirli bir IP adresinden veya kullan\u0131c\u0131 ad\u0131ndan gelen ba\u015far\u0131s\u0131z giri\u015f denemelerinin say\u0131s\u0131n\u0131 s\u0131n\u0131rlamak anlam\u0131na gelir. Hanami uygulamalar\u0131nda, middleware katman\u0131nda veya giri\u015f aksiyonunda bu t\u00fcr kontrolleri uygulayabilirsiniz. \u00d6rne\u011fin, <code>rack-attack<\/code> gibi bir gem bu t\u00fcr sald\u0131r\u0131lara kar\u015f\u0131 koruma sa\u011flayabilir. E\u011fer belirli say\u0131da ba\u015far\u0131s\u0131z deneme olursa, kullan\u0131c\u0131n\u0131n belirli bir s\u00fcre boyunca giri\u015f yapmas\u0131n\u0131 engelleyebilirsiniz.<\/p>\n<pre><code class=\"language-ruby\">\n# Hanami'de rack-attack kullan\u0131m\u0131 i\u00e7in config\/environment.rb i\u00e7inde \u00f6rnek\n# (Tam kurulum i\u00e7in rack-attack d\u00f6k\u00fcmantasyonuna bak\u0131n\u0131z)\n# config.middleware.use Rack::Attack\n\n# Rack::Attack.throttle('logins\/ip', limit: 5, period: 20.seconds) do |req|\n#   req.ip if req.path == '\/login' && req.post?\n# end\n\n# Rack::Attack.track('failed_logins') do |req|\n#   if req.path == '\/auth\/identity\/callback' && req.post? && req.env['omniauth.auth'].nil?\n#     req.ip\n#   end\n# end\n<\/pre>\n<p><\/code><\/p>\n<h3>Di\u011fer Omniauth Sa\u011flay\u0131c\u0131lar\u0131yla Birle\u015ftirme<\/h3>\n<p><code>omniauth-identity<\/code>, yerel kimlik do\u011frulamas\u0131n\u0131 sa\u011flarken, uygulaman\u0131z\u0131n ayn\u0131 zamanda Google, GitHub, Facebook gibi harici sa\u011flay\u0131c\u0131larla da oturum a\u00e7ma imkan\u0131 sunmas\u0131n\u0131 isteyebilirsiniz. OmniAuth'\u0131n g\u00fcc\u00fc burada ortaya \u00e7\u0131kar. Tek bir \u00e7er\u00e7eve alt\u0131nda birden fazla kimlik sa\u011flay\u0131c\u0131y\u0131 sorunsuz bir \u015fekilde birle\u015ftirebilirsiniz. Bu, kullan\u0131c\u0131lara daha fazla esneklik sunar ve kay\u0131t s\u00fcre\u00e7lerini basitle\u015ftirebilir. Yapman\u0131z gereken, <code>config\/environment.rb<\/code> i\u00e7indeki <code>OmniAuth::Builder<\/code> blo\u011funa di\u011fer sa\u011flay\u0131c\u0131lar\u0131 eklemektir:<\/p>\n<pre><code class=\"language-ruby\">\n# config\/environment.rb i\u00e7inde middleware yap\u0131land\u0131rmas\u0131\nconfig.middleware.use OmniAuth::Builder do\n  provider :identity, model: 'MyHanamiApp::IdentityRepository'\n  provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET']\n  provider :github, ENV['GITHUB_CLIENT_ID'], ENV['GITHUB_CLIENT_SECRET']\nend\n<\/pre>\n<p><\/code><\/p>\n<p>Bu entegrasyon i\u00e7in, kullan\u0131c\u0131lar\u0131n birden fazla kimlik do\u011frulama y\u00f6ntemini (yerel, Google, GitHub) tek bir ana hesapla ili\u015fkilendirebilmesi i\u00e7in <code>User<\/code> modelinizde ek ili\u015fkiler (\u00f6rne\u011fin, <code>User has_many Identities<\/code>) tan\u0131mlaman\u0131z gerekebilir. Bu, bir kullan\u0131c\u0131n\u0131n farkl\u0131 platformlardaki kimliklerini birle\u015ftirerek daha esnek bir y\u00f6netim sa\u011flar.<\/p>\n<h3>Loglama ve \u0130zleme<\/h3>\n<p>Kimlik do\u011frulama olaylar\u0131n\u0131n (ba\u015far\u0131l\u0131\/ba\u015far\u0131s\u0131z giri\u015fler, \u015fifre s\u0131f\u0131rlama talepleri vb.) detayl\u0131 bir \u015fekilde loglanmas\u0131, g\u00fcvenlik denetimi ve olas\u0131 ihlallerin tespiti i\u00e7in hayati \u00f6nem ta\u015f\u0131r. Hanami'nin yerle\u015fik loglama yeteneklerini kullanarak veya harici bir loglama k\u00fct\u00fcphanesi entegre ederek bu olaylar\u0131 kaydedebilirsiniz. Ayr\u0131ca, \u015f\u00fcpheli aktiviteyi (\u00f6rne\u011fin, farkl\u0131 IP adreslerinden arka arkaya ba\u015far\u0131s\u0131z giri\u015f denemeleri) otomatik olarak tespit etmek i\u00e7in izleme ara\u00e7lar\u0131 ve uyar\u0131 sistemleri kurmak da faydal\u0131 olacakt\u0131r.<\/p>\n<p>Bu ileri d\u00fczey senaryolar, uygulaman\u0131z\u0131n sadece \u00e7al\u0131\u015fmas\u0131n\u0131 de\u011fil, ayn\u0131 zamanda g\u00fcvenli, dayan\u0131kl\u0131 ve kullan\u0131c\u0131 dostu olmas\u0131n\u0131 da sa\u011flar. Hanami ve ROM'un mod\u00fcler yap\u0131s\u0131, bu ek g\u00fcvenlik katmanlar\u0131n\u0131 ve \u00f6zellikleri mevcut sisteminize daha d\u00fczenli ve y\u00f6netilebilir bir \u015fekilde entegre etmenize olanak tan\u0131r.<\/p>\n<h3>Mobil Uyumlu Kimlik Do\u011frulama Aray\u00fczleri<\/h3>\n<p>G\u00fcn\u00fcm\u00fczde kullan\u0131c\u0131lar\u0131n b\u00fcy\u00fck bir k\u0131sm\u0131 mobil cihazlar \u00fczerinden uygulamalara eri\u015fti\u011fi i\u00e7in, kimlik do\u011frulama sayfalar\u0131n\u0131z\u0131n mobil uyumlu olmas\u0131 \u015fartt\u0131r. Hanami, backend odakl\u0131 bir framework olsa da, frontend taraf\u0131nda kullanaca\u011f\u0131n\u0131z HTML ve CSS'i mobil uyumlu hale getirmeniz \u00f6nemlidir. Duyarl\u0131 (responsive) tasar\u0131m prensiplerini uygulayarak, giri\u015f ve kay\u0131t formlar\u0131n\u0131z\u0131n ekran boyutuna g\u00f6re otomatik olarak ayarlanmas\u0131n\u0131 sa\u011flayabilirsiniz. \u00d6rne\u011fin, a\u015fa\u011f\u0131daki gibi bir CSS media query kullanarak mobil cihazlar i\u00e7in \u00f6zel stiller tan\u0131mlayabilirsiniz:<\/p>\n<pre><code class=\"language-html\">\n<style>\n  \/* Genel stil *\/\n  .auth-form {\n    max-width: 400px;\n    margin: 50px auto;\n    padding: 30px;\n    border: 1px solid #ddd;\n    border-radius: 8px;\n    box-shadow: 0 4px 10px rgba(0,0,0,0.1);\n    background-color: #fff;\n  }\n  .auth-form input[type=\"email\"],\n  .auth-form input[type=\"password\"] {\n    width: 100%;\n    padding: 12px;\n    margin-bottom: 15px;\n    border: 1px solid #ccc;\n    border-radius: 4px;\n    box-sizing: border-box; \/* Padding'i geni\u015fli\u011fe dahil et *\/\n  }\n  .auth-form button[type=\"submit\"] {\n    width: 100%;\n    padding: 12px;\n    background-color: #007bff;\n    color: white;\n    border: none;\n    border-radius: 4px;\n    cursor: pointer;\n    font-size: 16px;\n  }\n  .auth-form button[type=\"submit\"]:hover {\n    background-color: #0056b3;\n  }\n\n  \/* Mobil cihazlar i\u00e7in stil *\/\n  @media only screen and (max-width: 600px) {\n    .auth-form {\n      width: 90%; \/* K\u00fc\u00e7\u00fck ekranlarda form geni\u015fli\u011fini art\u0131r *\/\n      margin: 20px auto;\n      padding: 15px;\n      box-shadow: none; \/* Mobil cihazlarda g\u00f6lgeyi kald\u0131rarak daha temiz bir g\u00f6r\u00fcn\u00fcm *\/\n    }\n    .auth-form h2 {\n      font-size: 24px;\n      text-align: center;\n    }\n    .auth-form input[type=\"email\"],\n    .auth-form input[type=\"password\"],\n    .auth-form button[type=\"submit\"] {\n      font-size: 16px; \/* Dokunmatik ekranlarda daha rahat kullan\u0131m i\u00e7in yaz\u0131 boyutunu b\u00fcy\u00fct *\/\n      padding: 15px;\n    }\n  }\n<\/style>\n\n<div class=\"auth-form\">\n  <h2>Giri\u015f Yap<\/h2>\n  <form action=\"\/auth\/identity\" method=\"post\">\n    <label for=\"email\">E-posta:<\/label>\n    <input type=\"email\" id=\"email\" name=\"auth_key\" placeholder=\"e-posta adresiniz\" required>\n    <label for=\"password\">\u015eifre:<\/label>\n    <input type=\"password\" id=\"password\" name=\"password\" placeholder=\"\u015fifreniz\" required>\n    <button type=\"submit\">Giri\u015f Yap<\/button>\n  <\/form>\n<\/div>\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnek, formun genel g\u00f6r\u00fcn\u00fcm\u00fcn\u00fc tan\u0131mlar ve 600 pikselden daha dar ekranlar (\u00e7o\u011fu mobil cihaz) i\u00e7in \u00f6zelle\u015ftirilmi\u015f stiller sunar. Bu \u015fekilde, kullan\u0131c\u0131lar\u0131n\u0131z hangi cihazdan eri\u015firse eri\u015fsin, tutarl\u0131 ve kullan\u0131\u015fl\u0131 bir kimlik do\u011frulama deneyimi ya\u015far.<\/p>\n<h2 id=\"sonuc-omniauth-identity-v315-ile-guvenli-ve-hizli-uygulamalar-gelistirin\">Sonu\u00e7: omniauth-identity v3.1.5 ile G\u00fcvenli ve H\u0131zl\u0131 Uygulamalar Geli\u015ftirin<\/h2>\n<p>Modern web uygulamas\u0131 geli\u015ftirmede kimlik do\u011frulama, uygulaman\u0131n temel g\u00fcvenli\u011fini ve kullan\u0131c\u0131 deneyimini do\u011frudan etkileyen kritik bir unsurdur. <code>omniauth-identity v3.1.5<\/code>'in Hanami ve ROM ekosistemlerine getirdi\u011fi kapsaml\u0131 destek, Ruby geli\u015ftiricileri i\u00e7in bu alanda \u00f6nemli bir bo\u015flu\u011fu doldurmu\u015ftur. Bu entegrasyon sayesinde, Hanami'nin minimalist ve performans odakl\u0131 yap\u0131s\u0131yla ROM'un esnek ve ORM ba\u011f\u0131ms\u0131z veri eri\u015fim katman\u0131, <code>omniauth-identity<\/code>'nin g\u00fcvenilir yerel kimlik do\u011frulama yetenekleriyle m\u00fckemmel bir uyum i\u00e7inde \u00e7al\u0131\u015fabilmektedir.<\/p>\n<p>Bu makalede ele ald\u0131\u011f\u0131m\u0131z ad\u0131mlar ve vaka analizleri, <code>omniauth-identity v3.1.5<\/code>'i Hanami projenize nas\u0131l entegre edece\u011finizi, ROM ile veritaban\u0131 ili\u015fkilerini ve kimlik y\u00f6netimini nas\u0131l kuraca\u011f\u0131n\u0131z\u0131 detayl\u0131 bir \u015fekilde g\u00f6stermi\u015ftir. \u015eifrelerin g\u00fcvenli bir \u015fekilde hash'lenmesinden, kimlik do\u011frulama ak\u0131\u015flar\u0131n\u0131n y\u00f6netilmesine kadar her bir ad\u0131m, uygulaman\u0131z\u0131n temel g\u00fcvenlik prensiplerine uygun olarak in\u015fa edilmesini sa\u011flam\u0131\u015ft\u0131r. Ayr\u0131ca, iki fakt\u00f6rl\u00fc kimlik do\u011frulama, \u015fifre s\u0131f\u0131rlama mekanizmalar\u0131, brute-force korumas\u0131 ve di\u011fer OmniAuth sa\u011flay\u0131c\u0131lar\u0131yla entegrasyon gibi ileri d\u00fczey senaryolar, uygulaman\u0131z\u0131n g\u00fcvenlik duru\u015funu daha da g\u00fc\u00e7lendirerek, modern tehditlere kar\u015f\u0131 daha diren\u00e7li hale getirme yollar\u0131n\u0131 sunmu\u015ftur.<\/p>\n<p><code>omniauth-identity v3.1.5<\/code> ile geli\u015ftiriciler, Hanami ve ROM'un sundu\u011fu h\u0131z, esneklik ve mod\u00fclerlik avantajlar\u0131ndan tam olarak faydalan\u0131rken, ayn\u0131 zamanda kullan\u0131c\u0131lar\u0131na g\u00fcvenli ve sorunsuz bir kimlik do\u011frulama deneyimi sunabilirler. Bu, \u00f6zellikle performans\u0131n ve temiz mimarinin \u00f6n planda oldu\u011fu projelerde, geli\u015ftirme s\u00fcrecini h\u0131zland\u0131r\u0131rken uzun vadeli bak\u0131m ve \u00f6l\u00e7eklenebilirlik a\u00e7\u0131s\u0131ndan da \u00f6nemli avantajlar sa\u011flar. Ruby ekosisteminin s\u00fcrekli geli\u015fimiyle birlikte, bu t\u00fcr entegrasyonlar, geli\u015ftiricilere daha fazla ara\u00e7 se\u00e7ene\u011fi sunarak daha yenilik\u00e7i ve g\u00fcvenli uygulamalar geli\u015ftirmelerine olanak tan\u0131maktad\u0131r. \u00d6zetle, <code>omniauth-identity v3.1.5<\/code>, Hanami ve ROM kullanan t\u00fcm geli\u015ftiriciler i\u00e7in kimlik y\u00f6netimini basitle\u015ftiren ve g\u00fc\u00e7lendiren vazge\u00e7ilmez bir ara\u00e7t\u0131r.<\/p>\n<h3 id=\"sikca-sorulan-sorular\">S\u0131k\u00e7a Sorulan Sorular<\/h3>\n<dl>\n<dt>Q1: <code>omniauth-identity<\/code> sadece Hanami ile mi \u00e7al\u0131\u015f\u0131r?<\/dt>\n<dd>A1: Hay\u0131r, <code>omniauth-identity<\/code> OmniAuth \u00e7at\u0131s\u0131n\u0131n bir par\u00e7as\u0131d\u0131r ve Ruby tabanl\u0131 herhangi bir web framework'\u00fc (Rails, Sinatra, Roda vb.) ile uyumlu \u00e7al\u0131\u015fabilir. V3.1.5 s\u00fcr\u00fcm\u00fc, \u00f6zellikle Hanami ve ROM ile entegrasyonu kolayla\u015ft\u0131ran geli\u015ftirmeler i\u00e7erir, ancak bu di\u011fer framework'lerle \u00e7al\u0131\u015famayaca\u011f\u0131 anlam\u0131na gelmez. Sadece entegrasyon ad\u0131mlar\u0131 kulland\u0131\u011f\u0131n\u0131z framework'e g\u00f6re de\u011fi\u015fiklik g\u00f6sterebilir.<\/dd>\n<dt>Q2: Mevcut bir Rails uygulamamda kullanabilir miyim?<\/dt>\n<dd>A2: Kesinlikle evet. <code>omniauth-identity<\/code>, Rails uygulamalar\u0131nda ActiveRecord veya di\u011fer ORM'lerle sorunsuz bir \u015fekilde entegre edilebilir. Tek yapman\u0131z gereken, Identity modelinizi ve repository (veya do\u011frudan ActiveRecord modelinizi) Omniauth yap\u0131land\u0131rman\u0131za uygun \u015fekilde d\u00fczenlemektir. Zaten Rails toplulu\u011funda uzun s\u00fcredir yayg\u0131n olarak kullan\u0131lmaktad\u0131r.<\/dd>\n<dt>Q3: ROM yerine ba\u015fka bir ORM ile \u00e7al\u0131\u015f\u0131r m\u0131?<\/dt>\n<dd>A3: Evet, <code>omniauth-identity<\/code> temel olarak bir \"model\" nesnesini (veya Hanami\/ROM ba\u011flam\u0131nda bir \"repository\" nesnesini) bekler. Bu nesnenin belirli metotlara (\u00f6rne\u011fin <code>authenticate(email, password)<\/code>) sahip olmas\u0131 yeterlidir. Dolay\u0131s\u0131yla, ActiveRecord, Sequel veya ba\u015fka bir veri eri\u015fim k\u00fct\u00fcphanesi kullan\u0131yorsan\u0131z, o k\u00fct\u00fcphaneye \u00f6zg\u00fc modelinizi veya veri eri\u015fim katman\u0131n\u0131z\u0131 <code>omniauth-identity<\/code>'nin beklentilerine uygun \u015fekilde uyarlayarak kullanabilirsiniz.<\/dd>\n<dt>Q4: \u015eifreleri nas\u0131l g\u00fcvenli bir \u015fekilde saklamal\u0131y\u0131m?<\/dt>\n<dd>A4: \u015eifreleri hi\u00e7bir zaman d\u00fcz metin olarak saklamamal\u0131s\u0131n\u0131z. Her zaman kriptografik olarak g\u00fcvenli bir tek y\u00f6nl\u00fc hash algoritmas\u0131 (\u00f6rne\u011fin BCrypt veya Argon2) kullanarak hash'lemelisiniz. <code>bcrypt<\/code> gem'i Ruby'de bu ama\u00e7la yayg\u0131n olarak kullan\u0131l\u0131r. \u015eifre hash'leme i\u015flemi s\u0131ras\u0131nda yeterince g\u00fc\u00e7l\u00fc bir tuzlama (salting) kullan\u0131ld\u0131\u011f\u0131ndan emin olun. Ayr\u0131ca, hashlenmi\u015f \u015fifreler veritaban\u0131na kaydedilirken uygun s\u00fctun boyutunu ve indekslemeyi kullanmaya \u00f6zen g\u00f6sterin.<\/dd>\n<dt>Q5: <code>omniauth-identity<\/code> OAuth\/OpenID Connect sa\u011flay\u0131c\u0131lar\u0131yla nas\u0131l entegre olur?<\/dt>\n<dd>A5: <code>omniauth-identity<\/code>, OmniAuth \u00e7at\u0131s\u0131n\u0131n sadece bir par\u00e7as\u0131d\u0131r. OmniAuth'\u0131n g\u00fcc\u00fc, farkl\u0131 kimlik do\u011frulama stratejilerini (OAuth, OpenID Connect, LDAP vb.) tek bir API alt\u0131nda birle\u015ftirmesidir. <code>omniauth-identity<\/code> yerel kullan\u0131c\u0131 ad\u0131\/\u015fifre kimlik do\u011frulamas\u0131 sa\u011flarken, <code>omniauth-google_oauth2<\/code> veya <code>omniauth-github<\/code> gibi di\u011fer OmniAuth gem'lerini ayn\u0131 OmniAuth Builder blo\u011fu i\u00e7inde yap\u0131land\u0131rarak uygulaman\u0131za harici sa\u011flay\u0131c\u0131larla oturum a\u00e7ma se\u00e7ene\u011fi ekleyebilirsiniz. Kullan\u0131c\u0131lar\u0131n farkl\u0131 sa\u011flay\u0131c\u0131lar \u00fczerinden giri\u015f yapt\u0131klar\u0131nda ayn\u0131 kullan\u0131c\u0131 hesab\u0131na y\u00f6nlendirilmesini sa\u011flamak i\u00e7in, uygulaman\u0131zda bir \"User\" modelini ve bu modele ba\u011fl\u0131 birden fazla \"Identity\" kayd\u0131n\u0131 y\u00f6neten bir ili\u015fki kurman\u0131z gerekebilir.<\/dd>\n<\/dl>\n","protected":false},"excerpt":{"rendered":"Modern web uygulamalar\u0131 geli\u015ftirirken kullan\u0131c\u0131 kimlik do\u011frulama, uygulaman\u0131z\u0131n g\u00fcvenli\u011finin temelini olu\u015fturur. Peki, bu s\u00fcreci Hanami ve ROM gibi&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-31798","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>omniauth-identity v3.1.5 Hanami ROM Entegrasyonu: Kimlik Y\u00f6netiminde Yeni Bir Boyut<\/title>\n<meta name=\"description\" content=\"Modern web uygulamalar\u0131 geli\u015ftirirken kullan\u0131c\u0131 kimlik do\u011frulama, uygulaman\u0131z\u0131n g\u00fcvenli\u011finin temelini olu\u015fturur. Peki, bu s\u00fcreci Hanami ve ROM gibi performans odakl\u0131 ara\u00e7larla entegre ederken kar\u015f\u0131la\u015f\u0131lan zorluklar\u0131 nas\u0131l a\u015far\u0131z? omniauth-identity v3.1.5, bu soruna g\u00fc\u00e7l\u00fc bir yan\u0131t sunarak Hanami ve ROM kullan\u0131c\u0131lar\u0131na sorunsuz bir yerel kimlik do\u011frulama deneyimi vaat ediyor.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"omniauth-identity v3.1.5 Hanami ROM Entegrasyonu: Kimlik Y\u00f6netiminde Yeni Bir Boyut\" \/>\n<meta property=\"og:description\" content=\"Modern web uygulamalar\u0131 geli\u015ftirirken kullan\u0131c\u0131 kimlik do\u011frulama, uygulaman\u0131z\u0131n g\u00fcvenli\u011finin temelini olu\u015fturur. Peki, bu s\u00fcreci Hanami ve ROM gibi performans odakl\u0131 ara\u00e7larla entegre ederken kar\u015f\u0131la\u015f\u0131lan zorluklar\u0131 nas\u0131l a\u015far\u0131z? omniauth-identity v3.1.5, bu soruna g\u00fc\u00e7l\u00fc bir yan\u0131t sunarak Hanami ve ROM kullan\u0131c\u0131lar\u0131na sorunsuz bir yerel kimlik do\u011frulama deneyimi vaat ediyor.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-14T01:01:28+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"31 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"omniauth-identity v3.1.5 Hanami ROM Entegrasyonu: Kimlik Y\u00f6netiminde Yeni Bir Boyut\",\"datePublished\":\"2025-10-14T01:01:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/\"},\"wordCount\":4120,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/\",\"name\":\"omniauth-identity v3.1.5 Hanami ROM Entegrasyonu: Kimlik Y\u00f6netiminde Yeni Bir Boyut\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-14T01:01:28+00:00\",\"description\":\"Modern web uygulamalar\u0131 geli\u015ftirirken kullan\u0131c\u0131 kimlik do\u011frulama, uygulaman\u0131z\u0131n g\u00fcvenli\u011finin temelini olu\u015fturur. Peki, bu s\u00fcreci Hanami ve ROM gibi performans odakl\u0131 ara\u00e7larla entegre ederken kar\u015f\u0131la\u015f\u0131lan zorluklar\u0131 nas\u0131l a\u015far\u0131z? omniauth-identity v3.1.5, bu soruna g\u00fc\u00e7l\u00fc bir yan\u0131t sunarak Hanami ve ROM kullan\u0131c\u0131lar\u0131na sorunsuz bir yerel kimlik do\u011frulama deneyimi vaat ediyor.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"omniauth-identity v3.1.5 Hanami ROM Entegrasyonu: Kimlik Y\u00f6netiminde Yeni Bir Boyut\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"omniauth-identity v3.1.5 Hanami ROM Entegrasyonu: Kimlik Y\u00f6netiminde Yeni Bir Boyut","description":"Modern web uygulamalar\u0131 geli\u015ftirirken kullan\u0131c\u0131 kimlik do\u011frulama, uygulaman\u0131z\u0131n g\u00fcvenli\u011finin temelini olu\u015fturur. Peki, bu s\u00fcreci Hanami ve ROM gibi performans odakl\u0131 ara\u00e7larla entegre ederken kar\u015f\u0131la\u015f\u0131lan zorluklar\u0131 nas\u0131l a\u015far\u0131z? omniauth-identity v3.1.5, bu soruna g\u00fc\u00e7l\u00fc bir yan\u0131t sunarak Hanami ve ROM kullan\u0131c\u0131lar\u0131na sorunsuz bir yerel kimlik do\u011frulama deneyimi vaat ediyor.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/","og_locale":"tr_TR","og_type":"article","og_title":"omniauth-identity v3.1.5 Hanami ROM Entegrasyonu: Kimlik Y\u00f6netiminde Yeni Bir Boyut","og_description":"Modern web uygulamalar\u0131 geli\u015ftirirken kullan\u0131c\u0131 kimlik do\u011frulama, uygulaman\u0131z\u0131n g\u00fcvenli\u011finin temelini olu\u015fturur. Peki, bu s\u00fcreci Hanami ve ROM gibi performans odakl\u0131 ara\u00e7larla entegre ederken kar\u015f\u0131la\u015f\u0131lan zorluklar\u0131 nas\u0131l a\u015far\u0131z? omniauth-identity v3.1.5, bu soruna g\u00fc\u00e7l\u00fc bir yan\u0131t sunarak Hanami ve ROM kullan\u0131c\u0131lar\u0131na sorunsuz bir yerel kimlik do\u011frulama deneyimi vaat ediyor.","og_url":"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-14T01:01:28+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"31 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"omniauth-identity v3.1.5 Hanami ROM Entegrasyonu: Kimlik Y\u00f6netiminde Yeni Bir Boyut","datePublished":"2025-10-14T01:01:28+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/"},"wordCount":4120,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/","url":"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/","name":"omniauth-identity v3.1.5 Hanami ROM Entegrasyonu: Kimlik Y\u00f6netiminde Yeni Bir Boyut","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-14T01:01:28+00:00","description":"Modern web uygulamalar\u0131 geli\u015ftirirken kullan\u0131c\u0131 kimlik do\u011frulama, uygulaman\u0131z\u0131n g\u00fcvenli\u011finin temelini olu\u015fturur. Peki, bu s\u00fcreci Hanami ve ROM gibi performans odakl\u0131 ara\u00e7larla entegre ederken kar\u015f\u0131la\u015f\u0131lan zorluklar\u0131 nas\u0131l a\u015far\u0131z? omniauth-identity v3.1.5, bu soruna g\u00fc\u00e7l\u00fc bir yan\u0131t sunarak Hanami ve ROM kullan\u0131c\u0131lar\u0131na sorunsuz bir yerel kimlik do\u011frulama deneyimi vaat ediyor.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/omniauth-identity-v3-1-5-hanami-rom-entegrasyonu-kimlik-yonetiminde-yeni-bir-boyut\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"omniauth-identity v3.1.5 Hanami ROM Entegrasyonu: Kimlik Y\u00f6netiminde Yeni Bir Boyut"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31798","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=31798"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31798\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=31798"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=31798"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=31798"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}