{"id":31461,"date":"2025-10-10T06:41:07","date_gmt":"2025-10-10T03:41:07","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=31461"},"modified":"2025-10-10T06:41:07","modified_gmt":"2025-10-10T03:41:07","slug":"rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/","title":{"rendered":"Rails Uygulamalar\u0131n\u0131z \u0130\u00e7in Devise ve OmniAuth Yap\u0131land\u0131rmas\u0131: Kapsaml\u0131 Bir K\u0131lavuz"},"content":{"rendered":"<p><body><\/p>\n<h2>Rails Uygulamalar\u0131n\u0131z \u0130\u00e7in Devise ve OmniAuth Yap\u0131land\u0131rmas\u0131: Kapsaml\u0131 Bir K\u0131lavuz<\/h2>\n<h3>Giri\u015f: Modern Kimlik Do\u011frulama \u00c7\u00f6z\u00fcmleri<\/h3>\n<p>G\u00fcn\u00fcm\u00fcz web uygulamalar\u0131n\u0131n olmazsa olmazlar\u0131ndan biri, kullan\u0131c\u0131 kimlik do\u011frulama ve yetkilendirme mekanizmalar\u0131d\u0131r. Kullan\u0131c\u0131lar\u0131n uygulamaya g\u00fcvenli bir \u015fekilde giri\u015f yapabilmesi, ki\u015fisel verilerinin korunmas\u0131 ve belirli \u00f6zelliklere eri\u015fimlerinin kontrol edilmesi, uygulaman\u0131n ba\u015far\u0131s\u0131 i\u00e7in kritik \u00f6neme sahiptir. Geleneksel olarak, bu s\u00fcre\u00e7ler e-posta ve parola tabanl\u0131 sistemlerle y\u00f6netilirken, modern uygulamalar sosyal medya hesaplar\u0131 veya di\u011fer \u00fc\u00e7\u00fcnc\u00fc taraf sa\u011flay\u0131c\u0131lar arac\u0131l\u0131\u011f\u0131yla giri\u015f yapma (Single Sign-On &#8211; SSO) imkan\u0131 sunarak kullan\u0131c\u0131 deneyimini zenginle\u015ftirmeyi hedeflemektedir.<\/p>\n<p>Ruby on Rails ekosisteminde, kimlik do\u011frulama ve yetkilendirme i\u015flemleri i\u00e7in en pop\u00fcler ve g\u00fc\u00e7l\u00fc \u00e7\u00f6z\u00fcmlerden ikisi Devise ve OmniAuth&#8217;tur. Devise, Rails uygulamalar\u0131 i\u00e7in kapsaml\u0131 bir kimlik do\u011frulama \u00e7\u00f6z\u00fcm\u00fcd\u00fcr. Kay\u0131t olma, giri\u015f yapma, parola s\u0131f\u0131rlama, e-posta onay\u0131 gibi temel \u00f6zellikleri kolayca entegre etmenizi sa\u011flayan esnek ve mod\u00fcler bir yap\u0131d\u0131r. OmniAuth ise, farkl\u0131 sa\u011flay\u0131c\u0131lar (Google, GitHub, Facebook, Twitter vb.) arac\u0131l\u0131\u011f\u0131yla kimlik do\u011frulama yapmay\u0131 sa\u011flayan bir Rack ara yaz\u0131l\u0131m\u0131d\u0131r. Kullan\u0131c\u0131lar\u0131n mevcut sosyal medya hesaplar\u0131n\u0131 kullanarak uygulaman\u0131za giri\u015f yapmalar\u0131na olanak tan\u0131r, b\u00f6ylece kay\u0131t formlar\u0131 doldurma zahmetinden kurtar\u0131r ve kullan\u0131c\u0131 kat\u0131l\u0131m\u0131n\u0131 art\u0131r\u0131r.<\/p>\n<p>Bu makalede, Rails uygulaman\u0131zda Devise ve OmniAuth&#8217;u nas\u0131l yap\u0131land\u0131raca\u011f\u0131n\u0131z\u0131, bu iki g\u00fc\u00e7l\u00fc arac\u0131 bir araya getirerek hem geleneksel e-posta\/parola tabanl\u0131 kimlik do\u011frulama hem de \u00fc\u00e7\u00fcnc\u00fc taraf sa\u011flay\u0131c\u0131lar arac\u0131l\u0131\u011f\u0131yla SSO deste\u011fi sunan robust bir sistem kuraca\u011f\u0131n\u0131z\u0131 ad\u0131m ad\u0131m inceleyece\u011fiz. Bu entegrasyon, uygulaman\u0131z\u0131n g\u00fcvenlik standartlar\u0131n\u0131 y\u00fckseltirken, kullan\u0131c\u0131lar\u0131n\u0131za modern ve sorunsuz bir giri\u015f deneyimi sunman\u0131za yard\u0131mc\u0131 olacakt\u0131r.<\/p>\n<h3>Devise Kurulumu ve Temel Yap\u0131land\u0131rmas\u0131<\/h3>\n<p>Devise, Rails uygulamalar\u0131na kimlik do\u011frulama \u00f6zelliklerini eklemenin en h\u0131zl\u0131 ve en yayg\u0131n yoludur. Mod\u00fcler yap\u0131s\u0131 sayesinde ihtiyac\u0131n\u0131z olan \u00f6zellikleri se\u00e7ebilir ve uygulaman\u0131za entegre edebilirsiniz.<\/p>\n<h4>1. Devise Gem&#8217;ini Ekleme<\/h4>\n<p>\u0130lk ad\u0131m olarak, Devise gem&#8217;ini <code>Gemfile<\/code> dosyan\u0131za eklemeniz gerekmektedir. <code>Gemfile<\/code> dosyan\u0131z\u0131 a\u00e7\u0131n ve a\u015fa\u011f\u0131daki sat\u0131r\u0131 ekleyin:<\/p>\n<pre><code class=\"language-ruby\"># Gemfile\ngem 'devise'<\/code><\/pre>\n<p>Ard\u0131ndan, terminalinizde <code>bundle install<\/code> komutunu \u00e7al\u0131\u015ft\u0131rarak gem&#8217;i projenize dahil edin.<\/p>\n<pre><code class=\"language-bash\">bundle install<\/code><\/pre>\n<h4>2. Devise&#8217;\u0131 Ba\u015flatma<\/h4>\n<p>Devise gem&#8217;ini y\u00fckledikten sonra, uygulaman\u0131zda Devise&#8217;\u0131 ba\u015flatman\u0131z gerekir. Bu i\u015flem i\u00e7in a\u015fa\u011f\u0131daki Rails generator komutunu kullan\u0131n:<\/p>\n<pre><code class=\"language-bash\">rails generate devise:install<\/code><\/pre>\n<p>Bu komut, uygulaman\u0131z i\u00e7in Devise&#8217;\u0131n varsay\u0131lan yap\u0131land\u0131rma dosyalar\u0131n\u0131 olu\u015fturacakt\u0131r:<\/p>\n<p>*   <code>config\/initializers\/devise.rb<\/code>: Devise&#8217;\u0131n ana yap\u0131land\u0131rma dosyas\u0131d\u0131r. Burada, e-posta onaylar\u0131, parola s\u0131f\u0131rlama token&#8217;lar\u0131n\u0131n ge\u00e7erlilik s\u00fcresi, mod\u00fcllerin etkinle\u015ftirilmesi gibi bir\u00e7ok ayar\u0131 yapabilirsiniz.<br \/>\n*   <code>config\/locales\/devise.en.yml<\/code>: Devise&#8217;\u0131n kulland\u0131\u011f\u0131 metinlerin \u0130ngilizce \u00e7evirilerini i\u00e7erir. \u0130sterseniz bu dosyay\u0131 kopyalay\u0131p kendi dilinize g\u00f6re d\u00fczenleyebilirsiniz.<br \/>\n*   <code>config\/environments\/development.rb<\/code>: Bu dosyaya, Devise&#8217;\u0131n e-posta g\u00f6ndermesi i\u00e7in gerekli olan <code>config.action_mailer.default_url_options<\/code> ayar\u0131 eklenir. Geli\u015ftirme ortam\u0131nda genellikle bu ayar <code>host: 'localhost:3000'<\/code> olarak ayarlan\u0131r. \u00dcretim ortam\u0131nda uygulaman\u0131z\u0131n ger\u00e7ek alan ad\u0131n\u0131 belirtmeniz gerekecektir.<\/p>\n<p><code>config\/environments\/development.rb<\/code> dosyas\u0131nda a\u015fa\u011f\u0131daki sat\u0131r\u0131n bulundu\u011fundan emin olun:<\/p>\n<pre><code class=\"language-ruby\"># config\/environments\/development.rb\nconfig.action_mailer.default_url_options = { host: 'localhost', port: 3000 }<\/code><\/pre>\n<h4>3. User Modelini Olu\u015fturma<\/h4>\n<p>Devise, kimlik do\u011frulama i\u00e7in bir veritaban\u0131 modeline ihtiya\u00e7 duyar. \u00c7o\u011fu uygulamada bu model <code>User<\/code> olarak adland\u0131r\u0131l\u0131r. Devise&#8217;\u0131n kendi generator&#8217;\u0131 ile bu modeli kolayca olu\u015fturabilirsiniz:<\/p>\n<pre><code class=\"language-bash\">rails generate devise User<\/code><\/pre>\n<p>Bu komut:<\/p>\n<p>*   <code>app\/models\/user.rb<\/code> dosyas\u0131n\u0131 olu\u015fturur ve Devise mod\u00fcllerini (\u00f6rne\u011fin <code>database_authenticatable<\/code>, <code>registerable<\/code>, <code>recoverable<\/code>, <code>rememberable<\/code>, <code>validatable<\/code>) ekler.<br \/>\n*   <code>db\/migrate<\/code> dizininde yeni bir migration dosyas\u0131 olu\u015fturur. Bu migration, <code>users<\/code> tablosunu olu\u015fturacak ve Devise&#8217;\u0131n ihtiya\u00e7 duydu\u011fu s\u00fctunlar\u0131 (e-posta, \u015fifre hash&#8217;i, parola s\u0131f\u0131rlama token&#8217;lar\u0131 vb.) ekleyecektir.<\/p>\n<p>Migration dosyas\u0131n\u0131 olu\u015fturduktan sonra, veritaban\u0131n\u0131z\u0131 g\u00fcncellemek i\u00e7in <code>rake db:migrate<\/code> (veya Rails 5+ i\u00e7in <code>rails db:migrate<\/code>) komutunu \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code class=\"language-bash\">rails db:migrate<\/code><\/pre>\n<h4>4. Rotalar\u0131 Yap\u0131land\u0131rma<\/h4>\n<p>Devise, kimlik do\u011frulama i\u015flemleri i\u00e7in gerekli t\u00fcm rotalar\u0131 otomatik olarak olu\u015fturur. Bu rotalar\u0131 uygulaman\u0131za eklemek i\u00e7in <code>config\/routes.rb<\/code> dosyan\u0131z\u0131 a\u00e7\u0131n ve a\u015fa\u011f\u0131daki sat\u0131r\u0131 ekleyin:<\/p>\n<pre><code class=\"language-ruby\"># config\/routes.rb\nRails.application.routes.draw do\n  devise_for :users\n  # Di\u011fer rotalar\u0131n\u0131z...\nend<\/code><\/pre>\n<p>Bu sat\u0131r, <code>\/users\/sign_in<\/code>, <code>\/users\/sign_up<\/code>, <code>\/users\/password\/new<\/code> gibi t\u00fcm Devise rotalar\u0131n\u0131 <code>User<\/code> modeli i\u00e7in tan\u0131mlar.<\/p>\n<p>Uygulaman\u0131zda kullan\u0131c\u0131 giri\u015fi gerektiren sayfalar\u0131n\u0131z varsa, ana sayfan\u0131z\u0131n veya belirli bir sayfan\u0131n giri\u015f yap\u0131lmadan eri\u015filememesini sa\u011flamak i\u00e7in <code>ApplicationController<\/code>&#8216;a a\u015fa\u011f\u0131daki sat\u0131r\u0131 ekleyebilirsiniz:<\/p>\n<pre><code class=\"language-ruby\"># app\/controllers\/application_controller.rb\nclass ApplicationController < ActionController::Base\n  before_action :authenticate_user!\nend<\/code><\/pre>\n<p>Bu, t\u00fcm sayfalara eri\u015fmeden \u00f6nce kullan\u0131c\u0131n\u0131n giri\u015f yapmas\u0131n\u0131 zorunlu k\u0131lar. Belirli sayfalarda bu zorunlulu\u011fu kald\u0131rmak isterseniz, ilgili controller'da <code>skip_before_action :authenticate_user!, only: [:index, :show]<\/code> gibi bir ifade kullanabilirsiniz.<\/p>\n<p>Ayr\u0131ca, uygulaman\u0131z\u0131n bir ana sayfaya sahip oldu\u011fundan emin olun. \u00d6rne\u011fin:<\/p>\n<pre><code class=\"language-ruby\"># config\/routes.rb\nRails.application.routes.draw do\n  devise_for :users\n  root to: \"home#index\" # Varsay\u0131lan ana sayfa\nend<\/code><\/pre>\n<p>Ve ilgili controller ve view dosyas\u0131n\u0131 olu\u015fturun:<\/p>\n<pre><code class=\"language-bash\">rails generate controller Home index<\/code><\/pre>\n<h4>5. G\u00f6r\u00fcn\u00fcmleri \u00d6zelle\u015ftirme (\u0130ste\u011fe Ba\u011fl\u0131)<\/h4>\n<p>Devise, varsay\u0131lan olarak kendi g\u00f6r\u00fcn\u00fcmlerini (giri\u015f, kay\u0131t, parola s\u0131f\u0131rlama formlar\u0131 vb.) kullan\u0131r. Bu g\u00f6r\u00fcn\u00fcmler, uygulaman\u0131z\u0131n tasar\u0131m\u0131na uymayabilir. Devise'\u0131n g\u00f6r\u00fcn\u00fcmlerini \u00f6zelle\u015ftirmek isterseniz, a\u015fa\u011f\u0131daki komutu kullanarak t\u00fcm Devise g\u00f6r\u00fcn\u00fcmlerini uygulaman\u0131z\u0131n <code>app\/views\/devise<\/code> dizinine kopyalayabilirsiniz:<\/p>\n<pre><code class=\"language-bash\">rails generate devise:views<\/code><\/pre>\n<p>Bu i\u015flemden sonra, <code>app\/views\/devise<\/code> alt\u0131ndaki dosyalar\u0131 istedi\u011finiz gibi d\u00fczenleyebilirsiniz. \u00d6rne\u011fin, <code>app\/views\/devise\/sessions\/new.html.erb<\/code> dosyas\u0131n\u0131 d\u00fczenleyerek giri\u015f formunun g\u00f6r\u00fcn\u00fcm\u00fcn\u00fc de\u011fi\u015ftirebilirsiniz.<\/p>\n<h3>OmniAuth Entegrasyonu ve \u0130lk Ad\u0131mlar<\/h3>\n<p>OmniAuth, Rails uygulamalar\u0131na \u00fc\u00e7\u00fcnc\u00fc taraf sa\u011flay\u0131c\u0131lar (Google, GitHub, Facebook vb.) arac\u0131l\u0131\u011f\u0131yla kimlik do\u011frulama yetene\u011fi kazand\u0131ran bir Rack ara yaz\u0131l\u0131m\u0131d\u0131r. Devise ile entegre edildi\u011finde, kullan\u0131c\u0131lar\u0131n sosyal medya hesaplar\u0131n\u0131 kullanarak uygulaman\u0131za kolayca giri\u015f yapmalar\u0131n\u0131 sa\u011flar.<\/p>\n<h4>1. OmniAuth Gem'lerini Ekleme<\/h4>\n<p>OmniAuth'u kullanmak i\u00e7in \u00f6ncelikle gerekli gem'leri <code>Gemfile<\/code> dosyan\u0131za eklemelisiniz. Temel OmniAuth gem'inin yan\u0131 s\u0131ra, CSRF sald\u0131r\u0131lar\u0131na kar\u015f\u0131 koruma sa\u011flayan <code>omniauth-rails_csrf_protection<\/code> gem'ini ve kullanmak istedi\u011finiz sa\u011flay\u0131c\u0131lara ait gem'leri eklemeniz gerekir. Bu \u00f6rnekte Google ve GitHub sa\u011flay\u0131c\u0131lar\u0131n\u0131 kullanaca\u011f\u0131z.<\/p>\n<pre><code class=\"language-ruby\"># Gemfile\ngem 'omniauth'\ngem 'omniauth-rails_csrf_protection' # CSRF korumas\u0131 i\u00e7in\ngem 'omniauth-google-oauth2'         # Google ile giri\u015f i\u00e7in\ngem 'omniauth-github'                # GitHub ile giri\u015f i\u00e7in<\/code><\/pre>\n<p>Gem'leri ekledikten sonra <code>bundle install<\/code> komutunu \u00e7al\u0131\u015ft\u0131r\u0131n.<\/p>\n<p><code>omniauth-rails_csrf_protection<\/code> gem'i, OmniAuth'un varsay\u0131lan olarak CSRF korumas\u0131 sa\u011flamad\u0131\u011f\u0131 durumlarda \u00f6nemli bir g\u00fcvenlik katman\u0131 ekler. Bu gem, OmniAuth geri arama (callback) rotalar\u0131nda Rails'in yerle\u015fik CSRF korumas\u0131n\u0131 etkinle\u015ftirerek g\u00fcvenlik a\u00e7\u0131klar\u0131n\u0131 \u00f6nlemeye yard\u0131mc\u0131 olur.<\/p>\n<h4>2. OmniAuth Sa\u011flay\u0131c\u0131lar\u0131n\u0131 Yap\u0131land\u0131rma<\/h4>\n<p>Her bir OmniAuth sa\u011flay\u0131c\u0131s\u0131 i\u00e7in Client ID ve Client Secret gibi kimlik bilgilerine ihtiyac\u0131n\u0131z olacakt\u0131r. Bu bilgiler, ilgili sa\u011flay\u0131c\u0131n\u0131n geli\u015ftirici konsolundan (\u00f6rne\u011fin Google Cloud Console, GitHub Developer Settings) al\u0131n\u0131r. Bu bilgileri do\u011frudan kodunuza yazmak yerine, g\u00fcvenlik nedeniyle \u00e7evre de\u011fi\u015fkenleri (environment variables) olarak saklamak en iyi pratiktir. Rails 6.1 ve sonraki s\u00fcr\u00fcmlerde <code>credentials.yml.enc<\/code> dosyas\u0131 da bu t\u00fcr s\u0131rlar i\u00e7in g\u00fcvenli bir saklama alan\u0131 sunar. Geli\u015ftirme ortam\u0131nda <code>.env<\/code> dosyas\u0131 kullanmak yayg\u0131nd\u0131r.<\/p>\n<p>\u00d6rne\u011fin, Google ve GitHub i\u00e7in kimlik bilgilerini \u015fu \u015fekilde yap\u0131land\u0131rabiliriz:<\/p>\n<pre><code class=\"language-ruby\"># config\/initializers\/devise.rb (veya config\/initializers\/omniauth.rb gibi ayr\u0131 bir dosya)\nDevise.setup do |config|\n  # Di\u011fer Devise ayarlar\u0131...\n\n  # OmniAuth yap\u0131land\u0131rmas\u0131\n  config.omniauth :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'], {\n    scope: 'email,profile',\n    prompt: 'select_account', # Kullan\u0131c\u0131n\u0131n her seferinde hesap se\u00e7mesini sa\u011flar\n    image_aspect_ratio: 'square',\n    image_size: 50\n  }\n\n  config.omniauth :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET'], {\n    scope: 'user:email' # Kullan\u0131c\u0131n\u0131n e-posta adresine eri\u015fim izni ister\n  }\nend<\/code><\/pre>\n<p>Bu yap\u0131land\u0131rmada <code>ENV['GOOGLE_CLIENT_ID']<\/code> gibi ifadeler, sistemin \u00e7evre de\u011fi\u015fkenlerinden ilgili de\u011feri okuyaca\u011f\u0131n\u0131 belirtir. Bu de\u011fi\u015fkenleri ayarlamak i\u00e7in:<\/p>\n<p>*   <strong>Geli\u015ftirme Ortam\u0131:<\/strong> <code>dotenv-rails<\/code> gibi bir gem kullanarak <code>.env<\/code> dosyas\u0131na ekleyebilirsiniz:<\/p>\n<pre><code class=\"language-\"># .env\n    GOOGLE_CLIENT_ID=your_google_client_id\n    GOOGLE_CLIENT_SECRET=your_google_client_secret\n    GITHUB_KEY=your_github_client_id\n    GITHUB_SECRET=your_github_client_secret<\/code><\/pre>\n<p>    <code>.env<\/code> dosyas\u0131n\u0131 <code>git<\/code>'e eklemeyi unutmay\u0131n (<code>.gitignore<\/code> i\u00e7inde olmal\u0131).<br \/>\n*   <strong>\u00dcretim Ortam\u0131:<\/strong> Sunucunuzda \u00e7evre de\u011fi\u015fkenlerini do\u011frudan ayarlaman\u0131z veya bulut sa\u011flay\u0131c\u0131n\u0131z\u0131n (Heroku, AWS vb.) sundu\u011fu s\u0131r y\u00f6netimi ara\u00e7lar\u0131n\u0131 kullanman\u0131z gerekir.<\/p>\n<p><strong>Callback URL'leri:<\/strong> Sa\u011flay\u0131c\u0131 geli\u015ftirici konsollar\u0131nda (Google Cloud Console, GitHub Developer Settings) uygulaman\u0131z\u0131n callback URL'lerini belirtmeniz gerekir. Bu URL'ler, kimlik do\u011frulama i\u015flemi tamamland\u0131ktan sonra sa\u011flay\u0131c\u0131n\u0131n kullan\u0131c\u0131y\u0131 uygulaman\u0131za geri y\u00f6nlendirece\u011fi adreslerdir. Genellikle \u015fu formattad\u0131rlar:<\/p>\n<p>*   Google: <code>http:\/\/localhost:3000\/users\/auth\/google\/callback<\/code> (Geli\u015ftirme)<br \/>\n*   GitHub: <code>http:\/\/localhost:3000\/users\/auth\/github\/callback<\/code> (Geli\u015ftirme)<br \/>\n*   \u00dcretim ortam\u0131 i\u00e7in <code>http:\/\/localhost:3000<\/code> yerine uygulaman\u0131z\u0131n ger\u00e7ek alan ad\u0131n\u0131 kullan\u0131n.<\/p>\n<h3>Devise ve OmniAuth'u Birle\u015ftirme<\/h3>\n<p>\u015eimdiye kadar Devise'\u0131 geleneksel kimlik do\u011frulama i\u00e7in ve OmniAuth'u \u00fc\u00e7\u00fcnc\u00fc taraf sa\u011flay\u0131c\u0131lar i\u00e7in ayr\u0131 ayr\u0131 yap\u0131land\u0131rd\u0131k. Bu iki sistemi bir araya getirerek, hem e-posta\/parola ile hem de sosyal medya hesaplar\u0131yla giri\u015f yapabilen bir kullan\u0131c\u0131 deneyimi sunaca\u011f\u0131z.<\/p>\n<h4>1. User Modelini OmniAuth \u0130\u00e7in Haz\u0131rlama<\/h4>\n<p><code>User<\/code> modelimizin OmniAuth sa\u011flay\u0131c\u0131lar\u0131ndan gelen <code>uid<\/code> (benzersiz kullan\u0131c\u0131 kimli\u011fi) ve <code>provider<\/code> (sa\u011flay\u0131c\u0131 ad\u0131) bilgilerini saklamas\u0131 gerekir. Bu s\u00fctunlar\u0131 <code>users<\/code> tablosuna eklemek i\u00e7in bir migration olu\u015ftural\u0131m:<\/p>\n<pre><code class=\"language-bash\">rails generate migration AddOmniauthToUsers provider:string uid:string<\/code><\/pre>\n<p>Bu komut, <code>db\/migrate<\/code> dizininde yeni bir migration dosyas\u0131 olu\u015fturacakt\u0131r. Olu\u015fturulan migration dosyas\u0131n\u0131 a\u00e7\u0131n ve <code>add_index<\/code> sat\u0131r\u0131n\u0131 ekleyerek <code>provider<\/code> ve <code>uid<\/code> s\u00fctunlar\u0131 \u00fczerinde bir birle\u015fik indeks olu\u015fturun. Bu, ayn\u0131 sa\u011flay\u0131c\u0131dan ayn\u0131 <code>uid<\/code> ile birden fazla kullan\u0131c\u0131 olmas\u0131n\u0131 engelleyerek veri b\u00fct\u00fcnl\u00fc\u011f\u00fcn\u00fc sa\u011flar ve sorgu performans\u0131n\u0131 art\u0131r\u0131r.<\/p>\n<pre><code class=\"language-ruby\"># db\/migrate\/YYYYMMDDHHMMSS_add_omniauth_to_users.rb\nclass AddOmniauthToUsers < ActiveRecord::Migration[7.0] # Rails s\u00fcr\u00fcm\u00fcn\u00fcze g\u00f6re de\u011fi\u015febilir\n  def change\n    add_column :users, :provider, :string\n    add_column :users, :uid, :string\n    add_index :users, [:provider, :uid], unique: true # Birle\u015fik indeks ekliyoruz\n  end\nend<\/code><\/pre>\n<p>Migration'\u0131 \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code class=\"language-bash\">rails db:migrate<\/code><\/pre>\n<h4>2. OmniAuth Callbacks Controller Olu\u015fturma<\/h4>\n<p>OmniAuth kimlik do\u011frulama i\u015flemi tamamland\u0131\u011f\u0131nda, sa\u011flay\u0131c\u0131 kullan\u0131c\u0131y\u0131 belirledi\u011fimiz callback URL'sine y\u00f6nlendirir. Bu URL'yi i\u015flemek i\u00e7in Devise'\u0131n <code>OmniauthCallbacksController<\/code>'\u0131ndan miras alan \u00f6zel bir controller olu\u015fturaca\u011f\u0131z.<\/p>\n<p>\u00d6ncelikle, <code>config\/routes.rb<\/code> dosyas\u0131nda Devise'a, OmniAuth callback'lerini i\u015flemek i\u00e7in \u00f6zel bir controller kullanaca\u011f\u0131m\u0131z\u0131 bildirmemiz gerekiyor:<\/p>\n<pre><code class=\"language-ruby\"># config\/routes.rb\nRails.application.routes.draw do\n  devise_for :users, controllers: { omniauth_callbacks: 'users\/omniauth_callbacks' }\n  root to: \"home#index\"\nend<\/code><\/pre>\n<p>\u015eimdi, <code>app\/controllers\/users\/omniauth_callbacks_controller.rb<\/code> dosyas\u0131n\u0131 olu\u015ftural\u0131m:<\/p>\n<pre><code class=\"language-ruby\"># app\/controllers\/users\/omniauth_callbacks_controller.rb\nclass Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController\n  def google_oauth2\n    handle_omniauth_callback # Ortak metodu \u00e7a\u011f\u0131r\n  end\n\n  def github\n    handle_omniauth_callback # Ortak metodu \u00e7a\u011f\u0131r\n  end\n\n  def failure\n    redirect_to root_path, alert: 'Kimlik do\u011frulama ba\u015far\u0131s\u0131z oldu.'\n  end\n\n  private\n\n  def handle_omniauth_callback\n    @user = User.from_omniauth(request.env[\"omniauth.auth\"])\n\n    if @user.persisted?\n      sign_in_and_redirect @user, event: :authentication # Kullan\u0131c\u0131y\u0131 giri\u015f yap ve y\u00f6nlendir\n      set_flash_message(:notice, :success, kind: params[:action].capitalize) if is_navigational_format?\n    else\n      session[\"devise.omniauth_data\"] = request.env[\"omniauth.auth\"].except(\"extra\") # Hata durumunda verileri sakla\n      redirect_to new_user_registration_url, alert: @user.errors.full_messages.join(\", \")\n    end\n  end\nend<\/code><\/pre>\n<p>Bu controller, <code>google_oauth2<\/code> ve <code>github<\/code> gibi her sa\u011flay\u0131c\u0131 i\u00e7in bir metot tan\u0131mlar. Bu metotlar, Devise'\u0131n <code>OmniauthCallbacksController<\/code>'\u0131ndan miras ald\u0131\u011f\u0131 i\u00e7in Devise'\u0131n flash mesajlar\u0131 ve y\u00f6nlendirme yard\u0131mc\u0131lar\u0131 gibi \u00f6zelliklerini kullanabilir. <code>handle_omniauth_callback<\/code> metodu, her sa\u011flay\u0131c\u0131 i\u00e7in ortak mant\u0131\u011f\u0131 i\u00e7erir.<\/p>\n<h4>3. User Modelinde from_omniauth Metodunu Tan\u0131mlama<\/h4>\n<p><code>Users::OmniauthCallbacksController<\/code> i\u00e7inde \u00e7a\u011f\u0131rd\u0131\u011f\u0131m\u0131z <code>User.from_omniauth(auth)<\/code> metodu, <code>User<\/code> modelimizde tan\u0131mlanmal\u0131d\u0131r. Bu metot, OmniAuth'tan gelen verileri kullanarak bir kullan\u0131c\u0131y\u0131 bulmaktan veya yeni bir kullan\u0131c\u0131 olu\u015fturmaktan sorumlu olacakt\u0131r.<\/p>\n<p><code>app\/models\/user.rb<\/code> dosyas\u0131n\u0131 a\u00e7\u0131n ve a\u015fa\u011f\u0131daki s\u0131n\u0131f metodunu ekleyin:<\/p>\n<pre><code class=\"language-ruby\"># app\/models\/user.rb\nclass User < ApplicationRecord\n  devise :database_authenticatable, :registerable,\n         :recoverable, :rememberable, :validatable,\n         :omniauthable, omniauth_providers: [:google_oauth2, :github] # OmniAuthable mod\u00fcl\u00fcn\u00fc ve sa\u011flay\u0131c\u0131lar\u0131 ekle\n\n  def self.from_omniauth(auth)\n    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|\n      user.email = auth.info.email\n      user.password = Devise.friendly_token[0, 20] # Rastgele bir \u015fifre olu\u015ftur\n      user.name = auth.info.name # Kullan\u0131c\u0131n\u0131n ad\u0131n\u0131 kaydet (iste\u011fe ba\u011fl\u0131)\n      user.image = auth.info.image # Kullan\u0131c\u0131n\u0131n profil foto\u011fraf\u0131n\u0131 kaydet (iste\u011fe ba\u011fl\u0131)\n      # E\u011fer e-posta onay\u0131 kullan\u0131yorsan\u0131z ve OmniAuth ile gelen e-postalar\u0131n onayl\u0131 oldu\u011funu varsaymak isterseniz:\n      user.confirmed_at = Time.current if user.respond_to?(:confirmed_at)\n    end\n  end\nend<\/code><\/pre>\n<p>Bu <code>from_omniauth<\/code> metodu:<\/p>\n<p>1.  <code>provider<\/code> ve <code>uid<\/code> de\u011ferlerine g\u00f6re mevcut bir kullan\u0131c\u0131y\u0131 arar.<br \/>\n2.  E\u011fer kullan\u0131c\u0131 bulunamazsa, yeni bir kullan\u0131c\u0131 olu\u015fturur (<code>first_or_create<\/code>).<br \/>\n3.  Yeni bir kullan\u0131c\u0131 olu\u015ftururken, sa\u011flay\u0131c\u0131dan gelen e-posta, ad ve profil foto\u011fraf\u0131 gibi bilgileri kullan\u0131r.<br \/>\n4.  Devise'\u0131n <code>validatable<\/code> mod\u00fcl\u00fc i\u00e7in rastgele bir parola olu\u015fturur. OmniAuth ile giri\u015f yapan kullan\u0131c\u0131lar\u0131n parolay\u0131 bilmesine gerek yoktur, ancak Devise modelinin bir parolaya sahip olmas\u0131 gerekir.<br \/>\n5.  E\u011fer Devise'\u0131n <code>confirmable<\/code> mod\u00fcl\u00fcn\u00fc kullan\u0131yorsan\u0131z ve OmniAuth \u00fczerinden giri\u015f yapan kullan\u0131c\u0131lar\u0131n e-postalar\u0131n\u0131 do\u011frulanm\u0131\u015f kabul etmek isterseniz, <code>confirmed_at<\/code> alan\u0131n\u0131 <code>Time.current<\/code> olarak ayarlayabilirsiniz.<\/p>\n<p><code>User<\/code> modelinize <code>name<\/code> ve <code>image<\/code> gibi s\u00fctunlar\u0131 da eklemek isteyebilirsiniz. Bunun i\u00e7in bir migration olu\u015fturman\u0131z gerekecektir:<\/p>\n<pre><code class=\"language-bash\">rails generate migration AddNameToUsers name:string image:string\nrails db:migrate<\/code><\/pre>\n<h4>4. Giri\u015f\/Kay\u0131t Linklerini Ekleme<\/h4>\n<p>Son olarak, kullan\u0131c\u0131lar\u0131n OmniAuth sa\u011flay\u0131c\u0131lar\u0131 arac\u0131l\u0131\u011f\u0131yla giri\u015f yapabilmeleri i\u00e7in giri\u015f veya kay\u0131t sayfalar\u0131n\u0131za ilgili linkleri eklemeniz gerekir. Bu linkler, Devise taraf\u0131ndan olu\u015fturulan yard\u0131mc\u0131 metotlar kullan\u0131larak kolayca olu\u015fturulabilir.<\/p>\n<p>\u00d6rne\u011fin, <code>app\/views\/devise\/sessions\/new.html.erb<\/code> (giri\u015f sayfas\u0131) dosyan\u0131z\u0131 a\u00e7\u0131n ve a\u015fa\u011f\u0131daki linkleri ekleyin:<\/p>\n<pre><code class=\"language-html\"><!-- app\/views\/devise\/sessions\/new.html.erb -->\n\n<h2>Giri\u015f Yap<\/h2>\n\n<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>\n  <div class=\"field\">\n    <%= f.label :email %><br \/>\n    <%= f.email_field :email, autofocus: true, autocomplete: \"email\" %>\n  <\/div>\n\n  <div class=\"field\">\n    <%= f.label :password %><br \/>\n    <%= f.password_field :password, autocomplete: \"current-password\" %>\n  <\/div>\n\n  <% if devise_mapping.rememberable? %>\n    <div class=\"field\">\n      <%= f.check_box :remember_me %>\n      <%= f.label :remember_me %>\n    <\/div>\n  <% end %>\n\n  <div class=\"actions\">\n    <%= f.submit \"Giri\u015f Yap\" %>\n  <\/div>\n<% end %>\n\n<%= render \"devise\/shared\/links\" %>\n\n<!-- OmniAuth Giri\u015f Linkleri -->\n<p>\n  Veya \u015funlarla giri\u015f yap:\n  <%= link_to \"Google ile Giri\u015f Yap\", user_google_oauth2_omniauth_authorize_path, method: :post %> |\n  <%= link_to \"GitHub ile Giri\u015f Yap\", user_github_omniauth_authorize_path, method: :post %>\n<\/p><\/code><\/pre>\n<p><code>user_google_oauth2_omniauth_authorize_path<\/code> ve <code>user_github_omniauth_authorize_path<\/code> gibi yard\u0131mc\u0131 metotlar, Devise taraf\u0131ndan OmniAuth rotalar\u0131n\u0131z i\u00e7in otomatik olarak olu\u015fturulur. <code>method: :post<\/code> kullanmak, OmniAuth ak\u0131\u015f\u0131n\u0131n g\u00fcvenli\u011fini art\u0131rmak i\u00e7in \u00f6nerilen bir yakla\u015f\u0131md\u0131r.<\/p>\n<p>Art\u0131k uygulaman\u0131zda hem geleneksel e-posta\/parola ile hem de Google veya GitHub hesaplar\u0131yla giri\u015f yapma imkan\u0131 sunan tam entegre bir kimlik do\u011frulama sisteminiz var.<\/p>\n<h3>Geli\u015fmi\u015f Konular ve En \u0130yi Uygulamalar<\/h3>\n<p>Devise ve OmniAuth entegrasyonu tamamland\u0131ktan sonra, uygulaman\u0131z\u0131n daha sa\u011flam, g\u00fcvenli ve kullan\u0131c\u0131 dostu olmas\u0131n\u0131 sa\u011flayacak baz\u0131 geli\u015fmi\u015f konular\u0131 ve en iyi uygulamalar\u0131 g\u00f6z \u00f6n\u00fcnde bulundurmak \u00f6nemlidir.<\/p>\n<h4>\u00c7oklu Sa\u011flay\u0131c\u0131 Deste\u011fi<\/h4>\n<p>Bir kullan\u0131c\u0131n\u0131n birden fazla sosyal medya hesab\u0131n\u0131 (\u00f6rne\u011fin hem Google hem de GitHub) ayn\u0131 uygulama hesab\u0131na ba\u011flamas\u0131na izin vermek isteyebilirsiniz. Yukar\u0131daki basit <code>provider<\/code> ve <code>uid<\/code> s\u00fctunlar\u0131 <code>User<\/code> modelinde bu senaryoyu do\u011frudan desteklemez, \u00e7\u00fcnk\u00fc bir kullan\u0131c\u0131 sadece bir <code>provider<\/code> ve <code>uid<\/code> \u00e7iftine sahip olabilir.<\/p>\n<p>Bu senaryoyu desteklemek i\u00e7in, <code>Authentication<\/code> veya <code>Identity<\/code> ad\u0131nda ayr\u0131 bir model olu\u015fturmak yayg\u0131n bir yakla\u015f\u0131md\u0131r. Bu model <code>User<\/code> modeline <code>belongs_to<\/code> ili\u015fkisi ile ba\u011fl\u0131 olur ve <code>provider<\/code>, <code>uid<\/code> s\u00fctunlar\u0131n\u0131 i\u00e7erir. Bir kullan\u0131c\u0131 birden fazla <code>Authentication<\/code>'a sahip olabilir.<\/p>\n<pre><code class=\"language-ruby\"># app\/models\/user.rb\nclass User < ApplicationRecord\n  has_many :authentications, dependent: :destroy\n  # ... di\u011fer devise mod\u00fclleri\nend\n\n<h2>app\/models\/authentication.rb<\/h2>\nclass Authentication < ApplicationRecord\n  belongs_to :user\n  validates :provider, presence: true\n  validates :uid, presence: true, uniqueness: { scope: :provider }\nend<\/code><\/pre>\n<p>Bu durumda, <code>from_omniauth<\/code> metodu, mevcut bir kullan\u0131c\u0131 i\u00e7in <code>Authentication<\/code> kayd\u0131n\u0131 bulmaya veya olu\u015fturmaya odaklan\u0131r, ard\u0131ndan <code>User<\/code> modelini bulur veya olu\u015fturur.<\/p>\n<h4>Kullan\u0131c\u0131 Bilgilerini G\u00fcncelleme<\/h4>\n<p>OmniAuth arac\u0131l\u0131\u011f\u0131yla giri\u015f yapan bir kullan\u0131c\u0131n\u0131n profil bilgilerini (ad, profil foto\u011fraf\u0131 vb.) sa\u011flay\u0131c\u0131dan gelen en g\u00fcncel verilerle otomatik olarak g\u00fcncellemek isteyebilirsiniz. <code>from_omniauth<\/code> metodunda veya giri\u015f i\u015flemi s\u0131ras\u0131nda bu g\u00fcncellemeleri yapabilirsiniz:<\/p>\n<pre><code class=\"language-ruby\"># app\/models\/user.rb (from_omniauth metodunda)\ndef self.from_omniauth(auth)\n  user = where(provider: auth.provider, uid: auth.uid).first_or_initialize do |new_user|\n    new_user.email = auth.info.email\n    new_user.password = Devise.friendly_token[0, 20]\n    new_user.confirmed_at = Time.current if new_user.respond_to?(:confirmed_at)\n  end\n\n  # Kullan\u0131c\u0131 zaten varsa veya yeni olu\u015fturulduysa bilgileri g\u00fcncelle\n  user.name = auth.info.name\n  user.image = auth.info.image\n  user.save! if user.changed? # Sadece de\u011fi\u015fen alanlar\u0131 kaydet\n  user\nend<\/code><\/pre>\n<h4>Hata Y\u00f6netimi ve Kullan\u0131c\u0131 Deneyimi<\/h4>\n<p>Kimlik do\u011frulama s\u00fcrecinde \u00e7e\u015fitli hatalar meydana gelebilir (\u00f6rne\u011fin kullan\u0131c\u0131 izni iptal etti, sa\u011flay\u0131c\u0131da bir sorun olu\u015ftu). <code>Users::OmniauthCallbacksController<\/code> i\u00e7indeki <code>failure<\/code> metodu bu durumlar\u0131 ele almak i\u00e7in kullan\u0131l\u0131r. Kullan\u0131c\u0131ya a\u00e7\u0131klay\u0131c\u0131 hata mesajlar\u0131 g\u00f6stermek ve onlar\u0131 uygun bir sayfaya y\u00f6nlendirmek \u00f6nemlidir.<\/p>\n<pre><code class=\"language-ruby\"># app\/controllers\/users\/omniauth_callbacks_controller.rb\ndef failure\n  flash[:alert] = \"Kimlik do\u011frulama ba\u015far\u0131s\u0131z oldu. L\u00fctfen tekrar deneyin.\"\n  redirect_to new_user_session_path # Giri\u015f sayfas\u0131na y\u00f6nlendir\nend<\/code><\/pre>\n<p><code>flash<\/code> mesajlar\u0131n\u0131 uygulamak i\u00e7in <code>app\/views\/layouts\/application.html.erb<\/code> dosyan\u0131zda \u015fu kodun oldu\u011fundan emin olun:<\/p>\n<pre><code class=\"language-html\"><!-- app\/views\/layouts\/application.html.erb -->\n<body>\n  <% if flash[:notice] %>\n    <p class=\"notice\"><%= flash[:notice] %><\/p>\n  <% end %>\n  <% if flash[:alert] %>\n    <p class=\"alert\"><%= flash[:alert] %><\/p>\n  <% end %>\n  <%= yield %>\n<\/body><\/code><\/pre>\n<h4>G\u00fcvenlik \u00d6nlemleri<\/h4>\n<p>*   <strong>HTTPS Kullan\u0131m\u0131:<\/strong> T\u00fcm \u00fcretim ortam\u0131 uygulamalar\u0131 i\u00e7in HTTPS kullanmak zorunludur. Bu, kullan\u0131c\u0131 kimlik bilgilerinin ve di\u011fer hassas verilerin a\u011f \u00fczerinde \u015fifrelenmesini sa\u011flar.<br \/>\n*   <strong>S\u0131rlar\u0131n G\u00fcvenli Saklanmas\u0131:<\/strong> <code>Client ID<\/code> ve <code>Client Secret<\/code> gibi API anahtarlar\u0131n\u0131 asla do\u011frudan kodunuza yazmay\u0131n veya <code>git<\/code> deposuna eklemeyin. \u00c7evre de\u011fi\u015fkenleri veya Rails <code>credentials<\/code> dosyas\u0131 gibi g\u00fcvenli y\u00f6ntemler kullan\u0131n.<br \/>\n*   <strong><code>state<\/code> Parametresi:<\/strong> OmniAuth, OAuth 2.0 ak\u0131\u015f\u0131nda CSRF korumas\u0131 i\u00e7in <code>state<\/code> parametresini kullan\u0131r. <code>omniauth-rails_csrf_protection<\/code> gem'i bu korumay\u0131 sa\u011flar. Kullan\u0131c\u0131y\u0131 bir sa\u011flay\u0131c\u0131ya y\u00f6nlendirirken bir <code>state<\/code> de\u011feri g\u00f6nderilir ve callback s\u0131ras\u0131nda bu de\u011ferin e\u015fle\u015fti\u011fi do\u011frulan\u0131r. Bu, sald\u0131rganlar\u0131n kimlik do\u011frulama ak\u0131\u015f\u0131n\u0131 manip\u00fcle etmesini engeller.<br \/>\n*   <strong>E-posta Do\u011frulamas\u0131:<\/strong> OmniAuth sa\u011flay\u0131c\u0131lar\u0131ndan gelen e-postalar\u0131n genellikle do\u011frulanm\u0131\u015f oldu\u011fu varsay\u0131l\u0131r. Ancak, baz\u0131 sa\u011flay\u0131c\u0131lar do\u011frulanmam\u0131\u015f e-posta adresleri d\u00f6nd\u00fcrebilir. E\u011fer uygulaman\u0131z e-posta do\u011frulamas\u0131na \u00e7ok \u00f6nem veriyorsa, OmniAuth ile giri\u015f yapan kullan\u0131c\u0131lar i\u00e7in bile ek bir e-posta do\u011frulama ad\u0131m\u0131 eklemeyi d\u00fc\u015f\u00fcnebilirsiniz.<\/p>\n<h4>Test Etme<\/h4>\n<p>Devise ve OmniAuth entegrasyonunu test etmek, uygulaman\u0131z\u0131n g\u00fcvenilirli\u011fini sa\u011flamak i\u00e7in \u00f6nemlidir. RSpec veya Minitest gibi test framework'leri ile testler yazarken OmniAuth'u taklit etmek (mocking) yayg\u0131n bir y\u00f6ntemdir.<\/p>\n<p><strong>RSpec i\u00e7in OmniAuth Mocking \u00d6rne\u011fi:<\/strong><\/p>\n<pre><code class=\"language-ruby\"># spec\/support\/omniauth.rb\nOmniAuth.config.test_mode = true\n\ndef mock_omniauth_response(provider, email = \"test@example.com\", name = \"Test User\")\n  OmniAuth.config.mock_auth[provider] = OmniAuth::AuthHash.new({\n    provider: provider.to_s,\n    uid: '123456',\n    info: {\n      email: email,\n      name: name,\n      image: \"https:\/\/example.com\/avatar.jpg\"\n    },\n    credentials: {\n      token: 'mock_token',\n      expires_at: 1.hour.from_now.to_i\n    }\n  })\nend<\/code><\/pre>\n<p>Bu yard\u0131mc\u0131 metodu bir <code>before<\/code> blo\u011funda \u00e7a\u011f\u0131rarak testlerinizde OmniAuth yan\u0131tlar\u0131n\u0131 sim\u00fcle edebilirsiniz:<\/p>\n<pre><code class=\"language-ruby\"># spec\/features\/user_signs_in_with_google_spec.rb\nrequire 'rails_helper'\n\nRSpec.feature \"User signs in with Google\", type: :feature do\n  before do\n    mock_omniauth_response(:google_oauth2)\n  end\n\n  scenario \"successfully signs in with Google\" do\n    visit new_user_session_path\n    click_link \"Google ile Giri\u015f Yap\" # Linkin metnine g\u00f6re de\u011fi\u015febilir\n    expect(page).to have_content(\"Ba\u015far\u0131yla Google hesab\u0131n\u0131zla giri\u015f yapt\u0131n\u0131z.\")\n    expect(page).to have_content(\"Ho\u015f geldiniz, Test User!\")\n  end\nend<\/code><\/pre>\n<h4>Da\u011f\u0131t\u0131m (Deployment)<\/h4>\n<p>Uygulaman\u0131z\u0131 \u00fcretim ortam\u0131na da\u011f\u0131t\u0131rken dikkat etmeniz gerekenler:<\/p>\n<p>*   <strong>\u00c7evre De\u011fi\u015fkenleri:<\/strong> \u00dcretim sunucunuzda veya bulut sa\u011flay\u0131c\u0131n\u0131z\u0131n y\u00f6netim panelinde <code>GOOGLE_CLIENT_ID<\/code>, <code>GOOGLE_CLIENT_SECRET<\/code>, <code>GITHUB_KEY<\/code>, <code>GITHUB_SECRET<\/code> gibi \u00e7evre de\u011fi\u015fkenlerini do\u011fru bir \u015fekilde ayarlad\u0131\u011f\u0131n\u0131zdan emin olun.<br \/>\n*   <strong>Callback URL'leri:<\/strong> OmniAuth sa\u011flay\u0131c\u0131lar\u0131n\u0131z\u0131n geli\u015ftirici konsollar\u0131nda (Google Cloud Console, GitHub Developer Settings) callback URL'lerini \u00fcretim ortam\u0131 alan ad\u0131n\u0131za (<code>https:\/\/your-domain.com\/users\/auth\/google\/callback<\/code>) g\u00f6re g\u00fcncellemeyi unutmay\u0131n. Yanl\u0131\u015f callback URL'leri kimlik do\u011frulama ak\u0131\u015f\u0131n\u0131n ba\u015far\u0131s\u0131z olmas\u0131na neden olur.<br \/>\n*   <strong>HTTPS:<\/strong> \u00dcretim ortam\u0131nda her zaman HTTPS kullan\u0131n.<br \/>\n*   <strong>Asset Pipeline:<\/strong> Devise'\u0131n varsay\u0131lan g\u00f6r\u00fcn\u00fcmlerini \u00f6zelle\u015ftirdiyseniz, CSS ve JavaScript dosyalar\u0131n\u0131z\u0131n asset pipeline taraf\u0131ndan do\u011fru bir \u015fekilde derlendi\u011finden ve sunuldu\u011fundan emin olun.<\/p>\n<h3>Sonu\u00e7<\/h3>\n<p>Bu makalede, Ruby on Rails uygulamalar\u0131n\u0131zda Devise ve OmniAuth'u entegre etmenin kapsaml\u0131 bir rehberini sunduk. Devise'\u0131n g\u00fc\u00e7l\u00fc ve esnek yap\u0131s\u0131n\u0131 kullanarak geleneksel e-posta\/parola tabanl\u0131 kimlik do\u011frulamas\u0131n\u0131 nas\u0131l kuraca\u011f\u0131n\u0131z\u0131, ard\u0131ndan OmniAuth'u entegre ederek Google ve GitHub gibi \u00fc\u00e7\u00fcnc\u00fc taraf sa\u011flay\u0131c\u0131lar arac\u0131l\u0131\u011f\u0131yla sosyal giri\u015f \u00f6zelliklerini nas\u0131l ekleyece\u011finizi ad\u0131m ad\u0131m g\u00f6sterdik.<\/p>\n<p>Bu entegrasyon, uygulaman\u0131z\u0131n kullan\u0131c\u0131lar\u0131na modern ve sorunsuz bir giri\u015f deneyimi sunarken, geli\u015ftiriciler i\u00e7in de kimlik do\u011frulama s\u00fcre\u00e7lerini y\u00f6netmeyi b\u00fcy\u00fck \u00f6l\u00e7\u00fcde basitle\u015ftirir. G\u00fcvenlik en iyi uygulamalar\u0131n\u0131 (HTTPS, \u00e7evre de\u011fi\u015fkenleri, CSRF korumas\u0131) takip ederek, uygulaman\u0131z\u0131n hem i\u015flevsel hem de g\u00fcvenli olmas\u0131n\u0131 sa\u011flayabilirsiniz.<\/p>\n<p>Unutmay\u0131n ki her uygulaman\u0131n kendine \u00f6zg\u00fc ihtiya\u00e7lar\u0131 olabilir. Bu k\u0131lavuz, sa\u011flam bir temel olu\u015fturman\u0131za yard\u0131mc\u0131 olacakt\u0131r. \u0130htiya\u00e7lar\u0131n\u0131za g\u00f6re Devise ve OmniAuth yap\u0131land\u0131rmalar\u0131n\u0131 daha da \u00f6zelle\u015ftirebilir, ek sa\u011flay\u0131c\u0131lar ekleyebilir veya \u00e7oklu hesap ba\u011flama gibi geli\u015fmi\u015f \u00f6zellikler uygulayabilirsiniz. Bu g\u00fc\u00e7l\u00fc ikili sayesinde, kullan\u0131c\u0131 kimlik do\u011frulama ve yetkilendirme s\u00fcre\u00e7leriniz art\u0131k bir endi\u015fe kayna\u011f\u0131 olmaktan \u00e7\u0131k\u0131p, uygulaman\u0131z\u0131n rekabet avantajlar\u0131ndan biri haline gelecektir.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Rails Uygulamalar\u0131n\u0131z \u0130\u00e7in Devise ve OmniAuth Yap\u0131land\u0131rmas\u0131: Kapsaml\u0131 Bir K\u0131lavuz\nGiri\u015f: Modern Kimlik Do\u011frulama \u00c7\u00f6z\u00fcmleri\nG\u00fcn\u00fcm\u00fcz","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":[1342],"tags":[],"class_list":{"0":"post-31461","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-ai","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>Rails Uygulamalar\u0131n\u0131z \u0130\u00e7in Devise ve OmniAuth Yap\u0131land\u0131rmas\u0131: Kapsaml\u0131 Bir K\u0131lavuz - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\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\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Rails Uygulamalar\u0131n\u0131z \u0130\u00e7in Devise ve OmniAuth Yap\u0131land\u0131rmas\u0131: Kapsaml\u0131 Bir K\u0131lavuz\" \/>\n<meta property=\"og:description\" content=\"Rails Uygulamalar\u0131n\u0131z \u0130\u00e7in Devise ve OmniAuth Yap\u0131land\u0131rmas\u0131: Kapsaml\u0131 Bir K\u0131lavuz Giri\u015f: Modern Kimlik Do\u011frulama \u00c7\u00f6z\u00fcmleri G\u00fcn\u00fcm\u00fcz\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-10T03:41:07+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=\"20 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Rails Uygulamalar\u0131n\u0131z \u0130\u00e7in Devise ve OmniAuth Yap\u0131land\u0131rmas\u0131: Kapsaml\u0131 Bir K\u0131lavuz\",\"datePublished\":\"2025-10-10T03:41:07+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/\"},\"wordCount\":2826,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"AI\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/\",\"name\":\"Rails Uygulamalar\u0131n\u0131z \u0130\u00e7in Devise ve OmniAuth Yap\u0131land\u0131rmas\u0131: Kapsaml\u0131 Bir K\u0131lavuz - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-10T03:41:07+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Rails Uygulamalar\u0131n\u0131z \u0130\u00e7in Devise ve OmniAuth Yap\u0131land\u0131rmas\u0131: Kapsaml\u0131 Bir K\u0131lavuz\"}]},{\"@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":"Rails Uygulamalar\u0131n\u0131z \u0130\u00e7in Devise ve OmniAuth Yap\u0131land\u0131rmas\u0131: Kapsaml\u0131 Bir K\u0131lavuz - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","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\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/","og_locale":"tr_TR","og_type":"article","og_title":"Rails Uygulamalar\u0131n\u0131z \u0130\u00e7in Devise ve OmniAuth Yap\u0131land\u0131rmas\u0131: Kapsaml\u0131 Bir K\u0131lavuz","og_description":"Rails Uygulamalar\u0131n\u0131z \u0130\u00e7in Devise ve OmniAuth Yap\u0131land\u0131rmas\u0131: Kapsaml\u0131 Bir K\u0131lavuz Giri\u015f: Modern Kimlik Do\u011frulama \u00c7\u00f6z\u00fcmleri G\u00fcn\u00fcm\u00fcz","og_url":"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-10T03:41:07+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"20 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Rails Uygulamalar\u0131n\u0131z \u0130\u00e7in Devise ve OmniAuth Yap\u0131land\u0131rmas\u0131: Kapsaml\u0131 Bir K\u0131lavuz","datePublished":"2025-10-10T03:41:07+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/"},"wordCount":2826,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["AI"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/","url":"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/","name":"Rails Uygulamalar\u0131n\u0131z \u0130\u00e7in Devise ve OmniAuth Yap\u0131land\u0131rmas\u0131: Kapsaml\u0131 Bir K\u0131lavuz - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-10T03:41:07+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/rails-uygulamalariniz-icin-devise-ve-omniauth-yapilandirmasi-kapsamli-bir-kilavuz\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Rails Uygulamalar\u0131n\u0131z \u0130\u00e7in Devise ve OmniAuth Yap\u0131land\u0131rmas\u0131: Kapsaml\u0131 Bir K\u0131lavuz"}]},{"@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\/31461","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=31461"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31461\/revisions"}],"predecessor-version":[{"id":31462,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31461\/revisions\/31462"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=31461"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=31461"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=31461"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}