Facebook 2200 callback verification failed - php

I want to subscribe to picture object of a specific Facebook page. In order to do that I am following this article. I made uploaded the PHP file that would serve as callback here. Code below:
<?php
/**
* This is sample subscription endpoint for using Facebook real-time update
* See http://developers.facebook.com/docs/api/realtime to additional
* documentation
*/
// Please make sure to REPLACE the value of VERIFY_TOKEN 'abc' with
// your own secret string. This is the value to pass to Facebook
// when add/modify this subscription.
define('VERIFY_TOKEN', 'app_code_123');
$method = $_SERVER['REQUEST_METHOD'];
// In PHP, dots and spaces in query parameter names are converted to
// underscores automatically. So we need to check "hub_mode" instead
// of "hub.mode".
if ($method == 'GET' && $_GET['hub_mode'] == 'subscribe' &&
$_GET['hub_verify_token'] == VERIFY_TOKEN) {
echo $_GET['hub_challenge'];
} else if ($method == 'POST') {
$updates = json_decode(file_get_contents("php://input"), true);
// Replace with your own code here to handle the update
// Note the request must complete within 15 seconds.
// Otherwise Facebook server will consider it a timeout and
// resend the push notification again.
error_log('updates = ' . print_r($updates, true));
}
?>
Then I got my access_token as directed in the article where I replaced client_id with APP_ID and client_secret with APP SECRET from my app details:
https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id=<REMOVED APP ID>&client_secret=<REMOVED CLIENT SECRET>
Followed by an attempt to create the subscription:
https://graph.facebook.com/<REMOVED APP ID>/subscriptions?access_token=<REMOVED APP ACCESS TOKEN>object=user&fields=feed&verify_token=app_code_123&method=post&callback_url=http://www.shameemcompany.com/facebook.php
But it fails with the error:
"message": "(#2200) callback verification failed: ",
"type": "OAuthException",
"code": 2200
I want to subscribe to a specific Facebook page so where or how would I specify that?

First you must use HTTP POST method instead of sending "..&method=POST&.."
Second, your server must be reachable from the internet.
And third, your server must be able to process concurrent requests, because facebook sends verification requests simultaneously.

Related

Google Ads API - How to get the access and referesh token using PHP

I am following this package: https://github.com/googleads/google-ads-php. Here they said that I need to run this page:
https://github.com/googleads/google-ads-php/blob/main/examples/Authentication/GenerateUserCredentials.php
to terminal.
and I did it like:
php /locaation of the fie/GenerateUserCredentials.php
After that I can get a link which is something like that:
https://accounts.google.com/o/oauth2/v2/auth?response_type=code&access_type=offline&client_id=535777736006-d1rp8msevnls2pmihk7b8l23j3vra7duh.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fcallback&state=4e23ce963534701029c1a22d2de7848d034d8b0b0&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fadwords
(Above link is demo purpose)
So, When I click on this link I redirect to my google account and give access to them and after that I redirect back to this following URL:
http://localhost:3000/auth/callback?state=fddbaae6583b15aba552f682fe9f018233388533555f&code=4%2F0AfgeXvs4NV49mrqEBrl81ATRnXhqcu9x9ja8SAbaENSWhmNejGRGkZJE_AcD1aAFWdrlGg&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fadwords
Here you can see I have 2 params which is state and code.
Now my question is how can I get the access token and refresh token using this URL?
Here you can see I have 2 params which is state and code.
Now you can use them to get tokens.
Here is an example from the google-ads-php source code (open the link for the full example/code):
// Exit if the state is invalid to prevent request forgery.
$state = $request->getQueryParams()['state'];
if (empty($state) || ($state !== $oauth2->getState())) {
throw new UnexpectedValueException(
"The state is empty or doesn't match expected one." . PHP_EOL
);
};
// Set the authorization code and fetch refresh and access tokens.
$code = $request->getQueryParams()['code'];
$oauth2->setCode($code);
$authToken = $oauth2->fetchAuthToken();
$refreshToken = $authToken['refresh_token'];
print 'Your refresh token is: ' . $refreshToken . PHP_EOL;

How can I re-acquire a Shopify OAuth access token for a store that has previously installed my application?

I requested authorization for a public application to be able to access store data via the Shopify API.
The store successfully authorized my application via an authorization request URL such as
https://some-store.myshopify.com/admin/oauth/authorize?client_id=123abc&scope=read_inventory%2Cread_products&redirect_uri=http%3A%2F%mysite.com%2Fauth.php&state=123456
and the response was passed back to my application. This response (containing the code that can be exchanged for a permanent access token) was mishandled by my application (an error on the page meant that the access token was not stored).
Everything I read regarding requesting these tokens involves authorization by the store - but given the store has already authorized my application, passed back the code and that code has already successfully been exchanged for a token: is there a way my application can request that same token or a fresh one using my API keys given that the application is already authorized?
The only method I currently can find for requesting a token requires starting back at the beginning and fetching a code for exchange etc.
I working in PHP and using Luke Towers' php shopify wrapper
This stage was completed successfully:
function check_authorization_attempt()
{
$data = $_GET;
$api = new Shopify($data['shop'], [
'api_key' => '123',
'secret' => '456',
]);
$storedAttempt = null;
$attempts = json_decode(file_get_contents('authattempts.json'));
foreach ($attempts as $attempt) {
if ($attempt->shop === $data['shop']) {
$storedAttempt = $attempt;
break;
}
}
return $api->authorizeApplication($storedAttempt->nonce, $data);
}
$response = check_authorization_attempt();
and I would have been able to read the access token from :
$access_token = $response->access_token;
But this was the stage at which my application hit an error in accessing a database in which to write said token.
I cannot repeat it without repeating the auth request because the data in $_GET that's passed to this function comes from Shopify's response to the shop owner authorizing the access, and includes amoung other things the code for exchange.
You have to re-ask for authorization. It is no one's fault but yours that your persistence layer code was incorrect. So there is nothing you can do to change that. Ensure your code works. Since the client has no token in your App persistence layer, your App will retry the authorization token exchange. They do not have to delete your App first. So basically, the next time your client tries to use the App, YES they will asked to approve it, but who cares, they will, and you'll get a good auth token to store. You have fixed your code (right), so that will work. You are one step closer to glory.
Shopify does return the Permanent Access Token, but the ACCESS_MODE must be "Offline" for the token to be permanent.
With ACCESS_MODE offline, your app receives the permanent access token
to make requests whenever you want, without the user's permission.
Documentation:
https://shopify.dev/tutorials/authenticate-with-oauth#step-2-ask-for-permission
https://shopify.dev/concepts/about-apis/authentication#api-access-modes

infinite loop in a WebHook

I'm doing a facebook messenger bot. After you start it, it makes a call to WebHook.
Unfortunately after the first start will not stop throwing the same call with the same parameters.
The settings are:
message_deliveries;
message_reads;
messages;
messaging_optins;
messaging_postbacks.
The source code is this: https://github.com/Ellusu/nuraghebot-facebookmessenger/blob/master/index.php
Where am I wrong?
Why does only one call?
By your code I decided that you can't setup your webhook, so from documentation
At your webhook URL, add code for verification. Your code should
expect the Verify Token you previously defined, and respond with the
challenge sent back in the verification request. Click the "Verify and
Save" button in the New Page Subscription to call your webhook with a
GET request.
So, for PHP to make a success with webhook setup you must return hub_challenge parameter.
Define $verify_token with your token and add something like:
if (!empty($_REQUEST['hub_mode']) && $_REQUEST['hub_mode'] == 'subscribe' && $_REQUEST['hub_verify_token'] == $verify_token) {
// Webhook setup request
echo $_REQUEST['hub_challenge']; exit;
}
After success setup, you can delete this code from your script.
Or, if your webhook already hooked:
You should skip any read and delivery messages, like this:
if (!empty($input['entry'][0]['messaging'])) {
foreach ($input['entry'][0]['messaging'] as $message) {
// Skipping delivery messages
if (!empty($message['delivery'])) {
continue;
}
// Skipping read messages
if (!empty($message['read'])) {
continue;
}
}
}
Or, you can deselect message_reads & message_deliveries checkboxes in Page Subscription section of your Facebook Page Settings/Webhooks.

Generate a Dwolla access token using AJAX instead of redirecting to their webpage?

Looking at Dwolla's API documentation and trying the oauth.php example code (code shown below) on my site it is not clear to me if I can generate an access token without redirecting to Dwolla's page.
Redirecting from my site to their site back to my site is really terrible from a UI/UX perspective and is no better than the crappy interface Paypal provides.
Does anyone know how to generate a Dwolla access token using AJAX?
<?php
// Include the Dwolla REST Client
require '../lib/dwolla.php';
// Include any required keys
require '_keys.php';
// OAuth parameters
$redirectUri = 'http://localhost:8888/oauth.php'; // Point back to this file/URL
$permissions = array("Send", "Transactions", "Balance", "Request", "Contacts", "AccountInfoFull", "Funding");
// Instantiate a new Dwolla REST Client
$Dwolla = new DwollaRestClient($apiKey, $apiSecret, $redirectUri, $permissions);
/**
* STEP 1:
* Create an authentication URL
* that the user will be redirected to
**/
if(!isset($_GET['code']) && !isset($_GET['error'])) {
$authUrl = $Dwolla->getAuthUrl();
header("Location: {$authUrl}");
}
/**
* STEP 2:
* Exchange the temporary code given
* to us in the querystring, for
* a never-expiring OAuth access token
**/
if(isset($_GET['error'])) {
echo "There was an error. Dwolla said: {$_GET['error_description']}";
}
else if(isset($_GET['code'])) {
$code = $_GET['code'];
$token = $Dwolla->requestToken($code);
if(!$token) { $Dwolla->getError(); } // Check for errors
else {
session_start();
$_SESSION['token'] = $token;
echo "Your access token is: {$token}";
} // Print the access token
}
TL;DR - No, that's not how OAuth works
The whole point of the OAuth scheme is authentication on the website of the service that you want to use, in this case, Dwolla. By forcing the user to go to their page it ensures a few things:
The user is made aware that they are using an external service whose terms of service may be different than your application
The user is made aware of the features requested by your application for that service. In dwolla's case there are different levels of functionality that can be requested by your application including transferring of money, so it's important that your users are aware of that!
You can read up more on OAuth at http://oauth.net/

Twitter OAuth + auto login + MYSQL

I'm using https://github.com/abraham/twitteroauth library. I already created my app on Twitter, the callbacks are working fine (even on localhost), but one thing that is bugging me is HOW the auto-login happens? I know there's "user_id" that is stored in the MYSQL database, along with oauth_token and oauth_token_secret, but how do I obtain user_id as soon as the user enters the site, so I can query the database to see if it already exists and what not, without having to popup the authorize twitter popup then reaching the callback, over and over again?
I've seen a lot of questions like this one, but no one ever answered it in a satisfying way.
The ones that should be saved to be used in verifying the user automatically are the oauth_access_token and oauth_access_secrete . Have you managed to get them from twitter?
The Oauth steos are:
Acquiring a request token
Sending the user to authorization
Exchanging a request token for an access token
Using out-of-band/PIN code mode for desktop & mobile applications
please refer to :
http://dev.twitter.com/pages/auth
actually, it needs to be a mix of PHP own $_SESSION with OAuth callbacks. After the callback, set the current user ID you inserted on the database or query for "user_id" from Twitter OAuth response (that you should ALSO store on the database, along with the username), then use that for future reference, and using $_SESSION containing the registered user data on your own database.
So, for a quick example
function action_login()
{
if ( ! $this->user->is_logged())
{
// Create TwitterOAuth object with our Twitter provided keys
$tOAuth = new TwitterOAuth($this->config->get('consumer_key'), $this->config->get('consumer_secret'));
// Generate request tokens
$requestToken = $tOAuth->getRequestToken(url::site('auth/twitter','http'));
$_SESSION["oauth_token"] = $requestToken["oauth_token"];
$_SESSION["oauth_token_secret"] = $requestToken["oauth_token_secret"];
// Display Twitter log in button with encoded link
$this->view->set('url', $tOAuth->getAuthorizeURL($requestToken["oauth_token"]));
$_SESSION['current_url'] = Request::detect_uri();
}
echo $this->view->render();
}
public function action_twitter()
{
if ( empty($_GET["denied"]) && isset($_GET["oauth_token"]))
{
if ($_GET["oauth_token"] == #$_SESSION["oauth_token"])
{
// Use generated request tokens (from session) to construct object
$tOAuth = new TwitterOAuth($this->config->get('consumer_key'), $this->config->get('consumer_secret'), $_SESSION["oauth_token"], $_SESSION["oauth_token_secret"]);
// Retrieve access token from Twitter
$accessToken = $tOAuth->getAccessToken();
// Check we have valid response
if(is_numeric($accessToken["user_id"])) {
// Remove request token session variables
if ($this->user->loaded() || $this->user->where('user_id', '=', $accessToken['user_id'])->find()->loaded())
{
$this->user->values(array(
'oauth_token' => $accessToken['oauth_token'],
'oauth_token_secret' => $accessToken['oauth_token_secret'],
'screen_name' => $accessToken['screen_name'],
))->update();
}
else
{
$this->user->values(array(
'user_id' => $accessToken['user_id'],
'oauth_token' => $accessToken['oauth_token'],
'oauth_token_secret' => $accessToken['oauth_token_secret'],
'screen_name' => $accessToken['screen_name'],
))->create();
}
unset($_SESSION["oauth_token"]);
unset($_SESSION["oauth_token_secret"]);
echo $this->view->render();
// Redirect to main page
}
}
}
$this->request->redirect($_SESSION['current_url']);
}
so basically, the AUTO LOGIN (like the user is already logged to twitter, and already registered to your website) can't be done without him clicking the LOGIN WITH TWITTER button, unless you set the lifetime of your $_SESSION pretty high (like it happens with twitpic for example).
$this->user->is_logged() is checking for $_SESSION['id'] (auto increment on MYSQL) and $_SESSION['twitter']['user_id'] from twitter info
EDIT: Also, the quickest and cleanest way to do it, is to make an AJAX call on the page load with the Twitter credentials using the Javascript SDK, then set the $_SESSION variables with the info the SDK provided.

Categories