Now I'm looking for more than two days for a solution for the following problem. I have an EmberJS client-side javascript app, that uses my server-side Rail RESTful API. Authorization is done via access token.
Now I want to give the user the ability also to login with OAuth2 from Google, Twitter and so on. Discourse uses OmniAuth for third party login, but OmniAuth needs a server side session. Because I build a RESTful and stateless API, I didn't want to use a session on the server. So I decide to build it on my own with help of Google+ Sign-In for server-side apps, but the example there also uses a session.
Does anyone have a solution for a similar problem or some hints for solving my problem?
EDIT 1
Because OmniAuth doesn't fit well in my setup, I started to create a own implementation for third-party OAuth2 login following Googles help. Everything works fine at the moment. But I didn't implement the CSRF protection explained under heading 1. Create an anti-forgery state token
on the site from Google mentioned above. My problem is, how could I store this CSRF token without using a session. Would it be enough to store it in Database and look it up in the callback request from Google later?
EDIT 2
I followed this railscast. There three possible cases, if a user want to sign-in with an extern oauth provider:
- The user already signed-up with extern oauth, then he got a Doorkeeper access token.
- The user has an account, but didn't sign-in with extern provider before. After oauth flow we only have to create a new authentication for this user.
- The user didn't have an account and now tries to sign-in with extern provider. Here we have to redirect the user to the sign-up page, we also can use informations from the oauth provider to pre-fill in the sign-up form, but until the user pushes the sign-up button, we have to save the authentication.
My question now is, what is a good practice to save such informations (authentication, oauth2 csrf-token) server-side in a REST API, without using a session. I have to save these information on the server, because the user should not have the possibility to manipulate them on the client-side.
Maybe I also should create a new question for pros and cons of token and session authentication with Ember apps and possible solutions for both?
Here is my authentication controller:
class Api::V1::AuthenticationsController < ApplicationController
def oauth
# redirect to google/twitter/...
login_at(params[:provider])
end
def callback
# callback from provider
provider = params[:provider]
if @user = login_from(provider)
doorkeepter_token = Doorkeeper::AccessToken.create!(:resource_owner_id => @user.id)
@data = {
access_token: doorkeepter_token.token,
user: @user
}
render 'oauth/complete'
else
# user has no account, create a new one
@user = User.new
@user.email = @user_hash[:user_info]['email']
@user.authentications.build(:uid => @user_hash[:uid], :provider => params[:provider])
@user.oauth_pending!
if @user.save
doorkeepter_token = Doorkeeper::AccessToken.create!(:resource_owner_id => @user.id)
@data = {
access_token: doorkeepter_token.token,
user: @user,
errors: @user.errors
}
render 'oauth/complete'
else
render 'oauth/error'
end
end
end
end