I am writing a user creation system for an iOS app and a web app (ie a user can be created from mobile app or web frontend) using Ruby on Rails. I am not interested in using a system like Devise.
I haven't done this in a couple of years so just want to make sure that my ideas are current and make sense.
Steps / Assumptions
In the case of email login, the user will just post the following json:
{
user:{
email:'[email protected]',
password:'testpassword',
}
}
I will be using Rails has_secure_password to hash the values.
and will return
{
user:{
id:23,
auth_token:'md5value',
}
}
For web, we will pass the auth_token as a cookie value. For the iOS app, the auth_token will be passed as a custom HTTP header field such as "X-auth_token"
{
user: {
is_facebook_login: true,
fb_email: '[email protected]',
fb_auth_token: 'abigvaluefromFB'
}
}
On the server, we will ensure that they are passing a valid fb_auth_token credentials by calling facebook with
def self.verify_facebook fb_auth_token
result = Net::HTTP.get(URI.parse("https://graph.facebook.com/me?access_token=#{fb_auth_token}"))
obj=JSON.parse(result)
obj["email"]
end
and verifying that the fb_email sent in the initial request corresponds to the email provided back by facebook.
Here's the steps with a corresponding diagram:
STEPS
Not worried about right now, if they change their facebook email, tough luck. If they login via Facebook and then want to login via email / pwd, tough luck.
on our end, we will generate an auth_token (an MD5 string), and send it back to the client which now manages authentication. From that point on, we will send a custom HTTP header X-auth_token
We will respond with
{
user:{
id:23,
auth_token:'md5value',
}
}
and the iOS app will write the auth_token to the keychain via https://github.com/kishikawakatsumi/KeychainAccess
Does the above scenario seem reasonable for user creation?
All the ideas you describe look valid for me, but the whole description looks incomplete.
Missing parts are:
You already have a description of two processes - new user registration via email and new user registration via facebook.
On the server I would store them like this, users
table:
And I would also merge email / facebook users in scenarios like this:
If the user changes his facebook email - this doesn't break anything, we can just ignore this change if we already have the email in the users
table. So the user can still login with his old email. (Or, using additional login history, we could check that user had never logged in with email and replace it with new one).
It is also easy to provide a generate password
feature for facebook users. They can enter email and generate a password when they are logged in, so they can also login with email/password in the future.
Also you can add forgot password
feature which can generate a new password and send it to the user's email - this can be used both by email
users and those facebook
who provided the email.
If I get your idea right, you want to have a single unified method to both create new users and authenticate existing users, something like this:
It is similar for facebook, but instead of email / password we check facebook_id and verify with request to facebook.
You can also consider having separate backend endpoints - one to register new users and another one to login existing users. Because with the procedure above, if the user mis-types his email, you will create a new user which is not expected. For facebook registration / login will probably doesn't make much difference.
I assume that it is useful to allow one user to have multiple auth tokens to login from different locations, so here is the tokens
table:
Regular request looks like this:
The token expiration can be done like this:
now() - token.created_at > EXPIRATION_PERIOD
token.expired
= True + save)Some tips:
1) Remember that the facebook email is not the facebook user login email, its the profile email, If the user leaves it blank it defaults to [email protected]. This is important because you may want users to validate the registration by email, is this scenario i suggest you to use a modal to ask user to input his email after the fb registration.
2) Facebook users won't have passwords but they can change it using "forget my password" and this scenario relies on the usecase above (they need a real email address).
3) I dont know your security scenario and the kind of app you are creating. But you can always just use the fb api to retrieve user data and save it as a default user. example: get data from fb api and save user as [email protected] password: tokenWithMd5OrSomethingLikeThat userType: "facebook" . This is usefull when you are developing a small application that you will not update too soon, its way faster.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With