views:

2101

answers:

2

I'm trying to write a simple OAuth consumer app in Rails. I'm using Authlogic for handling authentication and the Authlogic OAuth plugin to do the oauth thing.

The oauth plugin provides a couple of helpers to render the sign in button: oauth_login_button and oauth_register_button. Together with the Authlogic logics and the plugin's request filters these two buttons somehow create the session/user.

What happens next is as follows: - if I use the oauth_login_button helper, then the session object fails to save as there's no such user locally. - if I use the oauth_register_button helper, then, on any login after the first one, Rails complains that the token has been taken already... that means it can't create the second copy for the same user, which is right.

The issue is: I don't want to have BOTH Register AND Login buttons on my site.

On the user side, what I want to achieve is a single button on the start page, saying smth. like "Sign In with Twitter", which the user must click to proceed to inner pages of the site.

On the server side, I want to implicitly create the local user account, if the user is a first time visitor to my site.

Any hints on how to do this?

All the samples on Authlogic+OAuth I was able to find doesn't seem to care about having only a single button for sign in. :(

+10  A: 

Seems like I'm going to answer the question myself.

I use the following code to generate the Sign In button (in HAML):

- form_tag({:controller => "users", :action => "create"}, {:method => "post"}) do
  = oauth_register_button :value => "Sign In with Twitter"

and then I simply create the user's session object in the create method of the UsersController class, if the user already exists:

def create
  @user = User.new(params[:user])
  @user.save do |result| # LINE A
    if result
      flash[:notice] = "Account registered!"
      redirect_to some_inner_path
    else
      unless @user.oauth_token.nil?
        @user = User.find_by_oauth_token(@user.oauth_token)
        unless @user.nil?
          UserSession.create(@user)
          flash.now[:message] = "Welcome back!"
          redirect_to some_inner_path        
        else
          redirect_back_or_default root_path
        end
      else
        redirect_back_or_default root_path
      end
    end
  end
end

If the user is a first time visitor, then the user object is successfully saved in the LINE A. And if it's not and there's an oauth token available, then we try to fetch the user from the DB and log him/her in.

E-ploko
Exactly what I was just looking for. Thanks
Marc Roberts
this is very helpful
Anurag
Thank you very much :)
Chris Salij
A: 

Great tip, Thanks

Rafael Oshiro