Retrieving Google profile picture with Omniauth on Rails 3 - ruby-on-rails

I'm starting a new Rails 3 app using Omniauth for authentication via Facebook, Twitter and Google. I can easily get the user's avatar from Facebook and Twitter, but can't find a way to retrieve it from Google, if existent.
Here's the code I use to build the authentication hash:
omniauth['user_info']['email'] ? #authhash[:email] = omniauth['user_info']['email'] : #authhash[:email] = ''
omniauth['user_info']['name'] ? #authhash[:name] = omniauth['user_info']['name'] : #authhash[:name] = ''
omniauth['uid'] ? #authhash[:uid] = omniauth['uid'].to_s : #authhash[:uid] = ''
omniauth['provider'] ? #authhash[:provider] = omniauth['provider'] : #authhash[:provider] = ''
On Twitter and Facebook this next line gets the avatar or sets to the default if not provided:
omniauth['user_info']['image'] ? #authhash[:image] = omniauth['user_info']['image'] : #authhash[:image] = 'avatar.jpg'
This doesn't work on Google and I couldn't find any documentation on that.
Any ideas?
Thanks a lot!

Try 'Omniauth Google OAuth2 Strategy' in which a commit states:
Returns name, first_name, last_name, image, email in info with :scope => 'userinfo.email,userinfo.profile'
You can view the commit here

Yes you can get the picture, though i would imagine it depends on what versions your using.
im using
rvm current
ruby-1.9.3-p194
> gem list
oauth (0.4.6)
oauth2 (0.8.0)
omniauth (1.1.0, 1.0.3)
omniauth-facebook (1.4.1, 1.4.0)
omniauth-google (1.0.1)
omniauth-google-oauth2 (0.1.13)
omniauth-oauth (1.0.1)
omniauth-oauth2 (1.1.0, 1.0.3)
omniauth-twitter (0.0.12)
I arrived here for a different reason that was due to the fact that the naming convention to access the profile properties was different from those explain in various tutorials, as such i was experiencing error completing the sign in. In fact in your question you may find that you will have the same issues.
The problem is that google has different property names from FB, Twitter, etc. so you have to account for that.
To find the properties i commented out the doing bit, and just dumped the response out. like so.
elsif service_route == 'google_oauth2'
render :text => omniauth.to_yaml
return
This will output your google profile details which will hopefully look like the following.
--- !ruby/hash:OmniAuth::AuthHash
provider: google_oauth2
uid: '1234567'
info: !ruby/hash:OmniAuth::AuthHash::InfoHash
name: Your Name
email: yourEmail
first_name: firstname
last_name: surname
image: https://animage
credentials: !ruby/hash:Hashie::Mash
token: aToken
expires_at: 123
expires: true
extra: !ruby/hash:Hashie::Mash
raw_info: !ruby/hash:Hashie::Mash
id: '123456'
email: YourEmail
verified_email: true
name: YourName
given_name: Name
family_name: surname
link: https://plus.google.com/blah
picture: https://lh6.googleusercontent.com/blah blah
gender: male
birthday: ''
locale: en-GB
As you can see the names of the parameters are different, get rid of user_info and instead have info.
You will also notice that you have picture: and image: so whilst i have not tried this i would assume that it is your profile picture.
elsif service_route == 'google_oauth2'
omniauth['info']['email'] ? email = omniauth['info']['email'] : email = ''
omniauth['info']['name'] ? name = omniauth['info']['name'] : name = ''
omniauth['uid'] ? uid = omniauth['uid'] : uid = ''
omniauth['provider'] ? provider = omniauth['provider'] : provider = ''
omniauth['info']['image'] ? image = omniauth['info']['image'] : image = ''

I was having the same issue and found out that it was just that the image of the profile wasn't public. I had to change the settings from 'Visible only to people I can chat with' to 'Visible to everyone'. Then the image started to show up. Hope this helps someone.

Related

how Inject headers to OmniAuth mock tests

I'm using omniauth-google-oauth2 gem to log in via google account. recently I saw this post https://developers.googleblog.com/2020/08/guidance-for-our-effort-to-block-less-secure-browser-and-apps.html. even though it will not affect to the regular users I'm worried about unit tests. which i guess use headless browsers. so I would like to test that by injecting headers as described in this post(Google-Accounts-Check-OAuth-Login:true). couldn't find any api methods for that on omiauth documentations.
OmniAuth.config.mock_auth[:google] = OmniAuth::AuthHash.new(
provider: "google",
uid: "123545",
info: {
email: EMAIL,
first_name: FIRST_NAME,
last_name: LAST_NAME,
}
)
visit new_user_registration_path
click_link "Sign in with Google"

Sign into GitLab with OAuth2 Custom provider does not map user information

I've installed Gitlab-CE on a CentOS VM and am trying to configure the Sign On with an generic OAuth2 provider, to be more specific am actually using IBM Security Access Manager 9.0.6.
So far Sign On works after tweeking a bit the omniauth-oauth2-generic gem configuration :
I do see the SSO Button :
And on the administration area i do find my user with the oauth2 identity provider :
My problem is that the user information is not set when the user signs on :
Here it's my omniauth configuration :
#https://gitlab.com/satorix/omniauth-oauth2-generic
gitlab_rails['omniauth_enabled'] = true
gitlab_rails['omniauth_allow_single_sign_on'] = ['oauth2_generic']
gitlab_rails['omniauth_block_auto_created_users'] = false
gitlab_rails['omniauth_providers'] = [
{
'name' => 'oauth2_generic',
'app_id' => '9gzCzRKeiipexDRXsJOJ',
'app_secret' => 'mysecret',
'args' => {
client_options: {
'site' => 'https://example.com', # including port if necessary
'authorize_url': '/mga/sps/oauth/oauth20/authorize',
'token_url': '/mga/sps/oauth/oauth20/token',
'user_info_url' => '/mga/sps/oauth/oauth20/userinfo'
},
user_response_structure: {
root_path: [],
id_path: ['sub'],
attributes: {
nickname: 'sub',
name: 'name',
first_name: 'given_name',
last_name: 'family_name'
}
}
# optionally, you can add the following two lines to "white label" the display name
# of this strategy (appears in urls and Gitlab login buttons)
# If you do this, you must also replace oauth2_generic, everywhere it appears above, with the new name.
#name: 'IBM ISAM', # display name for this strategy
#strategy_class: "OmniAuth::Strategies::OAuth2Generic" # Devise-specific config option Gitlab uses to find renamed strategy
}
}
]
And my user info endpoint returns :
{ "sub":"XCQX342",
"nickname": "Kalem",
"name": "My name",
"given_name": "My name",
"family_name": "My surname",
"email": "myemail#example.com"
}
I've compare my configuration with http://lifeinide.com/post/2017-08-30-jetbrains-hub-as-oauth2-provider-for-gitlab/ but i don't see what am doing wrong, and why gitlab is not able to my parse the user attributes.
Thx for your help.
I hope you are resolved your problem.
If not :
Try direct to set field as in this case
https://gitlab.com/satorix/omniauth-oauth2-generic/blob/master/lib/omniauth/strategies/oauth2_generic.rb#L20
Simural as you set there
user_response_structure: {
root_path: [],
id_path: ['sub'],
attributes: {
nickname: 'sub',
name: 'name',
first_name: 'given_name',
last_name: 'family_name',
email: 'email'
}
}

Examples of Ruby on rails + aws congnito

I am building a rails 5 app that is deployed on heroku.
I want to use AWS congnito to achieve single sign on, but there are not enough example to implement it.
I am using devise for authentication. Now my goal is to put my all users on AWS cognito and authenticate them from my rails App.
This is the only resource i found on AWS congnito with rails, I am looking for some example application or a link to tools or ruby API document to achieve this.
Please Help.
Update On basis Of Bala Answer
require 'aws-sdk'
ENV['AWS_ACCESS_KEY_ID'] = 'XXXXXXXXXXXXXXXXX'
ENV['AWS_SECRET_ACCESS_KEY'] = 'XXXX+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
region_name = 'us-east-1'
endpoint = 'cognito-idp.us-east-1.amazonaws.com'
client = Aws::CognitoIdentityProvider::Client.new(
region: region_name
)
resp = client.admin_create_user({
user_pool_id: "us-east-1_iD7xNHj0x", # required
username: "Test", # required
user_attributes: [
{
name: "email", # required
value: "sachin.singh#example.com",
},
],
validation_data: [
{
name: "Email", # required
value: "AttributeValueType",
},
],
temporary_password: "PasswordType",
force_alias_creation: false,
message_action: "RESEND", # accepts RESEND, SUPPRESS
desired_delivery_mediums: ["EMAIL"], # accepts SMS, EMAIL
})
Error stack trace
home/sachin/.rvm/gems/ruby-2.1.5#global/gems/aws-sdk-core-2.6.38/lib/seahorse/client/plugins/raise_response_errors.rb:15:in `call': User does not exist. (Aws::CognitoIdentityProvider::Errors::UserNotFoundException)
from /home/sachin/.rvm/gems/ruby-2.1.5#global/gems/aws-sdk-core-2.6.38/lib/aws-sdk-core/plugins/idempotency_token.rb:18:in `call'
from /home/sachin/.rvm/gems/ruby-2.1.5#global/gems/aws-sdk-core-2.6.38/lib/aws-sdk-core/plugins/param_converter.rb:20:in `call'
from /home/sachin/.rvm/gems/ruby-2.1.5#global/gems/aws-sdk-core-2.6.38/lib/seahorse/client/plugins/response_target.rb:21:in `call'
from /home/sachin/.rvm/gems/ruby-2.1.5#global/gems/aws-sdk-core-2.6.38/lib/seahorse/client/request.rb:70:in `send_request'
from /home/sachin/.rvm/gems/ruby-2.1.5#global/gems/aws-sdk-core-2.6.38/lib/seahorse/client/base.rb:207:in `block (2 levels) in define_operation_methods'
from aws_cognito.rb:20:in `<main>'
Update 2
resp = client.admin_initiate_auth({
user_pool_id: "us-east-1_uKM", # required
client_id: "3g766413826eul9kre28qne4f", # required
auth_flow: "ADMIN_NO_SRP_AUTH",
auth_parameters: {
"EMAIL" => "kapil.sachdev#metacube.com",
"PASSWORD" => "Ibms#1234"
}
})
First of all, you need to create a user pool for your application
Use this link to create user pool through AWS console
You can find the ruby methods for sign_up, sign_in, change password and many other functions at http://docs.aws.amazon.com/sdkforruby/api/Aws/CognitoIdentityProvider/Client.html
EDIT
Now, you can sign up the user using sign_up
sign_in a user using
admin_initiate_auth
if you need mobile number confirmation, email confirmation you need to configure the user pool that you are creating.
You can find the corresponding methods for confirming the mobile numbers using http://docs.aws.amazon.com/sdkforruby/api/Aws/CognitoIdentityProvider/Client.html#confirm_sign_up-instance_method

Oauth2 Login for Facebook, Linkedin and Google Stopped Working with Devise and Omniauth, But Still Works for LinkedIn and Twitter

I have a site that is configured to work with multiple Oauth2 API's using Devise with Omniauth and has been functioning normally until last week. Currently login with Twitter and Github still function normally; however, Facebook, LinkedIn and Google are giving me an error stating that the Redirect URI doesn't match. The Error Messages read:
Facebook:
ERROR -- omniauth: (facebook) Authentication failure! invalid_credentials: >OAuth2::Error, :
{"error":{"message":"Error validating verification code. Please make sure your >redirect_uri is identical to the one you used in the OAuth dialog request","type":"OAuthException","code":100,"fbtrace_id":"XXXXXXXXXX"}}
LinkedIn:
ERROR -- omniauth: (linkedin) Authentication failure! invalid_credentials: >OAuth2::Error, invalid_request: missing required parameters, includes an invalid parameter value, parameter more than once. : Unable to retrieve access token : appId or redirect uri does not match authorization code or authorization code expired
{"error_description":"missing required parameters, includes an invalid parameter value, parameter more than once. : Unable to retrieve access token : appId or redirect uri does not match authorization code or authorization code expired","error":"invalid_request"}
Google
ERROR -- omniauth: (google_oauth2) Authentication failure! invalid_credentials: >OAuth2::Error, redirect_uri_mismatch:
{
"error" : "redirect_uri_mismatch"
}
I went reviewed the requests that were sent for all three of these in the Chrome Developers Console and the redirect uri for the callback matches the uri that is registered with each API (Which has not changed since it was working).
The challenge with back tracking this error is I am not 100% sure when these stopped working as I was logging in directly or using the Github login during recent integration tests as I installed new functionality. (Big Lesson Learned!) One of the significant changes that could be impacting this is that I integrated the Traceable extension for Devise which had me require the Warden Gem. However, I removed both the Traceable and Warden configuration and restored the user model and config files to their previous state and I am having the same issue.
I would generally prefer to provide more code samples but to be honest, I am not sure what code to start with. I am hoping that someone has experienced a similar problem and can point in the right direction to start.
To Start, below is my Devise Initializer with Comments Removed to Shorten
Devise.setup do |config|
config.mailer_sender = 'no-reply#' + ENV['DOMAIN_NAME']
config.mailer = 'Devise::Mailer'
require 'devise/orm/active_record'
config.case_insensitive_keys = [:email]
config.strip_whitespace_keys = [:email]
config.skip_session_storage = [:http_auth]
config.stretches = Rails.env.test? ? 1 : 10
config.allow_unconfirmed_access_for = 10.days
config.reconfirmable = true
config.confirmation_keys = [:email]
config.remember_for = 2.weeks
config.expire_all_remember_me_on_sign_out = true
config.password_length = 8..72
config.email_regexp = /\A[^#]+#[^#]+\z/
config.reset_password_keys = [:email]
config.reset_password_within = 6.hours
config.sign_in_after_reset_password = true
config.sign_out_via = :get
# ==> OmniAuth
# Add a new OmniAuth provider. Check the wiki for more information on setting
# up on your models and hooks.
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
require "omniauth-google-oauth2" # Added Based on Response to Another Stackoverflow Issues - Did Not Help.
OMNIAUTH = YAML.load(File.read(File.expand_path('../../omniauth.yml', __FILE__))).deep_symbolize_keys
OMNIAUTH.each_value do |provider|
config.omniauth provider[:reference].to_sym, ENV[provider[:key_ref]], ENV[provider[:secret_ref]], { :scope => provider[:scope] }
end
end
The omniauth.yml file that is loaded looks like this:
facebook: { reference: "facebook",
name: "Facebook",
scope: "email, public_profile, user_birthday",
key_ref: "FACEBOOK_KEY",
secret_ref: "FACEBOOK_SECRET" }
twitter: { reference: "twitter",
name: "Twitter",
scope: "r_fullprofile, r_emailaddress",
key_ref: "TWITTER_KEY",
secret_ref: "TWITTER_SECRET" }
linkedin: { reference: "linkedin",
name: "LinkedIn",
scope: "r_basicprofile r_emailaddress",
key_ref: "LINKEDIN_KEY",
secret_ref: "LINKEDIN_SECRET" }
github: { reference: "github",
name: "GitHub",
scope: "user, public_repo",
key_ref: "GITHUB_KEY",
secret_ref: "GITHUB_SECRET" }
google: { reference: "google_oauth2",
name: "Google",
scope: "email, profile",
key_ref: "GOOGLE_KEY",
secret_ref: "GOOGLE_SECRET" }
I had exactly similar issue, facebook working, linkedin and google - not.
After some digging/googling i was able to fix my issue by downgrading:
gem 'omniauth-oauth2', '1.3.1'
So my Gemfile looks like:
gem 'devise'
gem 'koala'
gem 'omniauth-oauth2', '1.3.1'
gem 'omniauth-facebook'
gem 'omniauth-google-oauth2'
gem 'omniauth-linkedin-oauth2'
I went through and updated all of the Omniauth Gems as there was recent version revisions and all of the issues have been resolved.

Omniauth-facebook hash not showing Facebook 'username' field, using rails 3

I've set up my rails 3 app to use omniauth-facebook, everything works fine but when I look at the omniauth hash as yaml there is no 'nickname' field, I can get the 'name' and 'email' but my validations fail to create a user because I can't grab the nickname for my app's username requirement.
I've double checked my facebook account, under "Settings", and my username is displayed. ANy ideas why this would be happening? Thanks for the help.
Here is an example of my omniauth hash, i've placed 'X' for privacy reason:
--- !ruby/hash:OmniAuth::AuthHash
provider: facebook
uid: 'XXXXXXXXXXXXX'
info: !ruby/hash:OmniAuth::AuthHash::InfoHash
email: XXXX#XXXX.XX
name: XXXX XXXX
first_name: XXXX
last_name: XXXX
image: http://graph.facebook.com/XXXXXXXXXXXXX/picture
urls: !ruby/hash:OmniAuth::AuthHash
Facebook: https://www.facebook.com/app_scoped_user_id/XXXXXXXXXXXXX/
verified: true
credentials: !ruby/hash:OmniAuth::AuthHash
token: ACCESS_TOKEN
expires_at: 1406357169
expires: true
extra: !ruby/hash:OmniAuth::AuthHash
raw_info: !ruby/hash:OmniAuth::AuthHash
id: 'XXXXXXXXXXXXXXX'
email: XXXX#XXXX.XX
first_name: XXXX
gender: male
last_name: XXXX
link: https://www.facebook.com/app_scoped_user_id/XXXXXXXXXXXXX/
locale: en_US
name: XXXX XXXX
timezone: 7
updated_time: '2014-05-07T00:58:12+0000'
verified: true
There's no field nickname, do you mean username? If so it's no longer available if you use the Graph API v2.0.
References:
https://developers.facebook.com/docs/apps/changelog#v2_0_graph_api
https://developers.facebook.com/docs/graph-api/reference/v2.0/user/#fields
I know this is an old question.
Since facebook now does not support fetching username at time of login, a workaround for getting user name would be, to call GraphRequest.newMeRequest() from the onSuccess() method of facebook login button

Resources