ASP.NET MVC 4 web application allows users to log in from an external provider, such as Facebook, Twitter, Microsoft or Google and then integrate into your web application. SomeOAuth/OpenId providers like Facebook, Google allow to access email. This article explains how to save the email in your database.
before implementing, first lets consider following points:
1. User name is different from Email.
2. Email might be different for different providers.
3. Email is optional(some external provider like twitter doesn’t allow to access email).
Getting Started:
1. Create a new ASP.NET MVC 4 > Internet Application Project
2. Open App_Start > AuthConfig.cs, uncomment the external services which you want to use and pass proper parameters. See here to configure and get parameters of external services. In this article, we will use Facebook,Twitter and Google providers.
before implementing, first lets consider following points:
1. User name is different from Email.
2. Email might be different for different providers.
3. Email is optional(some external provider like twitter doesn’t allow to access email).
Getting Started:
1. Create a new ASP.NET MVC 4 > Internet Application Project
2. Open App_Start > AuthConfig.cs, uncomment the external services which you want to use and pass proper parameters. See here to configure and get parameters of external services. In this article, we will use Facebook,Twitter and Google providers.
2. Email might be different for different providers.
3. Email is optional(some external provider like twitter doesn’t allow to access email).
Getting Started:
1. Create a new ASP.NET MVC 4 > Internet Application Project
2. Open App_Start > AuthConfig.cs, uncomment the external services which you want to use and pass proper parameters. See here to configure and get parameters of external services. In this article, we will use Facebook,Twitter and Google providers.
OAuthWebSecurity.RegisterTwitterClient(
consumerKey:
"xxxx"
,
consumerSecret:
"xxxxxxxx"
);
OAuthWebSecurity.RegisterFacebookClient(
appId:
"yyyy"
,
appSecret:
"yyyyyyyy"
);
OAuthWebSecurity.RegisterGoogleClient();
OAuthWebSecurity.RegisterTwitterClient( consumerKey: "xxxx" , consumerSecret: "xxxxxxxx" ); OAuthWebSecurity.RegisterFacebookClient( appId: "yyyy" , appSecret: "yyyyyyyy" ); OAuthWebSecurity.RegisterGoogleClient(); |
Model Changes:
3. In Account Model, add Email property in RegisterExternalLoginModel class:
public class RegisterExternalLoginModel
{
[Required]
[Display(Name =
"User name"
)]
public string UserName { get; set; }
public string ExternalLoginData { get; set; }
public string Email { get; set; }
}
4. To add Email field in OAuthMembership table, add following class:
[Table(
"webpages_OAuthMembership"
)]
public class OAuthMembership
{
[Key, Column(Order = 0), StringLength(30)]
public string Provider { get; set; }
[Key, Column(Order = 1), StringLength(100)]
public string ProviderUserId { get; set; }
public int UserId { get; set; }
[StringLength(100)]
public string Email { get; set; }
}
5. add OAuthMembership in Userscontext
public class UsersContext : DbContext
{
public UsersContext()
: base(
"DefaultConnection"
)
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
public DbSet<OAuthMembership> OAuthMemberships { get; set; }
}
It will create the required structure in database when you run the application and open register page first time.
3. In Account Model, add Email property in RegisterExternalLoginModel class:
public class RegisterExternalLoginModel { [Required] [Display(Name = "User name" )] public string UserName { get; set; } public string ExternalLoginData { get; set; } public string Email { get; set; } } |
4. To add Email field in OAuthMembership table, add following class:
[Table( "webpages_OAuthMembership" )] public class OAuthMembership { [Key, Column(Order = 0), StringLength(30)] public string Provider { get; set; } [Key, Column(Order = 1), StringLength(100)] public string ProviderUserId { get; set; } public int UserId { get; set; } [StringLength(100)] public string Email { get; set; } } |
5. add OAuthMembership in Userscontext
public class UsersContext : DbContext { public UsersContext() : base( "DefaultConnection" ) { } public DbSet<UserProfile> UserProfiles { get; set; } public DbSet<OAuthMembership> OAuthMemberships { get; set; } } |
It will create the required structure in database when you run the application and open register page first time.
Controller Changes:
In AccountController, To set email from the external provider, replace the following lines inExternalLoginCallback method :
// User is new, ask for their desired membership name
string loginData = OAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId);
ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName;
ViewBag.ReturnUrl = returnUrl;
return
View(
"ExternalLoginConfirmation"
,
new
RegisterExternalLoginModel { UserName = result.UserName, ExternalLoginData = loginData });
with the following lines:
// User is new, ask for their desired membership name
string loginData = OAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId);
ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName;
ViewBag.ReturnUrl = returnUrl;
var
model =
new
RegisterExternalLoginModel { UserName = result.UserName, ExternalLoginData = loginData };
switch
(result.Provider) {
case
"facebook"
:
case
"google"
:
{
model.Email = result.UserName;
model.UserName =
""
;
break
;
}
case
"twitter"
:
{
model.Email =
""
;
model.UserName = result.UserName;
break
;
}
default
:
break
;
}
return
View(
"ExternalLoginConfirmation"
, model);
Facebook and Google provide email as user name, so email is assigned for these providers.
In ExternalLoginConfirmation view, add following Email in form:
@Html.HiddenFor(m => m.Email)
It will post Email also when form is submitted. In ExternalLoginConfirmation method, To save email for new user,replace the following lines:
// Insert name into the profile table
db.UserProfiles.Add(
new
UserProfile { UserName = model.UserName });
db.SaveChanges();
OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName);
OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie:
false
);
return
RedirectToLocal(returnUrl);
with these lines:
// Insert name into the profile table
user =
new
UserProfile { UserName = model.UserName };
db.UserProfiles.Add(user);
db.SaveChanges();
OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName);
if
(!String.IsNullOrEmpty(model.Email)) {
var
oauthItem = db.OAuthMemberships.FirstOrDefault(x => x.Provider == provider && x.ProviderUserId == providerUserId && x.UserId == user.UserId);
if
(oauthItem !=
null
) {
oauthItem.Email = model.Email;
db.SaveChanges();
}
}
OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie:
false
);
return
RedirectToLocal(returnUrl);
This will save email in database for new user. Now if same user wants to add other external provider then in ExternalLoginCallback method, replace following line
OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, User.Identity.Name);
with following lines:
OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, User.Identity.Name);
if
(result.Provider ==
"facebook"
|| result.Provider ==
"google"
)
{
using (UsersContext db =
new
UsersContext())
{
UserProfile user = db.UserProfiles.FirstOrDefault(u => u.UserName.ToLower() == User.Identity.Name);
if
(user !=
null
)
{
var
oauthItem = db.OAuthMemberships.FirstOrDefault(x => x.Provider == result.Provider && x.ProviderUserId == result.ProviderUserId && x.UserId == user.UserId);
if
(oauthItem !=
null
)
{
oauthItem.Email = result.UserName;
db.SaveChanges();
}
}
}
}
It will save email in OAuthMembership table when new provider is added.
We have implemented to save email from OAuth/OpenId Providers. If you like this post, don’t forget to share. If you have any query, feel free to ask in comment box.
In AccountController, To set email from the external provider, replace the following lines inExternalLoginCallback method :
// User is new, ask for their desired membership name string loginData = OAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId); ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName; ViewBag.ReturnUrl = returnUrl; return View( "ExternalLoginConfirmation" , new RegisterExternalLoginModel { UserName = result.UserName, ExternalLoginData = loginData }); |
with the following lines:
// User is new, ask for their desired membership name string loginData = OAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId); ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName; ViewBag.ReturnUrl = returnUrl; var model = new RegisterExternalLoginModel { UserName = result.UserName, ExternalLoginData = loginData }; switch (result.Provider) { case "facebook" : case "google" : { model.Email = result.UserName; model.UserName = "" ; break ; } case "twitter" : { model.Email = "" ; model.UserName = result.UserName; break ; } default : break ; } return View( "ExternalLoginConfirmation" , model); |
Facebook and Google provide email as user name, so email is assigned for these providers.
In ExternalLoginConfirmation view, add following Email in form:
@Html.HiddenFor(m => m.Email)
It will post Email also when form is submitted. In ExternalLoginConfirmation method, To save email for new user,replace the following lines:
// Insert name into the profile table db.UserProfiles.Add( new UserProfile { UserName = model.UserName }); db.SaveChanges(); OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName); OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false ); return RedirectToLocal(returnUrl); |
with these lines:
// Insert name into the profile table user = new UserProfile { UserName = model.UserName }; db.UserProfiles.Add(user); db.SaveChanges(); OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName); if (!String.IsNullOrEmpty(model.Email)) { var oauthItem = db.OAuthMemberships.FirstOrDefault(x => x.Provider == provider && x.ProviderUserId == providerUserId && x.UserId == user.UserId); if (oauthItem != null ) { oauthItem.Email = model.Email; db.SaveChanges(); } } OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false ); return RedirectToLocal(returnUrl); |
This will save email in database for new user. Now if same user wants to add other external provider then in ExternalLoginCallback method, replace following line
OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, User.Identity.Name); |
with following lines:
OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, User.Identity.Name); if (result.Provider == "facebook" || result.Provider == "google" ) { using (UsersContext db = new UsersContext()) { UserProfile user = db.UserProfiles.FirstOrDefault(u => u.UserName.ToLower() == User.Identity.Name); if (user != null ) { var oauthItem = db.OAuthMemberships.FirstOrDefault(x => x.Provider == result.Provider && x.ProviderUserId == result.ProviderUserId && x.UserId == user.UserId); if (oauthItem != null ) { oauthItem.Email = result.UserName; db.SaveChanges(); } } } } |
It will save email in OAuthMembership table when new provider is added.
We have implemented to save email from OAuth/OpenId Providers. If you like this post, don’t forget to share. If you have any query, feel free to ask in comment box.
No comments:
Post a Comment