Register user and authenticate request on server using facebook - ruby-on-rails

I have an app that uses ember simple-auth with torii and devise extensions.
My backend is on rails with devise to protect ressources. (BTW, I am a rails noob)
My goal is that I want users to be able to register/login with facebook, but I also need to authenticate requests made to my backend. (e.g. A user can only access his account info)
If I take each authenticators by itself, it works fine. For example, I can authenticate a user through facebook. And I can register and sign in on my rails server. However, I want the registration to happen through facebook( No forms to fill for the user)
The questions I have are:
- What information should I persist on my server so that I can identify a facebook authenticated user and authorize him to access ressources?
- Is there a more straight forward way to do it ?
- Does it even make sense to have 2 authentication processes ?

If you're using Facebook login the only data you need to persist is the App-scoped User ID (https://developers.facebook.com/docs/apps/upgrading#upgrading_v2_0_user_ids)
That's a unique ID generated for the user in your App. When the user logs into your App with Facebook you only have to get back this ID and then match it in your database.
I hope it helps.

Related

Rails automatically send tweet after twitter authentication

I have an ruby on rails application that uses devise and omniauth-twitter gem to handle user management and authenication. Users can only login through twitter. I already have the application authenticating, however I would like to allow users to write a tweet; and if they are not logged in, authenticate through twitter then have the tweet they wrote before the authentication post to twitter.
I was wondering what is the best way to go about doing that?
Can I capture a request if a user is not logged in, log them in, then preform the captured request?
Just not sure how to go about doing this.
Thanks.

OAuth combined with custom users

I have a website where users can create an account and log in. This is stored in a database on the server. I also want users to be able to log in with Facebook etc, and thus skip the account creation. I don't know how to combine this and keep it persistent in the database. Any good examples on this use case?
Let's first see how logins work in general. When a user is logging in for the first time, a session id is generated for the user and is stored in the browser of the user as a cookie (note that there are mechanisms to store session id without a cookie, but let's assume you require a cookie for simplicity).
For subsequent requests to other pages in the same website, the cookie is also sent along. With this cookie (which has the session id), the unique user can be identified.
So, all that you require to know to identify a user in the server side (upon a web request) is the session id.
Having said that, if you want to include facebook etc into the login mechanisms, you need to do two things:
Connect your website with facebook (you will require a facebook developer account and some keys. Look here). When you do this successfully, if the user selects facebook login, your website should redirect to facebook login page and once the user logs in into facebook account, facebook will redirect back to your website with a token. This token is an indication that the user is a 'real' user. If required, you can use the token to get more details (such as facebook id, email address, name, etc.) from APIs facebook.
The second step is the same for any authentication flow. You need to generate a session id for use by your server and then save the session id in cookie.
What I have specified is the general flow on how your requirement could be achieved. The mechanics of how to do this will depend on the server side technology that you are adopting (such as ASP.NET, Ruby, etc.)
Additionally, if your website requires storing information about the user behavior / user activity, you may need to additionally check if the user logged in via FB already exists in your database. If not present, you can store the user's facebook id or something to uniquely identify the user later. With this as the primary key / user id, you can store user activity (such as inserting a record in orders table if the user purchases a product).

Using OAuth but store extra information in my own DB

I've been looking into OAuth for a while, but haven't implemented it in any of my applications yet. I'm having trouble really understanding the full concept, so I still have a few questions that I haven't found an answer to, so I hope that anyone can help me.
I want a user to be able to start my application (WP8), login to facebook / twitter / microsoft / ... .
When he gets authenticated, I want to actually save this user to my own DB so I can add some user specific stuff like preferences, posts, ... .
What do I need to save in my own DB to specify a user?
Do I need to save the token itself or is this something that will be invalidated after a while? Or do I need to specify the user's name? With other words: What can I use as a unique identifier?
And what happens when a user would authenticate with for example facebook and he deletes his account?
And one more question, would you ever allow a user to connect to an application with 2 different service providers? If so, how would you make the coupling of these 2 providers to 1 user in your own DB?
I hope my questions are clear enough!
If not, don't hesitate to ask for more information!
Kind regards,
Gert
I assume that you have your own back-end where you authenticate your own users and your WP8 application is just a client.
First, let me distinguish between a user credential and a user profile. User credential is something that validates who the user is, e.g. username/password, facebook user id supplied with a valid auth token. User profile, is what you store in your own database about the user.
You also need to distinguish between a token you use to authenticate the user and the AccessToken Facebook needs to grant you access to user's data.
So... to answer your questions:
What do I need to save in my own DB to specify a user?
Create a record with user data (like preferences, and your unique user ID), and user's login method (e.g. Facebook) and credential (e.g. Facebook's user ID). This is your user's profile.
Do I need to save the token itself or is this something that will be invalidated after a while?
You can also store the Facebook AccessToken here if you've been granted "offline access" privileges by Facebook, but that is used for Facebook's access by you... not by the user's access to your app/back-end. For user's access you could just use a mechanism similar to cookie-based authentication - it's up to you. You could use the AccessToken as a kind of a "cookie", but you would need to always check against Facebook that it's valid.
With other words: What can I use as a unique identifier?
You could treat Facebook's ID as unique (so long as you never allow another account in your user profile DB to link with the same Facebook account)
And what happens when a user would authenticate with for example facebook and he deletes his account?
It's a good idea to have users still create a username/password combination that works with you site and only rely on Facebook login for convenience. In any case, Facebook provides a "Deauthorize Callback URL" when you create an app profile on Facebook. This is called when a user deactivates your app or deletes an account with Facebook. When you receive this call, you could send your user an email when an auth link to setup a different credential so as to not lose access.
would you ever allow a user to connect to an application with 2 different service providers? If so, how would you make the coupling of these 2 providers to 1 user in your own DB?
Sure, you could do that. Say you'd want to allow a Twitter account as well. You'd need to add a Twitter user ID field to your user profile database.
Here's another tip: create an ASP.NET MVC4 project in Visual Studio - the template includes an example of how to set up a user profile database with OAuth login.
Hope it gives you the high-level overview to investigate further.

How does Devise and OmniAuth work together?

I have some questions on how Devise and OmniAuth work as I couldn't find any clarification on these one's I'm about to ask. Here I'll use Facebook as an example.
If I wanted users to be able to sign in using only Facebook and not be able to create an account, could I still use Devise? Does it still have a purpose?
If I were to go the Facebook route above, I see in my database it saves a "user" but does that user stay with that same ID or does it delete/change every time they re-sign in and they become "new users"?
What does using OmniAuth only mean for my application? It's basically the same as Devise right? Just going through a third party?
Right now, I created an app with just the omniauth-facebook gem and I'm thinking it's the same as Devise but just does the all the work for me (name, email, location, etc.) as if it was just a replacement.
The reason I ask these questions is because I don't want to end up assigning a user to a resource and it can't find him because it keeps changing the ID of said user because OmniAuth treats it like some type of sessions table (logging in) and not the actual user's table (save columns permanently). I want the the Devise functionality but to simply replace it with Facebook. I hope I'm making sense.
Thanks.
Well, Devise is an user management gem, so it will manage all your user sessions informations, password, password reset, confirmation ....
Everything that is related to registrations and login will be handled by devise.
Now if you want to add omniauth login (Facebook,Twitter,....) you have to use omniauth to take care of the login using any provider like Facebook.
Basically Omniauth allows you to link facebook users to your app users but works perfectly well with Devise.
For example when a user is created using Facebook signup it's created in the User Tables which has both devise and omniauth information. So your user will also be able to login using his email and create a password afterwards.
Facebook provide a unique ID for each user which is stored in your database, so when one user is created with Facebook login it has both an email address to use with Devise and the Facebook ID to use with Omniauth to login.
You can use both together with the same user model and manage how you want to do it.
You can for example let user to create a password after omniauth login so that they can login afterwards with either omniauth or devise.
Or you can also let existing user link their facebook account for future use.
I hope this is clear enough, if you have anymore questions let me know !
https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
Your user is your user. Omniauth provides an interface to your application which abstracts the whole Oauth protocol logic from you. But it's like this: your user signs in with his facebook account and gets a token. This token is bound to your user in your app, and that's how omniauth identifies him.
No, Omniauth is not the same as devise. Both try to address the same purpose (user authentication on your app), but while devise bundles the whole inner logic of identity provision in your app (creating an account, registering an account, registration emails, recovering an account, managing sessions, signing in, signing out...), Omniauth provides only an interface to link your user account to an authorized third-party account and access its information, and the rest you have to do yourself.
But they can work together (use devise to create accounts local to your app, use omniauth to link those accounts to third-party accounts and (maybe) fill some basic information for the user account based on his third party account, like facebook name, email, photo).
The sessions repository is independent of your users table, so there is no possibility of happening what you stated in the last paragraph.

Multi login problem using Twitter and Facebook Oauth

I am adding Twitter and Facebook login to a MVC 3 test application using TweetSharp and Facebook C# SDK.
Currently when a user signs in using Twitter I create a user account for that user in a user table and store the id, token, and token secret in a separate table with a foreign key to the user table. Since the id, token and token secret do not expire I can quickly locate the right user account when the user logs in next time using Twitter.
What if the very same user logs in using Facebook next time? Since Twitter does not provide email in their API and I therefore have no common piece of information to tie a user account to either Twitter or Facebook I assume I have to create a new user account for a Facebook login? Does anyone have any experience with this? Are there any ways to solve this?
I identify each user internally with a unique key. I check cookies for the user key when any user hits the site. If there's no cookie I create a new key. add it to the user database and set a new cookie. Once a user completes registration the first time by logging in with any of Facebook, Twitter or .Net membership , that key is forever married to that user.
So when an existing Twitter user logs in for the first time with Facebook, we know who they are because their user key exists. It is basically the same solution as macou suggested. Macou's has the plus of working on a new machine or if cookies are cleared, the cookie solution has the plus of not requiring additional user input.
Not really a solution, more of a work around. I was faced with the same problem and ended up forcing the user to complete thier account profile by asking for their email address before allowing them to proceed any further. This meant that if the email address coming back with the Facebook auth matched the email address created with the twitter signin then I didn't need to create another account.
The bigger difficulty was coming the other way, if the account was created by the facebook auth first. It meant an untidy marry up of accounts.
To be honest the information we got from allowing users to sign in with twitter was not worth the effort and in the end finished up only allowing Facebook auths. I'm not sure how important twitter is to your solution.
Not the perfect answer I know, but I thought I would share my experience.
You can't use just a cookie because I can login as facebook then my wife login as twitter using the same browser, you shouldn't link the two accounts in this case.
I think you need to do more than that:
Use a cookie then
Use name/first name/login name/... to see if they match.
Example:
Cookie id: 18459439731114330636, find user with id = 18459439731114330636. Found, go to 2, not found, go to 3.
Is username/first name/last name/... matches the current user? if yes, link accounts. if not, go to 3.
Create a new user.

Resources