omniauth with rails: get facebook user's information - ruby-on-rails

in the callback of the authentication process I do:
auth_hash = request.env['omniauth.auth']
and then, I'm extracting the user id, but is it possible in the same time getting the user's name and email address?

You need to first get the raw data from request.env["omniauth.auth"]
data = request.env["omniauth.auth"].extra.raw_info
username = data.first_name
email = data.email

yesss
u can get it by doing
auth_hash[:info][:name] for name and auth_hash[:info][:email] for email

Related

Omniauth-Saml with Devise - mapping and using an attribute

I'm pretty new to Rails but we have an app using Devise and Omniauth for authentication and have recently integrated Omniauth-Saml by following the Omniauth documentation for Devise integration: https://github.com/omniauth/omniauth-saml#devise-integration The authentication works and we can create users and use these accounts without any issues.
In the SAML response attributes is an lacode (4-digit string). We want to check this user attribute against a reference lacode. If their cag matches the reference cag we want to set the verified_at attribute in the user.rb model.
I've updated the user model and to test if I set the oauth_lacode to "9064" to match the oauth_lacode_ref then the code works and the user's verified_at time and date are set at point of account creation.
app/models/user.rb
# Get the existing user by email if the provider gives us a verified email.
def self.first_or_initialize_for_oauth(auth)
oauth_email = auth.info.email
oauth_email_confirmed = oauth_email.present? && (auth.info.verified || auth.info.verified_email)
oauth_lacode = auth.extra.raw_info.lacode
oauth_lacode_ref = "9064"
oauth_lacode_confirmed = oauth_lacode == oauth_lacode_ref
oauth_user = User.find_by(email: oauth_email) if oauth_email_confirmed
oauth_user || User.new(
username: auth.info.name || auth.uid,
email: oauth_email,
oauth_email: oauth_email,
password: Devise.friendly_token[0, 20],
terms_of_service: "1",
confirmed_at: oauth_email_confirmed ? DateTime.current : nil,
verified_at: oauth_lacode_confirmed ? DateTime.current : nil
)
end
I'm not mapping and calling the lacode from the hash correctly as I see this error in the log "NoMethodError (undefined method `lacode' for #OneLogin::RubySaml::Attributes:0x00007f7a5040ad40):"
This is how I'm mapping the attributes in config/initializers/devise.rb
attribute_statements: { email: ['urn:oid:0.9.2342.19200300.100.1.22'],
lacode: ['urn:oid:0.9.2342.19200300.100.1.17']}
I have confirmed with the IDP that 'urn:oid:0.9.2342.19200300.100.1.17' is mapped to the lacode in the SAML response.
As in the User model above, this is how I'm trying to access the lacode from within the User model.
"saml_cag = auth.extra.raw_info.lacode"
This is the guidance from Omniauth Saml:
:attribute_statements - Used to map Attribute Names in a SAMLResponse
to entries in the OmniAuth info hash. For example, if your
SAMLResponse contains an Attribute called 'EmailAddress', specify
{:email => ['EmailAddress']} to map the Attribute to the corresponding
key in the info hash. URI-named Attributes are also supported, e.g.
{:email =>
['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress']}.
Note: All attributes can also be found in an array under
auth_hash[:extra][:raw_info], so this setting should only be used to
map attributes that are part of the OmniAuth info hash schema.
Does this sentence at the end mean I don't need to/can't map the attribute. Can anyone help or point me in the right direction?
I managed to get this working. Only attribute names specified in the Omniauth Hash Schema can be used.
Mapping the lacode to description in the attribute statement, I was able to access it using "auth.info.description"

Rails Facebook Omniauth get user address

I'm tryig to get the user address from facebook with Omniauth but did not work.
i added their address on update callback after login.
If i removed their address from omniauth the app did not update their address.
Someone have any idea how to get their address and why the app did not edit and update their address after the login?
thank's
def omniauth_callback
auth_hash = request.env['omniauth.auth']
user = User.find_by_uid(auth_hash[:uid])
if user.nil? && auth_hash[:info][:email]
user = User.find_by_email(auth_hash[:info][:email])
end
if user.nil?
email_domain = ''
email_domain = '#facebook.com' if auth_hash[:provider] == 'facebook'
user = User.new(email: auth_hash[:info][:email] || auth_hash[:info][:nickname] + email_domain, name: auth_hash[:info][:first_name] || '', surname: auth_hash[:info][:last_name] || '', gender: 'I')
user.password_digest = ''
user.save!(validate: false)
end
user.update_attribute(:login_at, Time.zone.now)
user.update_attribute(:address)
user.update_attribute(:neighborhood)
user.update_attribute(:postal_code)
user.update_attribute(:ip_address, request.remote_ip)
user.update_attribute(:provider, auth_hash[:provider])
user.update_attribute(:uid, auth_hash[:uid])
user.update_attribute(:oauth_token, auth_hash[:credentials][:token])
user.update_attribute(:oauth_expires_at, Time.at(auth_hash[:credentials][:expires_at]))
cookies[:auth_token] = { value: user.oauth_token, expires: user.oauth_expires_at}
redirect_to root_url
end
One reason your code will not work is because this
user.update_attribute(:address)
Doesn't do anything - except raise an error. You have to pass a value into update_attribute as well as specify the field.
Also as #mysmallidea points out, you'd be better advised to use update as that will allow you to update multiple fields in one database action.
If present, the address data will be within the auth_hash. So I suggest that you first work out the structure of that hash. In your development environment, add the following:
Rails.logger.info auth_hash.inspect
That will output the current auth_hash to logs/development.log. Use that to determine where in the hash the address data is. You'll then be able to do something like:
user.update address: auth_hash[:info][:address]
However, you may find that the address is not included in the data returned by the facebook oauth system. In which case you will need to return to their documentation to see if this is possible.

devise_token_auth how to identify a user by token

I am new to use gem devise_token_auth and working on a mobile client api, two questions:
1) How should i identify a user? My current understanding is on a http request header set access_token is this right?
But seems from the source code i should provide for uid, access_token, clientlink
uid = request.headers['did']
#token = request.headers['access-token']
#client_id = request.headers['client']
2) i can find a user.tokens like below:
{"AOYZdDmwI7WQr8I6T4PpPw"=>{"token"=>"$2a$10$C/5f3JV7.9DZG8w.ggdCPelB6kzitWuGK4rfozHv15Hhf/x9DaCcO", "expiry"=>1473485374, "last_token"=>"$2a$10$abctsIP5bHPIm2nMXFTUH.1jPWQ5LiGTTrENjoqihWgcCkwRqbxb6", "updated_at"=>"2016-08-27T13:29:34.948+08:00"}}
which is client and which is access-token?
Thank you!
headers = JSON.parse(cookies['authHeaders'])
uid = headers['uid']
token = headers['access-token']
client_id = headers['client']
user = User.find_by_uid(uid)
if !user || !user.valid_token?(token, client_id)
render json: {error: "Usuario no autorizado."}, status: 401
end

Hash username and password for authenticate ruby on rails

How can l implement a hash function (SHA512) that encrypt the username and check if this username and password is correct in the SQL server?
Working login right now if you set a cleartext username
user = User.find_by(username: params[:session][:username].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
redirect_to :root
else
flash.now[:warning] = 'Wrong username/password'
render 'new'
end
I have tried encrypt the username before it runs the if statement but I can get it to work.
The way I hash the username is:
username = params[:session][:username].downcase
username_encrypted = Digest::SHA2.new(512).hexdigest(username)
any ideas how this can be made?
What i am trying to achieve with this is. Too have one column in SQL with encrypted usernames and another column with "public" usernames. Where public usernames is visible for everybody on the site and encrypted usernames is stored in SQL only for authentication.

Facebook - Tag user in photo, keep getting OAuthException - Unknown Error?

I'm making a Facebook app in Rails using Koala gem.
My app needs to upload a picture to a Page's Album and tag the User who submitted it.
I keep getting this error when I want to tag the photo:
Koala::Facebook::ServerError in PhotosController#update
type: OAuthException, code: 1, message: An unknown error has occurred. [HTTP 500]
My app already have publish_actions permission set, so it's not permission issue.
Here's my code:
# token, photo_id, and user_id is confirmed to be not the problem
#graph = Koala::Facebook::API.new(token)
#graph.put_connections(photo_id, "tags",
{
tag_uid: user_id
}
)
If I'm using User's Token, the photo is tagged successfully but still goes to that Error page. If with Page's Token, nothing is tagged and goes to Error.
Any hint or solution?
Thanks
My solution to upload photo:
def post_to_facebook
conf = YAML.load_file File.join(Rails.root,'public','fb.yaml')
oauth = Koala::Facebook::OAuth.new(conf['app'], conf['key'], "http://yoursite.com/social_networks/callback_facebook?id=#{params[:id]}")
redirect_to oauth.url_for_oauth_code(:permissions => 'publish_stream,photo_upload,manage_pages')
end
def callback_facebook
news = News.find(params[:id])
conf = YAML.load_file File.join(Rails.root,'public','fb.yaml')
oauth = Koala::Facebook::OAuth.new(conf['app'], conf['key'], "http://yoursite.com/social_networks/callback_facebook?id=#{params[:id]}")
token = oauth.get_access_token(params[:code])
page = FbGraph::Page.new(page_id).fetch(:access_token => token, :fields => :access_token)
mes = "text_mes"
img_url = "http://yoursite.com#{news.news_image_url}"
page.photo!(:message => mes, :url => img_url)
redirect_to 'https://www.facebook.com/your_page'
end
Where page_id is id of facebook's page where photo will be upload
I have found two possible reasons:
The fact that Facebook doesn't allow us to tag non-friend. Since my token is Page's token, it doesn't have friend.
Maybe Page can't tag anyone.
Even if the user "Liked" the page, it doesn't allow to be tagged.
I changed the token to a User's token and the tagging works fine (as long as it tags a friend of that User).
I will leave this question open for anyone to add proper answer.

Resources