Ruby Facebook Graph API Appsecret_Proof

Invalid appsecret_proof provided in the API argument

finally i got the answer....
disable Required app secret proof in the advanced settings of app, and comment the following code in base_facebook.php sdk

if (isset($params['access_token'])) {
$params['appsecret_proof'] = $this->getAppSecretProof($params['access_token']);
}

How dows Ketchup (gottaketchup.com) send facebook messages?

They are most likely using the Chat API but they really shouldn't, this could blow up in their face. It's not that clever of a circumvention, risking your app being banned.

Your Facebook Chat integration should only be used for applications facilitating real time conversation or interaction between users. Links or advertisements should not be sent via chat, unless the sending user types in this message

Chat permissions

In any case using require 'xmpp4r_facebook'

id = '-<sender user id>@chat.facebook.com'
to = '-<user id>@chat.facebook.com'
body = "hello, Im not spam!"
subject = 'message from ruby'
message = Jabber::Message.new to, body
message.subject = subject

client = Jabber::Client.new Jabber::JID.new(id)
client.connect
client.auth_sasl(Jabber::SASL::XFacebookPlatform.new(client, '<App ID/API Key>', '<Access Token>', '<App Secret>'), nil)
client.send message
client.close

With xmpp_login permission

This is just proof of concept, incorporating this in your app to send messages to users in a non-realtime format may result in consequences for your application

Graph returned an error: Invalid appsecret_proof provided in the API argument

You may want to read this: https://developers.facebook.com/docs/graph-api/securing-requests

appsecret_proof is a separate parameter that is generated by using the App Secret, but it is NOT the App Secret. Information about how to generate it can be found in the docs.

Ruby on Rails - OAuth 2 multipart Post (Uploading to Facebook or Soundcloud)

Struggled with this myself. The oauth2 library is backed by Faraday for it's HTTP interaction. with a little configuration it supports uploaded files out of the box. First step is to add the appropriate Faraday middleware when building your connection. An example from my code:

OAuth2::Client.new client_id, secret, site: site do |stack|
stack.request :multipart
stack.request :url_encoded
stack.adapter Faraday.default_adapter
end

This adds the multipart encoding support to the Faraday connection. Next when making the request on your access token object you want to use a Faraday::UploadIO object. So:

upload = Faraday::UploadIO.new io, mime_type, filename
access_token.post('some/url', params: {url: 'params'}, body: {file: upload})

In the above code:

io - An IO object for the file you want to upload. Can be a File object or even a StringIO.

mime_type - The mime type of the file you are uploading. You can either try to detect this server-side or if a user uploaded the file to you, you should be able to extract the mime type from their request.

filename - What are are calling the file you are uploading. This can also be determined by your own choosing or you can just use whatever the user uploading the file calls it.

some/url - Replace this with the URL you want to post to

{url: 'params'} - Replace this with any URL params you want to provide

{file: upload} - Replace this with your multipart form data. Obviously one (or more) of the key/value pairs should have an instance of your file upload.

Authenticate user using omniauth and Facebook for a rails API?

the best way I found (after being stuck for a while on this issue ) is to do your omniauth2 (specifically in my case using satellizer angular plugin) manually...

I'll discuss the solution for Facebook as it was my case, but everything could apply to any other provider.

first you have to know how omniauth2 works (as documented for humans here)...

  1. Client: Open a popup window for user to authenticate.
  2. Client: Sign in (if necessary), then authorize the application.
  3. Client: After successful authorization, the popup is redirected back to your app. with the code (authorization code) query string parameter

the redirect back url must match your front-end app url not the back-end url and it must be specified in your facebook app configurations


  1. Client: The code parameter is sent back to the parent window that opened the popup.
  2. Client: Parent window closes the popup and sends a POST request to backend/auth/facebook with code parameter.
  3. Server: code (Authorization code) is exchanged for access token

here is described in details how to exchange the code for an access-token from facebook developers documentation


  1. Server: use the access-token retrieved in step 6 to retrieve the User's info.

  2. VOILA you've got yourself a user you can merge/create account for/link with other oauth providers/etc. but bear in mind that user can revoke some of the permissions (like email, facebook supports revoking some of the permissions)...


(enough talking, show me some code)

First you have to add HTTParty gem to your Gemfile

gem 'httparty'  # Makes http fun again (http client)

I've added this gist which contains the flow for step (6, 7 and 8) those are the most problematic steps and are not documented almost anywhere.

the gist exports 2 main methods:

Omniauth::Facebook.authenticate(authorization_code)

which is used to authenticate the user with facebook and return the user_info, long_live_access_token (valid for 60 days)

Omniauth::Facebook.deauthorize(access_token)

which is used to de-authorize/revoke the access_token and application permissions on facebook...

This is used for special requirement I have, when the user revoke the email permission requested on facebook login... we revoke the whole application permissions... this will prompt the user in the next login as if it's his first login ( no need to go to facebook apps and manually revoke the application)...

here is how it's used in the controller

user_info, access_token = Omniauth::Facebook.authenticate(params['code'])
if user_info['email'].blank?
Omniauth::Facebook.deauthorize(access_token)
end

That's it... now if you are interested in the internals of the implementation... here is the code as seen in the gist. (added for reference)
Feel free to fork it, edit it, help making it better.

require 'httparty'

module Omniauth
class Facebook
include HTTParty

# The base uri for facebook graph API
base_uri 'https://graph.facebook.com/v2.3'

# Used to authenticate app with facebook user
# Usage
# Omniauth::Facebook.authenticate('authorization_code')
# Flow
# Retrieve access_token from authorization_code
# Retrieve User_Info hash from access_token
def self.authenticate(code)
provider = self.new
access_token = provider.get_access_token(code)
user_info = provider.get_user_profile(access_token)
return user_info, access_token
end

# Used to revoke the application permissions and login if a user
# revoked some of the mandatory permissions required by the application
# like the email
# Usage
# Omniauth::Facebook.deauthorize(access_token)
# Flow
# Send DELETE /me/permissions?access_token=XXX
def self.deauthorize(access_token)
options = { query: { access_token: access_token } }
response = self.delete('/me/permissions', options)

# Something went wrong most propably beacuse of the connection.
unless response.success?
Rails.logger.error 'Omniauth::Facebook.deauthorize Failed'
fail Omniauth::ResponseError, 'errors.auth.facebook.deauthorization'
end
response.parsed_response
end

def get_access_token(code)
response = self.class.get('/oauth/access_token', query(code))

# Something went wrong either wrong configuration or connection
unless response.success?
Rails.logger.error 'Omniauth::Facebook.get_access_token Failed'
fail Omniauth::ResponseError, 'errors.auth.facebook.access_token'
end
response.parsed_response['access_token']
end

def get_user_profile(access_token)
options = { query: { access_token: access_token } }
response = self.class.get('/me', options)

# Something went wrong most propably beacuse of the connection.
unless response.success?
Rails.logger.error 'Omniauth::Facebook.get_user_profile Failed'
fail Omniauth::ResponseError, 'errors.auth.facebook.user_profile'
end
response.parsed_response
end

private

# access_token required params
# https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.3#confirm
def query(code)
{
query: {
# The authorization_code we want to exchange for the access_token
code: code,
# This must match the redirectUrl registerd in the facebook app.
# You can save it to ENV['WEB_APP_URL'] if you have multiple facebook apps for development and testing
# so you can support testing app on development and production app on production env.
redirect_uri: "http://localhost:9000/",
client_id: ENV['FB_APP_ID'], # Facebook appId
client_secret: ENV['FB_APP_SECRET'], # Facebook app secret (must not exist on front-end app for security)
}
}
end
end
end

here is another nodejs tutorial implementing oauth for instagram that helped me understand how oauth2 is working (added for reference)



Related Topics



Leave a reply



Submit