MVC’de Facebook, Twitter ve Google OAuth2 Login İşlemleri
Bugün bir mvc projesinde Twitter, Facebook ve Google ile nasıl Login olunabileceğini hep beraber inceleyeceğiz.
Öncelikle aşağıdaki gibi yeni bir MVC Web projesi yaratılır. Bu şekilde default AccountController ve Login ekranları ile birlikte proje yaratılmış olunur. Yani dolu bir mvc projesi yaratılır.
NuGet’de en son OWIN paketi aşağıdaki gibi güncellenir.
Şimdi sıra geldi proje için SSL ayarlarının yapılmasına. Google ve Facebook’un authentication providerlarının kullanılabilmesi için IIS-Express’in SSL kullanması gerekmektedir. Böylece Login işleminden sonra HTTP’ye dönülmez. Ayrıca login işlemlerinde cookie, username ve password’ün clear-text olarak gönderilmemesi, yine SSL ile sağlanır. Proje tıklanıp, property ekranından SSL Enabled’a True değeri aşağıdaki gibi atanır.
Daha sonra aşağıda görülen SSL URL kopyalanır ve Proje sağ tıklanıp Properties seçilir. Solda Web sekmesi seçildikten sonra Project Url kısmına kopyalanan bu SSL adresi yapıştırılır ve kaydedilir.
HomeController’da Index() action’ın üstüne RequireHttps attribute’ü konarak tüm requestlerin HTTPS olması sağlanır. RequireHttps, uygulamayı daha güvenli bir hale getirir. Proje çalıştırıldığı zaman bazı browserlar güvenlik için sizi aşağıdaki gibi(Firefox) uyaracaktır.
Google App ile OAuth 2 Kullanarak Login Olma:
1-)Öncelikle Google Developers Console‘a gidilir.
2-)Create Project tıklnarak Proje isimi ve istenir ise(optional) ID’si doldurulur. Birkaç saniye sonra proje yaratılır ve browser sayfasında gösterilir.
3-)Sol tab’da, APIs & auth tıklanır, ve sonra > Credentials. Sağda açılan alandan OAuth 2.0 client ID tıklanır.
4-)Açılan ekrandan, application tipi olarak Web application seçilir. Eğer seçilemez ise aşağıda görüldüğü gibi Configuration consent ekranına gidilmesi gerekmektedir.
5-)Configuratin ekranında Product Name zorunlu alandır. Ayrıca logo ve homepage gibi diğer alanlarda girilebilir.
6-)Web application seçilince aşağıdaki ekran açılır. İsim alanı doldurulduktan sonra authorized JavaScript içine belirlediğimiz SSL URL konur https://localhost:44300. Redirect Url içine https://localhost:44300/signin-google adresi konur. Bu adres ile login işleminden sonra yönlenecek sayfa belirlenir.
7-)Create button’una basılıp application kaydedilince aşağıda görülen credential bilgileri alınır.
Soldaki menüden APIs tıklanır. Sağda çıkan menu’den Google+ API tıklanır. Enable API tıklanarak, ilgili apilerin kullanılmasına izin verilir. Yani böylece yarattığımız api proje içinden login amaçlı çağrılabilecektir.
8-) Şimdi sıra geldi çekilen credentialları uygulamada tanımlamaya. Google ekranından alınan “ClientID ve ClientSecret’ı “, App_Start/Startup.Auth.cs altına aşağıdaki gibi tanımlanır. Böylece login ekranında diğer servisden login ol kısmanda Google button’u gözükecektir.
1 2 3 4 5 |
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() { ClientId = "998653436940-mis9f15um8k0g65bff997k1hmbb2lbsp.apps.googleusercontent.com", ClientSecret = "EK_H0n_LH8illan76fjfWkPY" }); |
9-)İlgili button tıklanınca aşağıdaki gibi bir izin ekranı karşımıza çıkar.
“Allow” button’una basıldıktan sonra aşağıda görülen Register sayfasına yönlenilir. Google hesabına bağlı email girilerek rezervasyon işlemi tamamlanır.
Rezervasyon işleminden sonra aşağıda görüldüğü gibi google ile login olunmuş olunur.
Facebook’da Bir App Yaratıp Projeye Connect Olma:
1-)Öncelikle https://developers.facebook.com/apps adresine gidilir ve login olunur.
2-)Eğer önceden Facebook developer olarak register değil iseniz, yönlendirmelere göre kayıt olunur.
3-)Aşağıda görüldüğü gibi facebook bize ne tür bir proje yaratmak istenildiğini sorar. Sonuç olarak İnternet Sitesi seçilir.
4-) Daha sonra ilgili application’ın ismi ve kategorisi, altta gelen ekranlarda doldurulur ve ilgili App yaratılır.
5-)Daha sonra “My Apps“‘altında soldan Settings menu’sü seçilir. İlgili App ID ve App Secret kopyalanır. Ayrıca + Add Platform tıklanarak “Website” seçilir. Site URL kısmına local’de test edilecek SSL kullanılan https://localhost:44300 adresi girilir.
6-)App_Start/Startup.Auth.cs altına aşağıdaki gibi Facebook’dan kopyalanan credentiallar tanımlanır.
1 2 3 |
app.UseFacebookAuthentication( appId: "697040570396208", appSecret: "264879822b5fe6e94413e0c5bedbcebc"); |
7-) Facebook Authentication app altında tanımlandıktan sonra login ekranına artık FaceBook buttonu’da gelir. İlgili button tıklanınca, aşağıdaki gibi bir izin ekranı karşımıza gelir.
8-)İlgili izin verildikten sonra rezervasyon için aşağıdaki alanlar doldurulur. Sizde sadece Email alanı gözükecektir. Diğer alanların(HomeTown ve BirthDate) custom olarak nasıl eklendiğini makalenin ilerleyen kısımlarında inceleyeceğiz.
Register işleminden sonra uygulamaya login olunmuş olunur.
Twitter ile Uygulamaya Connect Olma:
1-) Öncelikle https://apps.twitter.com/ adresine gidilir ve login olunur. Aşağıda görüldüğü gibi “Create New App” button’u tıklanınca karşımıza yaratılacak uygulamanın detay formu gelir.
2-)Aşağıda görülen form’da Uygulamanın Adı, Açıklama, Website, Callback URL alanları girilir. “localhost” yerine “127.0.0.1” yazılmasına, dikkat etmişinizdir.
Not: Twitter “localhost” şeklinde url’in yazılmasına izin vermez.
3-)İlgili application Twitter’da yaratıldıktan sonra aşağıda görüldüğü gibi Twitter’a ait API Key ve API Secret alınır.
4-)Alınan API değerleri App_Start/Startup.Auth.cs altına aşağıdaki gibi tanımlanır. Böylece login ekranında karşımıza facebook ve google haricinde twitter buttonu da gelir.
1 2 3 4 |
app.UseTwitterAuthentication( consumerKey: "a7eHBSmPiSxN1M7JWTE5QwS7c", consumerSecret: "ia62qirMsvnz1fsVqLpi0LUDPAdpiDyIvOaawoSt0tv1wv0lTE" ); |
5-)Uygulamada twitter ile login olununca aşağıdaki ekran karşımıza gelir.
6-)Yukarıdaki ekrandaki onay verildikten sonra aşağıdaki register ekranı karşımıza çıkar. Ilgili kayıt yapıldıktan sonra yukarıda belirtiğimiz “Callback Url“‘e yani uygulamamızın ana sayfasına yönlenilir. Rezerasyon ekranında sizde sadece Email alanı gözükecektir. Diğer alanların(HomeTown, BirthDate) custom olarak nasıl ekleneceğini makalenin ilerleyen kısımlarında inceleyeceğiz.
Üyelik Data’sını Hep beraber İnceleyelim: Amaç login olan kişilerin kaydını detaylı şekilde görmektir. Data Connection =>DefaultConnection=>Tables=>AspNetUser sağ tıklanıp “Show Table Data” seçeneği seçilir. Aşağıda resimli şekilde ilgili Tablo gösterilmiştir.
Üyelik datasının sonucu aşağıdaki gibidir.
Şimdi sıra geldi User Class’ına Custom Kolonlar Ekelemeye: Yani Email haricinde formada görülmeyen BirthDate ve HomeTown alanlarını eklemeye.
Models\IdentityModels.cs dosyasındaki ApplicationUser sınıfına BirthDate ve HomeTown propertyleri aşağıdaki gibi eklenir:
1 2 3 4 5 6 7 8 9 10 11 12 |
public class ApplicationUser : IdentityUser { <strong>public string HomeTown { get; set; } public System.DateTime? BirthDate { get; set; }</strong> public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) { // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); // Add custom user claims here return userIdentity; } } |
Models\AccountViewModels.cs dosyasına BirthDate ve HomeTown propertyleri aşağıdaki gibi eklenir:
ExternalLoginConfirmationViewModel:
1 2 3 4 5 6 7 8 |
public class ExternalLoginConfirmationViewModel { [Required] [Display(Name = "Email")] public string Email { get; set; } public string HomeTown { get; set; } public System.DateTime? BirthDate { get; set; } } |
Controllers\AccountController.cs dosyasına BirthDate ve HomeTown propertyleri de eklenip doldurulur:
ExternalLoginConfirmation():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
// POST: /Account/ExternalLoginConfirmation [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl) { if (User.Identity.IsAuthenticated) { return RedirectToAction("Index", "Manage"); } if (ModelState.IsValid) { // Get the information about the user from the external login provider var info = await AuthenticationManager.GetExternalLoginInfoAsync(); if (info == null) { return View("ExternalLoginFailure"); } var user = new ApplicationUser { UserName = model.Email, Email = model.Email , <strong>BirthDate = model.BirthDate, HomeTown = model.HomeTown</strong> }; var result = await UserManager.CreateAsync(user); if (result.Succeeded) { result = await UserManager.AddLoginAsync(user.Id, info.Login); if (result.Succeeded) { await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); return RedirectToLocal(returnUrl); } } AddErrors(result); } ViewBag.ReturnUrl = returnUrl; return View(model); } |
Son olarak view için Views\Account\ExternalLoginConfirmation.cshtml dosya’sında BirthDate ve HomeTown alanlarıda view’a eklenir:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
@model FaceConnect.Models.ExternalLoginConfirmationViewModel @{ ViewBag.Title = "Register"; } <h2>@ViewBag.Title.</h2> <h3>Associate your @ViewBag.LoginProvider account.</h3> @using (Html.BeginForm("ExternalLoginConfirmation", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { @Html.AntiForgeryToken() <h4>Association Form</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <p class="text-info"> You've successfully authenticated with <strong>@ViewBag.LoginProvider</strong>. Please enter a user name for this site below and click the Register button to finish logging in. </p> <div class="form-group"> @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(m => m.HomeTown, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.HomeTown, new { @class = "form-control" }) @Html.ValidationMessageFor(m => m.HomeTown) </div> </div> <div class="form-group"> @Html.LabelFor(m => m.BirthDate, new { @class = "col-md-2 control-label" }) <div class="col-md-10"> @Html.TextBoxFor(m => m.BirthDate, new { @class = "form-control" }) @Html.ValidationMessageFor(m => m.BirthDate) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" class="btn btn-default" value="Register" /> </div> </div> } @section Scripts { @Scripts.Render("~/bundles/jqueryval") } |
Bu yeni 2 alanı test edebilmek için Facebook’daki register’ın silinip yeniden verify yapılması gerekir. Bu işlem sırasında bir hata ile karşılaşılır. Bu database hatasıdır. Birth Date ve Home Town alanlarının da email ile birlikte gelebilmesi için aşağıda görüldüğü gibi Solution Explorer’da Show All Files clicklendikten sonra Add_Data\aspnet-FaceConnect-<dateStamp>.mdf silinmesi gerekmektedir. Böylece uygulama yeniden çalıştırıldığında yeni eklenen alanlar hatasız olarak gözükecektir.
Böylece Mvc’de yaratılan bir projeye sosyal ağlar kullanılarak nasıl login olunabileceğini hep beraber gördük .
Geldik bir makalenin daha sonuna . Yeni bir makalede görüşmek üzere hoşçakalın.
harika abi eline sağlık
Teşekkürler Çağrı.
3’ü bir arada:)
Selamun Aleykum borsoft kardeşim bunu özellikleri sitemize eklemek istersek yardımcı olur musunuz
Saygılar gorusmek uzere
Selamlar;
Takıldığınız bir yer olur ise sormaktan çekinmeyin.
İyi çalışmalar.
Merhaba. Peki app-imizi host’a yerlestirirken nasil yapacagiz? ilk basta SSL Enabled=true yaptigimizda SSL url degistirilemiyor Visual Studio’da, localhost olarak kaliyor.
Selamlar İlkin,
Tam da bu konu ile ilgili Scott Hanselman’ın aşağıdaki makalesi var:) Bir bakmanı tavsiye ederim..
Workig with SSL at Development Time is easier with IISExpress
Merhaba, ben asp.net user tablo yapisi disinda custom sekilde bit login sistemi yapmak istiyorum. Yine owin kullanarak facebook google ile login olabilsin ama bu asp.net memebership yapisndaki tabolalari kullanmak istemiyorum. Custom bir authentication makalesi yazabilirmisiniz ? Ben cok denedim fakat olmadi.
Selam Mustafa,
Makaleler Listesine ekledim. İlerde bu konuda da yazıcam.
İyi çalışmalar.
facebook login işlemi esnasında gelen e-mail text box’a hangi maili yazarsak veritabanına onu kaydediyor. Facebook adresimin kayıtlı olduğu e-mail ise bir önemi kalmıyor. Bu nasıl önlenebilir?
Selam Doğukan,
Fırsat bulduğum zaman dediğin koşulu deneyeceğim. O zaman sana bir fikir verebilirim.
İyi çalışmalar.
yani sonuç olarak, facebook mailini veritabanına kayıt edemiyor oluyoruz bu yöntem ile facebook ile bağlan dediği zaman facebook’a yönlendiriyor bağlantı gerçekleştiriyor fakat sonrasında uygulamaya döndüğünde çıkan e-mail butonuna ne yazıyorsa veritabanına kullanıcı adı ve e-mail adresi olarak oradaki kayıt oluyor bununda aynı olmasına gerek yok. Örneğin; facebook mailim deneme@gmail.com, uygulamaya döndüğüm zaman deneme1234@gmail.com yazsamda uygulama bunu bir problem etmiyor. Sizi uğraştırmadan açıklamak istedim.
Twitter ile giriş yapmayı denediğim zaman “Doğrulama yordamına göre uzak sertifika geçersiz.” hatası alıyorum. İnternetten araştırdığım zaman yeni konfigürasyonun :
app.UseTwitterAuthentication(new TwitterAuthenticationOptions
{
ConsumerKey = “XXX”,
ConsumerSecret = “XXX”,
BackchannelCertificateValidator = new Microsoft.Owin.Security.CertificateSubjectKeyIdentifierValidator(new[]
{
“A5EF0B11CEC04103A34A659048B21CE0572D7D47”, // VeriSign Class 3 Secure Server CA – G2
“0D445C165344C1827E1D20AB25F40163D8BE79A5”, // VeriSign Class 3 Secure Server CA – G3
“7FD365A7C2DDECBBF03009F34339FA02AF333133”, // VeriSign Class 3 Public Primary Certification Authority – G5
“39A55D933676616E73A761DFA16A7E59CDE66FAD”, // Symantec Class 3 Secure Server CA – G4
“add53f6680fe66e383cbac3e60922e3b4c412bed”, // Symantec Class 3 EV SSL CA – G3
“4eb6d578499b1ccf5f581ead56be3d9b6744a5e5”, // VeriSign Class 3 Primary CA – G5
“5168FF90AF0207753CCCD9656462A212B859723B”, // DigiCert SHA2 High Assurance Server CA
“B13EC36903F8BF4701D498261A0802EF63642BC3” // DigiCert High Assurance EV Root CA
})
});
şeklinde yapılması gerektiği yazılmış ama hala aynı hatayı alıyorum. Bilginiz var mı bu konuda?
Merhaba bir sorum olacak,
facebook authentication olan kullanıcının
fotoğraflarını çekebilme ihtimalimiz varmı?
Sanırım yok.
Merhabalar, örneklendirmeleriniz ve makaleniz için çok teşekkür ederiz. Gerçekten çok makbule geçti ve fayda gördüm. Yalnız bir konuda size danışmam gerekti. MVC de yetkilendirmeleri yaparken metod başına [Autorize] özniteliğini yerleştiriyorum.
Ben simple membership kullanmıyorum ve kendi üyelik sistemim var. Metodun başında belirttiğim [Authorize] özniteliği membership için mi yoksa OAuth 2.0 nin bir parçası mı, açıkçası tereddütte kaldım.
Bu konuda bir fikriniz var mıdır ? Hazır membership kullanmıyorsak, OAuth 2.0 yi implement edebiliyor muyuz projemize ?
Teşekkürlerimi sunarım.
Ayşe
Selamlar,
[Authorize] tamamen MemeberShip ile gelen bir Action Filterlar’dır. Yani OAuth 2.0 ile gelen birşey değildir. Siz de isterseniz üyelikle ilgili kendi custom AAction Filterlarınızı yazabilirsiniz.
Örnek makalem: http://www.borakasmer.com/mvc-rooting-custom-constraint-custom-action-filters/
İyi çalışmalar.
Böyle bir Türkçe kaynak bulduğum için çok şanslıyım. Elinize sağlık çok güzüel bir anlatım olmuş.
Çok teşekkürler Seda :)
Hocam merhabalar projeyi authentication olarak değil empty bir mvc projesi olarak açtım. Ancak geldiğim şu aşamada facebook ve google login işlemleri kullanmam gerekti. Ancak Empty MVC açtığım için App_Start daki classlar bende yok. onları nasıl ekliyebilirim sonradan bilginiz varmı ? facebook app imi oluşturdum ıd ve şifremi aldım ancak proje authentication alt yapılı olmadığı için koyamıyorum. Yardımcı olursanız çok sevinirim. Teşekkürler iyi çalışmalar…
Hocam Merhaba. Öncelikle yazı için çok teşekkür ederim. Çok güzel ve detaylı anlatılmış. Bir sorum olacak. Google ile siteme giriş yaptırabildim fakat Facebook güvenli değil hatasını verip duruyor. Bunun nedeni nedir acaba. Ben https bağlantısı olmadığı için öyle olduğunu düşünüyorum ama bir sormak istedim. Localhostum http. Google bir sorun çıakrtmıyor fakat Facebook hata veriyor