Register/Loginwith facebook and google on mobile and web data store - asp.net-web-api

I want users to be able to log in with facebook/google via a mobile app(android and ios) and/or a website(built with asp.net MVC)...
What should my database be storing to make authentication work across mobile app and website? userId , google/facebook token?
Im unsure how to go about saving user information.
Should I combine this with OWIN? I dont know much about asp.net identity but have seen that it fairly straight forward with 3rd party providers....the question is if i login from the mobile app for the first time should i programatically add the new user to the database?
So far I think this seems like the best link: http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/
but I'm hoping theres a simpler way.
Im getting google/fb tokens and sending them to the server to get the ids of the users...
What do i need to do here, so that if the google/fb user logs in through the web, they will be recognised as the same user.
It seems like MS have made it so easy to use ASP.Net Identity to set up social login for the web, but have ignored how that can be used with mobile to use a sql server db to store user/membership details...
Just trying to work out the best way of managing users for mobile and web as one

This link describes everything you are looking for http://www.asp.net/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on
What you have to store in the database in order to check if user already exist in your database or not can be get from the response you will get from Facebook or Google after a users credential verified, Facebook & Google must be giving the details of the users back in response. like Email Id, Date of birth etc., you can save these details in your database and at every login check it user already exist or not and register accordingly.
Details that comes in response is mentioned in another post WebApi ASP.NET Identity Facebook login
public class FacebookLoginModel
{
public string token { get; set; }
public string username { get; set; }
public string userid { get; set; }
}
public class FacebookUserViewModel
{
public string id { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string username { get; set; }
public string email { get; set; }
}

It's relatively straightforward for Google Sign in.
The easiest way is for you to store the unique ID in your local database that Google returns for each account that you authenticate with it.
You can call the getSignInAccount method after the sign-in intent succeeds.
Auth.GoogleSignInApi.getSignInResultFromIntent(data);
GoogleSignInAccount acct = result.getSignInAccount();
String personName = acct.getDisplayName();
String personEmail = acct.getEmail();
**String personId = acct.getId();**
Uri personPhoto = acct.getPhotoUrl();
And whether the person signs in from the phone or the mobile, you know it is the same person. More details at https://developers.google.com/identity/sign-in/android/people
In any case, you will have to programmatically store the user in your database every time someone new logs in. So you will have to store their personID as an additional field to authenticate them overtime.

Related

How to tell default value from clearing with FromBody in ASP.NET Core Web API

I have coded in C# for years, but I am new to ASP.NET Core. I have created a Web API where I generated my Model classes from an existing database and used the scaffolding to create a Controller for each model that gives me Get, Put, Post, and Delete. My question is how do I know if the caller is clearing a value vs the value is the default for the C# object?
For example, in Vue.js I send
var sendstuff = {userName: "TestUser1", userId: 7, email: null};
In C#, my user object has
public int UserId { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string FavoriteColor { get; set; }
In my controller, my put method begins
public async Task<IActionResult> PutUsers([FromRoute] int id, [FromBody] User user)
My User instance in the database is TestUser1, 7, test#test.com, purple. The User that comes into PutUsers is TestUser1, 7, null, null.
At this point, I want to compare the values sent in for user 7 to the values in the database for user 7. However, since both FavoriteColor (that is not sent) and Email (that is sent) look the same as they both appear as null, how do I know whether or not it should be changed? I want test#test.com to be cleared, but I want purple to remain.
It seems my only other option is to have Vue.js send in every single column for every table, with the values either the original value I don't want changed or the new value. This doesn't feel right.
Am I missing something?
Thanks in advance!
The only way I can think of is to accept a Generic Json-Object and checking wether or not the Properties are set.
Most Json Frameworks will be able to cast to a specific Object from the Json Object so you won't even need to change your further code.

How to Authenticate using MVC5RC/RTW with existing database

I originally asked this question when Identity was in beta. The classes and interfaces have changed considerably since then and it appears the RTW version has some modifications again over the RC version. In principle I need to achieve the following.
authenticate the local login against my usertable tblMembers which contains the userid field and password which are the two items I need to authenticate.
have access to my tblMember record/class via the Controller.User property (Prior to MVC5 identity I had achieved this using the membership provider methods.) regardless of if the user logged in via the localuser method or via one of the other OAuth providers (Twitter, Google etc).
Ability to display my own custom username despite the login method. Local users login with a userid 1234567 and a password, ideally I would like to display "John Smith (1234567)" regardless of the authentication method (local/Twitter etc)
Initially I'm unsure as to what my memberclass should be inheriting from It appears from the
aspIdentitySample project that I should be using IdentityUser?
public partial class tblMember
{
public int id { get; set; }
public string membership_id { get; set; }
public string password { get; set; }
....other fields
}
Are there any new or updated examples of integrating your existing database/user tables with the ASP.NET Identity system?
I am also adding the identity tables to my database. If you create a new web project in visual studio 2013 you will see that now in RTM everything works better than RC plus you will see the
following table
public class ApplicationUser : IdentityUser
{
}
So Instead of ApplicationUser you can call your table tblMembers
public class tblMembers : IdentityUser
{
}
your table tblMembers will inherit Id Username Password security stamp and a discriminator column saying this is a tblMemeber
without making custom classes for authentication the easiest thing to do would be just to make the username the combination of your old usernames and userids. Then store the users real name or old username without the user id in a separate column.
have the users register with the built in user login and they can go to manage account and click use another service to log in. This will link the Google account to their regular account, so no matter which one they use it will log them in to the same account. If you have users with connected table information, I suggest you seed your table with all the users with something similar to the register method found in the template.Then just match the new combined username and Id to the old ones and populate data where needed in sql management studio.
Again a lot of issues in RC with extending IdentityUsers have been fixed. Microsoft is already adding more features to the identity user store and this tutorial http://www.windowsazure.com/en-us/develop/net/tutorials/web-site-with-sql-database/ is supposed to be updated soon. I plan on making my own walk through when i'm done changing my database but for now I hope my suggestions even though they are a simpler solution than you might want to implement.
You can do this easily by modifying the IdentityModel.cs as per the below:
Override OnModelCreating in your DbContext then add the following, this will change AspNetUser table to "Users" you can also change the field names the default Id column will become User_Id.
modelBuilder.Entity<IdentityUser>()
.ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");
or simply the below if you want to keep all the standard column names:
modelBuilder.Entity<IdentityUser>()
.ToTable("Users", "dbo")
Full example below (this should be in your IdentityModel.cs file) i changed my ApplicationUser class to be called User.
public class User : IdentityUser
{
public string PasswordOld { get; set; }
public DateTime DateCreated { get; set; }
public bool Activated { get; set; }
public bool UserRole { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<User>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUser>()
.ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");
modelBuilder.Entity<User>()
.ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");
}
}
Please note i have not managed to get this working if the current table exists.
Also note whatever columns you do not map the default ones will be created.
Hope that helps.
I'm starting to think (partially due to the lack of information in this area), that it may be easier to user the default identity classes, but to provide referential integrity to my own user table from the AspNetUsers table.
If i add a custom linking field into the AspNetUsers table is it possible to access my tables from the Controllers.User property? i.e. Controller.User.tblMember.Orders?

MVC3 Registration form and model

I have a question regarding the MVC 3 and more exaclty about the views and models. I want to mention that I'm new to MVC so I'm oly learning it.
Basically for example lets take te registration form:
I have a controller, view and model, to register a new user.
AccountController
Register.chtml
AccountModel => RegisterationModel
Now, in registration model i have all the datamembers with data annotations, for example:
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
This are then rendered in view.
What bothers me, or I don't really understand how to do it properly:
Ok I have RegistrationModel ... but later on, for example if i want to render the profile of the user, should i call registrationmodel again or then it will be profilemodel? So basically I will have a lot of the same models just to render the same thing ... no?
Can't I have then one general Model, something like user, and then User i can pass with RegistrationModel/ProfileModel to view.
Maybe it is a bit difficult to understand what I mean exactly, but how I imagine it: for example a user submits a form, everything is parsed and a User object is created with all the data members, then this User object is pased to DAL, where it is submitted to DB. Later on someone visits the profile of this user and the DAL, will return User object back which is then displyed.
The answer to your question is no you should generally separate your domain models from your view models. Consider a following scenario. Let's say you have a User model and your business logic allows you to both add a new user and edit an existing user. Let's say your user model looks like this:
public class User
{
[Required]
public int? UserId {get; set;}
[Required]
public string LastName {get; set;}
[Required]
public string FirstName {get; set;}
[Required]
public string Password {get; set;}
public bool IsAdmin {get; set;}
}
Now in order for your user model to be valid you have to have User ID to make the user identifiable. When you're inserting a new user you don't need the ID because that is something database will automatically take care of on insertion. However when you're doing an update of the user then you need the user ID to be populated. So now you have a model that in one case requires a field (UserId) but in another it doesn't. How are you going to handle that?
The answer is view models and this is the reason why they exist and why it's advised to create one for each entry form you have in your project. In this case you would end up with a different insert and update user view models. I know it's tedious to convert these view models into the underlying domain models but there are libraries to help you do that automatically like AutoMapper (https://github.com/AutoMapper/AutoMapper/wiki/Getting-started).
2nd and probably more serious problem is over posting. Suppose you are using the above User model to edit the user in your database. Now the model has an IsAdmin field which specifies whether user is an admin or not. Now your edit user view will omit this field since you don't want the general user to be able to make themselves an admin. But let's say you're dealing with a really smart user and he make a hidden field with id of IsAdmin and makes it value to be true:
<input type="hidden" id="IsAdmin" value="true" />
and then he/she posts the form to your save user url. Because you are using the domain logic user model which has IsAdmin property this hidden field will map to your model and this user just managed to make himself/herself and admin in your site. This is precisely why you need view models so this scenario can never happen.

MVC3 and EF // Add an Image to an existing database object

Model
public class Discount
{
public int DiscountId {get; set;}
public string Name { get; set; }
public string Information { get; set; }
}
I want to add an image to this model that does not exist yet. For instance when a user browses to the CRUD page Create View, the user can create a new Discount and it will have the option to browse/upload a new image that will be identified with the new discount created.
File Upload ASP.NET MVC 3.0
has taught me how to upload images in MVC3 but I am needing assistance on mapping this uploaded image to a specific discount (DiscountID).
I'm not sure what is your actual requirement is, but you can give image name based on the DB id. Eg. Img0001 etc.. Also, save the path of that image file in the related record in the DB.

How to get All users in web application by setting role as search parameter - asp.net mvc

In my MVC application I am using membership service . I need a page to list the users. But there are 1000's of users are in my application. So i don't need to display all of them in one page.
I am planning to give a search option .I mean admin user can search by specifying user role and how many users can show in one page.How can i do this ? Any ideas?
current code
Model
public MembershipUserCollection Users { get; set; }
Controller
model.Users = Membership.GetAllUsers();
But i am getting all users in the application.
You probably want to query your role provider:
public ActionResult Foo()
{
string[] usernamesInRole = Roles.GetUsersInRole("some_role");
...
}

Resources