简体   繁体   中英

Devise + Omniauth + Twitter. How to get user information?

I'm trying to create a system that allows user to signup using Twitter. I was following this tutorial:

http://www.orhancanceylan.com/rails-twitter-and-facebook-authentications-with-omniauth-and-devise/

Now I'm stuck in the Twitter's callback action. I've checked if there's already an authentication and if the user is already logged and this methods should work fine, now I'm creating the "new user" action, that should create both authentication and user.

I want the user to click on "Login with Twitter" button, then the script should get Name, Username, Bio and Location from Twitter's callback. Then the user should be redirected to a "2nd step page" where it should provide an e-mail and a password to complete the registration.

In my authentication controller I wrote this:

  user = User.new

  user.name = omni['info'].name
  user.username = omni['info'].nickname
  user.location = omni['info'].location
  user.bio = omni['info'].description

  user.apply_omniauth omni
  user.avatar_from_url omni['info'].image

  session[:omniauth] = omni.except('extra')

  #What should I do here?

I've already tried redirecting to new_user_registration_path as it says the tutorial but then I get the original signup form. I created a different view with only e-mail and password fields but my big question is:

How can I get Twitter user's information and pass this data to the create method of Devise controller?

@khanh 's answer is slightly wrong: I don't have enough reputations to comment so I'll post it here, sorry

uid can be get in that way(@khanh), but nickname should be in this way

puts env['omniauth.auth']['info']['name']

The ['info'] Hash include these:

  • description ,
  • email (which is nil in twitter),
  • image (profile image link),
  • location ,
  • name (user's name of twitter),
  • nickname (@username),
  • urls (Hash of URLs).

The whole ['omniauth.auth'] looks like this:

#<OmniAuth::AuthHash 
   credentials=#<OmniAuth::AuthHash
                  secret="some-secret-xxxxxxxxxxxxxxxxxxxxxx"
                  token="some-token-xxxxxxxxxxxxxxxxxxxxxx"
   >
   extra=#<OmniAuth::AuthHash 
            access_token=#<OAuth::AccessToken:0x0055cab742d2b8 
                            @token="some-token-xxxxxxxxxxxxxxxxxxxxxx", 
                            @secret="some-secret-xxxxxxxxxxxxxxxxxxxxxx", 
                            @consumer=#<OAuth::Consumer:0x0055cab760ba58 
                                          @key="some-consumer-key-xxxxxxxxxxxxxx", 
                                          @secret="some-consumer-secret-xxxxxxxxxxxxxx", 
                                          @options={
                                            :signature_method=>"HMAC-SHA1", 
                                            :request_token_path=>"/oauth/request_token", 
                                            :authorize_path=>"/oauth/authenticate", 
                                            :access_token_path=>"/oauth/access_token", 
                                            :proxy=>nil, 
                                            :scheme=>:header, 
                                            :http_method=>:post, 
                                            :oauth_version=>"1.0", 
                                            :site=>"https://api.twitter.com"
                                          }, 
                                          @http=#<Net::HTTP api.twitter.com:443 open=false>, 
                                          @http_method=:post, 
                                          @uri=#<URI::HTTPS https://api.twitter.com>
                            >, 
                            @params={
                              :oauth_token=>"some-token-xxxxxxxxxxxxxxxxxxxxxx", 
                              "oauth_token"=>"some-token-xxxxxxxxxxxxxxxxxxxxxx", 
                              :oauth_token_secret=>"some-secret-xxxxxxxxxxxxxxxxxxxxxx", 
                              "oauth_token_secret"=>"some-secret-xxxxxxxxxxxxxxxxxxxxxx", 
                              :user_id=>"000000000", 
                              "user_id"=>"000000000", 
                              :screen_name=>"sample_user", 
                              "screen_name"=>"sample_user", 
                              :x_auth_expires=>"0", 
                              "x_auth_expires"=>"0"
                            }, 
                            @response=#<Net::HTTPOK 200 OK readbody=true>
            > 
            raw_info=#<OmniAuth::AuthHash 
                        contributors_enabled=false 
                        created_at="Fri Sep 02 23:56:11 +0000 2011" 
                        default_profile=false 
                        default_profile_image=false 
                        description="Hi my name is Sample and I'm a Twitter user." 
                        entities=#<OmniAuth::AuthHash 
                                    description=#<OmniAuth::AuthHash 
                                                    urls=[]
                                    > 
                                    url=#<OmniAuth::AuthHash 
                                            urls=[
                                              #<OmniAuth::AuthHash 
                                                 display_url="link.to/my/blog_or_someth…" 
                                                 expanded_url="http://link.to/my/blog_or_something.html" 
                                                 indices=[0, 23] 
                                                 url="https://t.co/SAMPLE007"
                                              >
                                            ]
                                    >
                        > 
                        favourites_count=690
                        follow_request_sent=false 
                        followers_count=42
                        following=false 
                        friends_count=34 
                        geo_enabled=false 
                        has_extended_profile=false 
                        id=000000000 
                        id_str="000000000" 
                        is_translation_enabled=false 
                        is_translator=false 
                        lang="ja" 
                        listed_count=24 
                        location="Tokyo, Japan" 
                        name="Sample user" 
                        notifications=false 
                        profile_background_color="DBE9ED" 
                        profile_background_image_url="http://abs.twimg.com/images/themes/theme17/bg.gif" 
                        profile_background_image_url_https="https://abs.twimg.com/images/themes/theme17/bg.gif" 
                        profile_background_tile=false 
                        profile_banner_url="https://pbs.twimg.com/profile_banners/0000000000/00000000000" 
                        profile_image_url="http://pbs.twimg.com/profile_images/010101010101010101/LeoGT5Xu_normal.png" 
                        profile_image_url_https="https://pbs.twimg.com/profile_images/010101010101010101/LeoGT5Xu_normal.png" 
                        profile_link_color="CC3366" 
                        profile_sidebar_border_color="DBE9ED" 
                        profile_sidebar_fill_color="E6F6F9" 
                        profile_text_color="333333" 
                        profile_use_background_image=true 
                        protected=false 
                        screen_name="sample_user" 
                        statuses_count=61468 
                        time_zone="Tokyo" 
                        url="https://t.co/SAMPLE007" 
                        utc_offset=32400 
                        verified=false
            >
  >
  info=#<OmniAuth::AuthHash::InfoHash
          description="Hi my name is Sample and I'm a Twitter user."
          email=nil
          image="http://pbs.twimg.com/profile_images/010101010101010101/LeoGT5Xu_normal.png"
          location="Tokyo, Japan"
          name="Sample User"
          nickname="sample_user"
          urls=#<OmniAuth::AuthHash
                  Twitter="https://twitter.com/sample_user"
                  Website="https://t.co/SAMPLE007">
  > 
  provider="twitter"
  uid="000000000"
>

so you can get the username from

env['omniauth.auth']['extra']['raw_info']['name']
env['omniauth.auth']['extra']['raw_info']['screen_name']

too. I'm not sure which (from ['info'] and ['raw_info'] ) is the better way to go. But ['raw_info'] seems to give us more information than the former does.


EDIT: yeah-yeah-yeah, it was all written in the wiki!

Auth Hash Schema - intridea/omniauth Wiki | Github

But there's no concrete case for Twitter, so maybe my answer is useful after all ! :)

You can do it with the following steps:

devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }

users/omniauth_callbacks_controller.rb :

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
   def twitter   
    # show twitter account information
    puts env['omniauth.auth']['uid']
    puts puts env['omniauth.auth']['nickname']
  end
end   

To redirect the user to another form to input their email, we can sign them up using this method.

After the user is redirected and if it's a new user, we will render a form TwitterForm for the user to input an email to complete the registration.

Next, the form will be submitted to a custom action that we specified, in my case I put it under UsersController that'll complete the sign up process using the Twitter session data and the email that the user inputted.

Full answer over here

Devise CallbacksController

 def twitter
        auth = request.env["omniauth.auth"]
        @user = User.where(provider: auth.provider, uid: auth.uid).first_or_create
        if @user.persisted?
            flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Twitter"
            sign_in_and_redirect @user, :event => :authentication
        else
            @form = TwitterForm.new 
            session["devise.twitter_data"] = request.env["omniauth.auth"].except("extra")
            render :layout => 'none'
        end
    end

UsersController

def twitter_register
    @form = TwitterForm.new(params[:twitter_form])
    if @form.valid?
      email = params[:twitter_form][:email]      
      @user = User.from_twitter_omniauth(session["devise.twitter_data"],email)
      if @user.persisted?
        flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Twitter"
        sign_in_and_redirect @user, :event => :authentication
      else
        redirect_to register_path 
      end
    else 
      render 'callbacks/twitter',layout: 'none'
    end
  end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM