So I'm using Omniauth to authenticate with the likes of Twitter and Foursquare. Twitter works fine, but Foursquare doesn't appear to return a secret.
Anyone know what's going wrong?
Here's the create action in the controller, Foursquare is passing the user back to this, but as I said, it's not getting the secret, just the token
def create
omniauth = request.env["omniauth.auth"]
unless current_user.authentications.find_by_provider_and_uid(omniauth['provider'], omniauth['uid'])
current_user.apply_omniauth(omniauth)
current_user.save
end
flash[:notice] = "Authentication Successfull"
redirect_to authentications_url
end
Here is the apply omniauth method:
def apply_omniauth(omniauth)
authentications.build(
:provider => omniauth['provider'],
:uid => omniauth['uid'],
:token => omniauth['credentials']['token'],
:secret => omniauth['credentials']['secret']
)
end
Foursquare should not pass back a secret, just the token. The foursquare api key and and secret are provided to you by foursquare when you register your app on their developers site. You must use these values in your omniauth.rb
Twitter uses Oauth 1.0 and foursquare uses 2.0
That could be your issue there
Related
I am using databasedotcom gem. I am able to get data for 1 account only by specifying Client_id, client_secret, username and password in config/database.yml file. but i want to get data according to user login. 1st user login with salesforce he will get data from his salesforce account. same for 2nd 3rd and 4th.
Any suggestion will be appreciated.
Example code is below:-
database.yml:-
host: login.salesforce.com client_id: the Consumer Key from
Salesforce
client_secret: the Consumer Secret from Salesforce
username: username
password: password+securitytoken
debugging: true
sfdc_controller:-
class Api::V1::SfdcsController < ApplicationController
include Databasedotcom::Rails::Controller
def getSfdcauthentication
username = params[:username]
password = params[:password]
client_id = params[:client_id]
client_secret = params[:client_secret]
client = Databasedotcom::Client.new :client_id => client_id, :client_secret => client_secret
begin
oauth_token = client.authenticate :username => username, :password => password #=> "the-oauth-token"
rescue =>e
oauth_token = false
end
if oauth_token
contact_class = client.materialize("Contact")
#sf_contacts = Contact.all
respond_with(#sf_contacts) do |format|
format.json { render :json => #sf_contacts.as_json }
end
else
render json: {status:200,message:"Authentication failed"}
end
end
end
I found an another gem omniauth-salescforce and it worked well for me.
I found very good guide from here:-
http://geekymartian.com/articles/ruby-on-rails-4-salesforce-oauth-implementation/
and I found the sample code example from here :-
https://github.com/takahiro-yonei/OmniAuth-Salesforce-Sample
I am trying to fetch the list of friends from Facebook. Sign in through Facebook is not a problem, but the problem is to fetch person's friends - because of access token.
puts request.env["omniauth.auth"].inspect
puts '==='
#user = User.find_for_facebook_oauth(request.env["omniauth.auth"], current_user)
#fb_user = FbGraph::User.fetch(#user.uid).friends
puts #fb_user.inspect
The problem is on the #4 line - in this case I am getting error
OAuthException :: An access token is required to request this resource.
When I put there something like this:
#fb_user = FbGraph::User.fetch(request.env["omniauth.auth"].credentials.token).friends
I'll get
OAuthException :: (#803) Some of the aliases you requested do not exist: PRINTED OUT TOKEN
What's the proper way to obtain the access token?
EDIT: Current flow
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
#user = User.find_for_facebook_oauth(request.env["omniauth.auth"], current_user)
#fb_user = FbGraph::User.fetch(request.env["omniauth.auth"].credentials.token).friends
if !#user
flash[:error] = 'This email address is already used in the system.'
redirect_to :back
elsif #user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook"
sign_in_and_redirect #user, :event => :authentication
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
In User model:
def self.find_for_facebook_oauth(access_token, signed_in_resource=nil)
data = access_token.extra.raw_info
if user = User.where(:provider => 'facebook', :uid => data.id).first
user
elsif user = User.where('email = ? AND provider IS NULL', data.email).first
return false
else
...saving data...
end
return user if user
end
You can get an access token for test purposes via the Facebook Graph API Explorer. Make sure you select the proper fields that you want access to, and click "get access token". A more permanent solution is to register your app with Facebook so that you will be able to continually make requests without the token dying.
You should look into the Facebook OAuth dialogue.
I'm assuming you're trying to use the OAuth2 strategy instead of the Javascript SDK. Make sure you have set up a callback url like so:
client.redirect_uri = "http://your.client.com/facebook/callback"
In the controller that handles your callback, you should do something like this:
client.authorization_code = params[:code]
access_token = client.access_token! :client_auth_body
FbGraph::User.me(access_token).fetch
Make sure you've let fb_graph know what your app's id and secret are. You should look into this stackoverflow to keep your apps info safe.
I'll also plug the koala gem
using the twitter gem I want to get all the followers of the authenticated user. I only get the followers of the registered twitter id for the application though.
I have a twitter.rb in the initializers which uses the consumer key/secret of the registered app on twitter
Twitter.configure do |config|
config.consumer_key = '****'
config.consumer_secret = '****'
end
When you login you do so via Devise. Then in the user profile the user can authenticate with Twitter and at that point I store the token and secret.
def create
auth = request.env["omniauth.auth"]
currentAuthentication = Authentication.find_by_provider_and_uid(auth['provider'], auth['uid'])
if currentAuthentication
flash[:notice] = "Logged in successfully."
else
current_user.authentications.create(:provider => auth['provider'], :uid => auth['uid'], :token => auth['credentials']['token'], :secret => auth['credentials']['secret'])
flash[:notice] = "Authentication successful."
end
redirect_to authentications_url
end
Then at a later stage I authenticate that user with the information I stored and want to get his followers.
def getwords
# authenticate at twitter
authenticationDetails = current_user.authentications.first()
wordClient = Twitter::Client.new(
:oauth_token => authenticationDetails.token,
:oauth_token_secret => authenticationDetails.secret
)
# get the users followers
#wordClient.update("I'm tweeting using the Twitter Gem.")
cursor = "-1"
followerIds = []
while cursor != 0 do
followers = wordClient.follower_ids
cursor = followers.next_cursor
followerIds+= followers.ids
sleep(2)
end
return followerIds
end
When I do wordClient.update I sent a tweet out from the registered application, and I also get the followers of the registered application.
I was expecting to sent out a tweet and get the followers of the authenticated user? Where am I going wrong? All examples I've been able to find are on the bases of twittering with one single user.
I'm making a FB Canvas app.
The problem: After users authenticate, they are returned to the non-Canvas version of the app. Here's my code:
provider :facebook, CONFIG['app_id'], CONFIG['secret_key'], :scope => "publish_stream, rsvp_event"
match "/auth/facebook/callback" => "sessions#oauth_create"
match "/auth/facebook", :as => "facebook"
match "/auth/failure" => "sessions#oauth_failure"
When the user is returned from Facebook, they are sent to oauth_create (below)- however, they are sent to it via the normal (non-Canvas) app url (localhost:3000), rather than the canvas app (apps.facebook.com/my-app-namespace) so the redirect_to root_path below just sends them to the regular app.
def oauth_create
auth = request.env["omniauth.auth"]
t = auth["credentials"]["token"]
session[:facebook_token] = t
redirect_to root_path
end
I'm using omniauth-facebook gem.
How can I tell FB to send users to the canvas app after authentication?
I'm having trouble using omniauth & twitter gem to generate tweets.
I have been using this tutorial http://blog.assimov.net/post/2358661274/twitter-integration-with-omniauth-and-devise-on-rails-3
and I can log in using twitter, generate authentications but I cannot update tweets.
current_user.twitter.update("My Rails 3 App with Omniauth, Devise and Twitter")
This line complains about the method update.
What confuses me about the tutorial above is that at the beginning they generate a migration to store the secret in authentications, but at no point later in the tutorial is any mention of changing any code to write the secret to the database.
My understanding is that the secret is obtained from the omniauth hash that is stored in the session cookie. What am I missing here?
def hash_from_omniauth(omniauth)
{
:provider => omniauth['provider'],
:uid => omniauth['uid'],
:token => (omniauth['credentials']['token'] rescue nil),
:secret => (omniauth['credentials']['secret'] rescue nil)
}
end
So everything seems to be working apart from creating the Twitter Client hence not having the update method available?
current_user.twitter.update("first tweet")
The twitter method here should be creating the Twitter Client
def twitter
debugger
unless #twitter_user
provider = self.authentications.find_by_provider('twitter')
#twitter_user = Twitter::Client.new(:oauth_token => provider.token, :oauth_token_secret => provider.secret )rescue nil
end
#twitter_user
end
I'm sorry I'm not great at explaining the problem. Any help greatly appreciated.
Thanks
L
If you only need to post to twitter, it might just be easier to forgo the twitter gem completely. The consumer / access token generation requires the app id and secret as well as the user's access and secret tokens. I found this to be easy enough to implement that I thought the overhead of the twitter gem wasn't necessary.
module User::Social
def self.included(base)
base.instance_eval do
include Rails.application.routes.url_helpers
end
end
def promote_activity(type, profile)
url = short_profile_url(profile, :host => Conf.domain)
tw_client.request(:post, "http://api.twitter.com/1/statuses/update.json", :status => I18n.translate("tweets.#{type}", :profile => profile.to_s, :url => url))
end
def tw_client
#tw_client ||= begin
consumer = OAuth::Consumer.new(Conf.tw_app_id, Conf.tw_secret, :site => 'http://api.twitter.com')
OAuth::AccessToken.from_hash(consumer, {:oauth_token => self.access_token, :oauth_token_secret => self.secret_token})
end
end
end
class User < AR::Base
include User::Social
end