Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicit user creation with Authlogic and Authlogic OAuth plugin

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 don't seem to care about having only a single button for sign in. :(

like image 532
eploko Avatar asked Jul 24 '09 20:07

eploko


1 Answers

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.

like image 113
eploko Avatar answered Sep 21 '22 20:09

eploko