$facebook->getSignedRequest(); return the correct value in iframe while return null on my server side - api

i am building a fan gate for my site to give out some coupon.
here is my code:
<?php
require_once 'facebook.php';
$app_id = "xxxxxxxxxxxxxxx";
$app_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $app_secret,
'cookie' => true
));
print_r($_REQUEST);
$signed_request = $facebook->getSignedRequest();
echo "<pre>";
print_r($facebook->getSignedRequest());
echo "</pre>";
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
$like_status = $signed_request["page"]["liked"];
print_r($facebook);
?>
I find that the return value of $facebook->getSignedRequest(); is different when i am visiting my apps via apps.facebook.com/xxxxxxxxxxxxxxxxxxxxxx/ and when i am visiting www.coupon.mysite.com/facebook/index.php
via apps.facebook.com/xxxxxxxxxxxxxxxxxxxxxx/:
Facebook Object ( [appId:protected] => 15255288xxxxxxxx [appSecret:protected] => XXXXXXXXXXXXXXXXXXXX[user:protected] => [signedRequest:protected] => Array ( [algorithm] => HMAC-SHA256 [issued_at] => xxxxxxxxxxxxx[user] => Array ( [country] => hk [locale] => en_US [age] => Array ( [min] => 21 ) ) ) [state:protected] => [accessToken:protected] => [fileUploadSupport:protected] => )
via www.coupon.mysite.com/facebook/index.php:
Facebook Object ( [appId:protected] => xxxxxxxxxxxxxxxxxxx[appSecret:protected] => xxxxxxxxxxxxxxxxxx[user:protected] => [signedRequest:protected] => [state:protected] => [accessToken:protected] => [fileUploadSupport:protected] => )
so the fan gate wont work because $facebook->getSignedRequest(); always return null in my server side. I have do the searching for this problem for some days already and still dont understand what is the problem.
Any help is very much appreciated.

^ ... continue from the comments:
First of all, if you do this, your users will hate you; secondly, that plugin is bit of a scam - all it does is uses cookies to store if user has liked a page - but if you delete your cookies, you will be locked out of the content because you won't be able to like the page again. Furthermore, it won't work without Javascript.
All the plugin does is it hooks into the "like" action when user clicks on the like button via
FB.Event.subscribe('edge.create', function(href, response){});
facebook graph api determine if user likes url

Related

Twitter Video share using CodeBird API

I'm trying to share a video to Twitter Account but getting a response like below
stdClass Object ( [request] => /1.1/media/upload.json [error] => Segments do not add up to provided total file size. [httpstatus] => 400 [rate] => stdClass Object ( [limit] => 615 [remaining] => 613 [reset] => 1576651447 ) )
I don't know what to do to fix this issue. If anyone experienced this please let me know.
This is my code to share video to twitter.
\Codebird\Codebird::setConsumerKey(CONSUMER_KEY, CONSUMER_SECRET);
$cb = \Codebird\Codebird::getInstance();
$cb->setToken($access_token, $access_token_secret);
$file = $videopath;
$size_bytes = filesize($file);
$fp = fopen($file, 'r');
// INIT
$reply = $cb->media_upload([
'command' => 'INIT',
'media_type' => 'video/mp4',
'total_bytes' => $size_bytes
]);
$media_id = $reply->media_id_string;
// APPEND
$segment_id = 0;
while (! feof($fp)) {
$chunk = fread($fp, 1048576); // 1MB per chunk for this sample
$reply = $cb->media_upload([
'command' => 'APPEND',
'media_id' => $media_id,
'segment_index' => $segment_id,
'media' => $chunk
]);
$segment_id++;
}
fclose($fp);
// FINALIZE
$reply = $cb->media_upload([
'command' => 'FINALIZE',
'media_id' => $media_id
]);
if ($reply->httpstatus < 200 || $reply->httpstatus > 299) {
die();
}
// Now use the media_id in a Tweet
$reply = $cb->statuses_update([
'status' => $msg,
'media_ids' => $media_id
]);
I'm getting an error in the Finalize command result.
I tried to fix this but I can't because I don't know the exact reason for this issue and I didn't know how to handle and fix this. Can anyone help me to fix this? The above is the code I have used to share the post to the twitter account. And one thing is, the above code works fine when I tried to share the post immediately to twitter using this API but the issue is only when I tried to share the post by scheduling it with a specific time to share.
And when I trying to share a video below 1mb it gets shared. When I tried a video with 1mb or more than that I got the below error while sharing to account.
{"errors":[{"code":324,"message":"Invalid media id 1215261697298108416"}],"httpstatus":400,"rate":null}

Getting the "The provided value for the 'redirect_uri' is not valid" error when I try to get the access token

When I try to get the token I get the error:
The provided value for the 'redirect_uri' is not valid. The value must exactly match the redirect URI used to obtain the authorization code.
My redirect uri exactly matches so I don't understand why it is happening.
$TOKEN_ENDPOINT = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
$params = array(
'grant_type' => 'authorization_code',
'code' => $azureCode,
'clientId' => '7c09ab71-***-****-****-53d7c4438112',
'clientSecret' => 'bnot*******20*[',
'redirect_uri' => 'https://testing.****.com/outlookOauthCallback.php',
'urlAuthorize' => $AUTHORIZATION_ENDPOINT,
'urlAccessToken' => $TOKEN_ENDPOINT,
'urlResourceOwnerDetails' => '',
'scope' => 'Calendars.ReadWrite User.Read'
);
$response = $client->getAccessToken($TOKEN_ENDPOINT, 'authorization_code', $params);
(Trust me the part I turned into stars is exactly the same because I copy pasted)
Even in the response where I returned the params it is exactly the same:
Array
(
[grant_type] => authorization_code
[code] => M51b1b*****-daeec54627b2
[clientId] => 7c09ab71-a*****d7c4438112
[clientSecret] => bnotxds&*&QB***cVLF20*[
[redirect_uri] => https://testing.****.com/outlookOauthCallback.php
[urlAuthorize] => https://login.microsoftonline.com/common/oauth2/v2.0/authorize
[urlAccessToken] => https://login.microsoftonline.com/common/oauth2/v2.0/token
[urlResourceOwnerDetails] =>
[scope] => Calendars.ReadWrite User.Read
)
So how can it still be giving me this error? What am I missing here?
You need specify the redirect_uri in the request url. Something like
var href = 'login.microsoftonline.com/common/oauth2/…'; href += client_id + '&resource=webdir.online.lync.com&redirect_uri=' + window.location.href;

Silex security doesn't ask name and password

I am using Silex and apache. I want to disallow access for anonymous users to localhost/admin page. I read docs, docs of SimpleUserProvider and create the following index.php:
<?php
require_once __DIR__.'/../vendor/autoload.php';
use Silex\Provider;
use Symfony\Component\HttpFoundation\Request;
$app = new Silex\Application();
$app->register(new Provider\SecurityServiceProvider());
$app->register(new Provider\SessionServiceProvider());
$app->register(new Provider\TwigServiceProvider(), [
"twig.path" => __DIR__.'/../views'
]);
$app['debug'] = true;
$app['security.firewalls'] = array(
'default' => array(
'pattern' => '^/',
),
'secured' => array(
'pattern' => '^/admin/',
'form' => array('login_path' => '/login', 'check_path' => '/login_check'),
'users' => array(
'admin' => array('ROLE_ADMIN', '5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg=='),
'daria' => array('ROLE_USER', '5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg=='),
),
),
);
$app['security.access_rules'] = array(
array('^/admin', 'ROLE_ADMIN', 'https'),
array('^.*$', 'ROLE_USER'),
);
$app -> boot();
$app->get('/', function () {
return 'Hello from Silex container.';
});
$app->get('/admin/', function() {
return "Admin page";
});
$app->get('/login', function(Request $request) use ($app) {
return "Login page";
});
$app->get('/logout/', function() {
return "Logout page";
});
$app->get('/admin/login_check/', function() {
return "Admin login check page";
});
$app->run();
As Symfony 2 docs says, if I request to localhost/admin, I should see input fields for pass and login in alert.
So when I go to 'localhost' all are right, I see correct message. But when I go to 'localhost/admin' I expect that browser will ask with alert my login and password. But it doesn't happens, I get 'ERR_CONNECTION_REFUSED Site localhost disallow connection'. In apache log I have 301 http code. Is it normal behavior that browser doesn't ask login/password with alert? If yes, what should I add to code to change that behavior?
P.S. I know that hardcoded login and password are terrible, but I am just started Silex and it doesn't matter.
I think that you get ERR_CONNECTION_REFUSED error because of redirect to https. Try to remove this redirect by changing array('^/admin', 'ROLE_ADMIN', 'https'), to array('^/admin', 'ROLE_ADMIN'),.
Remove default section from firewalls. This section is first, catches all requests and doesn't require authorization.
If you want standard alert with user/password prompt, specify http entry point instead of form.
$app['security.firewalls'] = array(
'secured' => array(
'pattern' => '^/admin/',
'http' => array(),
'users' => array(
'admin' => array('ROLE_ADMIN', '...'),
'daria' => array('ROLE_USER', '...'),
),
),
);

Mandrill's UNSUB merge tag not getting parsed

I'm trying to make it so when someone clicks on the unsubscribe link in an email sent via the Mandrill API (using PHP) it works as described in: http://help.mandrill.com/entries/23815367-Can-I-add-an-automatic-unsubscribe-link-to-Mandrill-emails-
The *|UNSUB|* merge tag is not getting parsed. It just comes through in the the body of the email received.
Near the end of the message content ($message_content) I have:
Click here to unsubscribe.
In Gmail, the link is: Click here to unsubscribe.
(NOT a valid HREF, so Gmail just ignores the anchor tag)
In Outlook 2010 the link is: Click here to unsubscribe.
(Not a valid HREF)
Is there some merge_vars parameter I should add to the headers?
http://help.mandrill.com/entries/21678522-How-do-I-use-merge-tags-to-add-dynamic-content- mentions them, but I can't find what the parameter should be for the UNSUB merge tag.
$mandrill = new Mandrill($mandrill_api_key);
$message = array(
'html' => $message_content,
'subject' => $subject,
'from_email' => 'me#mydomain.com',
'from_name' => 'MY NAME',
'to' => $to_list,
'headers' => array('Reply-To' => 'me#mydomain.com'),
'important' => false,
'track_opens' => 1,
'track_clicks' => null,
'auto_text' => null,
'auto_html' => null,
'inline_css' => null,
'url_strip_qs' => null,
'preserve_recipients' => 0,
'view_content_link' => 1,
'tracking_domain' => null,
'signing_domain' => null,
'return_path_domain' => null,
'merge' => true,
'global_merge_vars' => array(
array(
'unsub' => 'unsub'
)
),
);
What step am I missing?
TIA!
The problem was the URL was missing a slash (http:/mydomain...)
This was caused by TinyMCE converting URLs. I added convert_urls: false to the tinymce.init and that solved my problem.
Kudos to Mandrill Support for helping me identify the problem.

CakePHP Auth->login not generating query for request data

I have the Auth component working perfectly for an application running Cake 2.4.1, and I need to copy it to another application that is also running Cake 2.4.1. I copied over everything I could think of that has to do with Auth stuff, but it just does not work in the second application. It refuses to log me in. The call to $this->Auth->login() fails even though it gets exactly the same data as the application that works.
Both applications are using exactly the same database and user login.
Both applications get exactly the same request data in the POST request.
First of all, here is my setup.
In AppController.php:
public $uses = array ('User');
public $components = array ( 'Session',
'CPRACL.CPRACL' => array (),
'Auth' => array (
// 'loginAction' => array ('controller' => 'users', 'action' => 'login'),
// 'logoutRedirect' => '/users/login',
// 'loginRedirect' => '/',
'authenticate' => array (
'Form' => array (
'fields' => array ('username' => 'email_address'),
'scope' => array ('User.active' => 1)
)
),
'authorize' => array ('Controller'),
// 'unauthorizedRedirect' => '/' // when going to a page the user is not authorized to go to
)
);
The commented out lines use the defaults, but they are included for reference to their default values. This is exactly the same in both applications. CPRACL is a plugin component that I am using instead of Cake's ACL component, but it fails long before it gets to any of that.
Also in AppController.php:
public function beforeFilter ()
{
$login_user = $this->User->find ('first', array ('conditions' => array ('id' => $this->Auth->user ('id'))));
if (!empty ($login_user))
$this->set ('login_user', $login_user ['User']);
}
public function isAuthorized ($user = null)
{
// This never gets called in the application that does not work, but it does get called in the one that works.
}
In both applications, it sets up the Auth component as defined in AppController.php, then it calls beforeFilter to check to see if the user is already logged in. This is a convenience so that when they get redirected to a different page, the application can display the username of the user who is logged in. It works fine and I don't think it is causing any problems.
The next thing that happens is it calls UsersController::login()
public function login ()
{
$redirect_url = $this->Auth->redirectUrl ();
if ($this->Auth->loggedIn ())
return $this->redirect ($redirect_url);
//die (print_r ($this->request->data, true));
if ($this->request->is ('post'))
{
//die (Debugger::dump ($this->Auth));
if ($this->Auth->login ())
return $this->redirect ($redirect_url);
else
return $this->redirect ($this->Auth->loginAction);
}
}
I used the two commented out lines to compare what is happening between the two applications. The two applications get exactly the same data in the post. For the dump of the Auth object, here is what I get:
object(AuthComponent) {
components => array(
(int) 0 => 'Session',
(int) 1 => 'RequestHandler'
)
authenticate => array(
'Form' => array(
[maximum depth reached]
)
)
authorize => array(
(int) 0 => 'Controller'
)
ajaxLogin => null
flash => array(
'element' => 'default',
'key' => 'auth',
'params' => array([maximum depth reached])
)
loginAction => array(
'controller' => 'users',
'action' => 'login',
'plugin' => null
)
loginRedirect => null
logoutRedirect => array(
'controller' => 'users',
'action' => 'login',
'plugin' => null
)
authError => 'You are not authorized to access that location.'
unauthorizedRedirect => true
allowedActions => array(
(int) 0 => 'register',
(int) 1 => 'login',
(int) 2 => 'logout'
)
request => object(CakeRequest) {}
response => object(CakeResponse) {}
settings => array(
'authenticate' => array(
[maximum depth reached]
),
'authorize' => array(
[maximum depth reached]
)
)
Session => object(SessionComponent) {}
[protected] _authenticateObjects => array()
[protected] _authorizeObjects => array()
[protected] _user => array()
[protected] _methods => array(
(int) 0 => 'index',
(int) 1 => 'view',
(int) 2 => 'add',
(int) 3 => 'register',
(int) 4 => 'login',
(int) 5 => 'logout',
(int) 6 => 'toggleactive',
(int) 7 => 'changePassword',
(int) 8 => 'passwordHash',
(int) 10 => 'edit_pwd',
(int) 11 => 'edit_your_pwd',
(int) 12 => 'isAuthorized'
)
[protected] _Collection => object(ComponentCollection) {}
[protected] _componentMap => array(
'Session' => array(
[maximum depth reached]
),
'RequestHandler' => array(
[maximum depth reached]
)
)
}
That is what both applications return from the Auth object dump when I send the login request. It says the user is not authorized to access that location, but I think that is because it hasn't actually logged the user in yet, so I don't think the dump of that Auth object is of much value, but I included it here anyway.
But here is the most important part because it is the only thing that is obviously different between the two applications. When I perform the login on the working application, it logs me in successfully and my layout (which displays the most recent query) shows this query. Notice the id field. The id field is correct in the query and it works.
SELECT `User`.`id`, `User`.`user_id`, `User`.`email_address`, `User`.`first_name`, `User`.`last_name`, `User`.`password`, `User`.`active`, `User`.`created`, `User`.`modified` FROM `brian_cake_test`.`users` AS `User` WHERE `id` = '529f9a8c-3460-46a2-a97c-6a6242a26b88' LIMIT 1
But when I do exactly the same thing for the application that does not work, everything happens exactly the same way except that it redirects me back to the login page, which it should do if it fails to login, and it displays this query in my layout.
SELECT `User`.`id`, `User`.`user_id`, `User`.`email_address`, `User`.`first_name`, `User`.`last_name`, `User`.`password`, `User`.`active`, `User`.`created`, `User`.`modified` FROM `brian_cake_test`.`users` AS `User` WHERE `id` IS NULL LIMIT 1
Notice how the id is NULL in the second query. I have no idea why this is happening.
My User.php model is just an empty class, exactly the same in both application, but one works perfectly and the other does not.
<?php
App::uses ('AppModel', 'Model');
class User extends AppModel
{
public $name = 'User';
}
I have racked my brain trying to figure out what is different between these two applications, and I can't think of anything, and nothing I try will make it work. I don't want to post hundreds of lines of code when I know that 99% of it has nothing to do with this problem, but I have no idea why it works in one but not the other. I will gladly post more information if you think you might know what the problem is. Any help would be much appreciated. This is very important to me.
Actually if its exactly the same code and DB it shouldn't be a reason not to work.
Have you tried clearing the cache folders? Those files sometimes mess up the app.