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.
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.