(Sorry for my english)
I am developing a web application with php and Facebook php sdk 4.0. I'm using the FacebookRedirectLoginHelper.php to let the authorize access to their information. I take their facebook-id and store it in the database table Users {int UserID FK, nvarchar(max) UserName, nvarchar(max) facebook-id}. I want to make a list of their facebookfriends who are using the web application. How can this be possible? I can't just change the row:
new FacebookRequest( $session, 'GET', '/me' );
to
new FacebookRequest( $session, 'GET', '/me/friends' );
?
require_once( 'Facebook/FacebookSession.php' );
require_once( 'Facebook/FacebookRedirectLoginHelper.php' );
require_once( 'Facebook/FacebookRequest.php' );
require_once( 'Facebook/FacebookResponse.php' );
require_once( 'Facebook/FacebookSDKException.php' );
require_once( 'Facebook/FacebookRequestException.php' );
require_once( 'Facebook/FacebookAuthorizationException.php' );
require_once( 'Facebook/GraphObject.php' );
use Facebook\FacebookSession;
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookRequest;
use Facebook\FacebookResponse;
use Facebook\FacebookSDKException;
use Facebook\FacebookRequestException;
use Facebook\FacebookAuthorizationException;
use Facebook\GraphObject;
// init app with app id (APPID) and secret (SECRET)
FacebookSession::setDefaultApplication('XXX','XXX');
// login helper with redirect_uri
$helper = new FacebookRedirectLoginHelper( 'http://livescoreapp.azurewebsites.net/' );
try {
$session = $helper->getSessionFromRedirect();
} catch( FacebookRequestException $ex ) {
// When Facebook returns an error
} catch( Exception $ex ) {
// When validation fails or other local issues
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h1>Welcome</h1>
<?php
if($conn === false)
{
die(print_r(sqlsrv_errors()));
}
else //Connection to database is ok.
{
// see if we have a session
if ( isset( $session ) )
{
// graph api request for user data
$request = new FacebookRequest( $session, 'GET', '/me' );
$response = $request->execute();
// get response
$graphObject = $response->getGraphObject();
// print data
echo '<pre>' . print_r( $graphObject, 1 ) . '</pre>';
$fb_Id = $graphObject->getProperty('id');
$fb_Name = $graphObject->getProperty('name');
echo "HEY <a href='" . $fb_link . "'>" . $fb_Name . "</a>";
echo "<br> Your fb-id: " . $fb_Id;
// if(CheckIfUserExistsInDatabase($fb_Id, $conn) == false)
// {
// InsertNewUser($conn, $fb_Id, $fb_Name);
// }
}
else {
// show login url
echo 'Login';
}
}
?>
What this code prints out:
!
To get the user's friends, you must request the user_friends permission when logging the user in:
$loginUrl = $helper->getLoginUrl( array( 'user_friends' ) );
Then, you'll be able to call the API as follows:
$friends = (new FacebookRequest( $session, 'GET', '/me/friends' ))->execute()->getGraphObject()->asArray();
echo '<pre>' . print_r( $friends, 1 ) . '</pre>';
See my tutorial for a complete solution.
The full solution then:
<?php
// added in v4.0.5
require_once( 'Facebook/FacebookHttpable.php' );
require_once( 'Facebook/FacebookCurl.php' );
require_once( 'Facebook/FacebookCurlHttpClient.php' );
// added in v4.0.0
require_once( 'Facebook/FacebookSession.php' );
require_once( 'Facebook/FacebookRedirectLoginHelper.php' );
require_once( 'Facebook/FacebookRequest.php' );
require_once( 'Facebook/FacebookResponse.php' );
require_once( 'Facebook/FacebookSDKException.php' );
require_once( 'Facebook/FacebookRequestException.php' );
require_once( 'Facebook/FacebookOtherException.php' );
require_once( 'Facebook/FacebookAuthorizationException.php' );
require_once( 'Facebook/GraphObject.php' );
require_once( 'Facebook/GraphSessionInfo.php' );
// added in v4.0.5
use Facebook\FacebookHttpable;
use Facebook\FacebookCurl;
use Facebook\FacebookCurlHttpClient;
// added in v4.0.0
use Facebook\FacebookSession;
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookRequest;
use Facebook\FacebookResponse;
use Facebook\FacebookSDKException;
use Facebook\FacebookRequestException;
use Facebook\FacebookOtherException;
use Facebook\FacebookAuthorizationException;
use Facebook\GraphObject;
use Facebook\GraphSessionInfo;
// start session
session_start();
// init app with app id and secret
FacebookSession::setDefaultApplication( 'XXX','YYY' );
// login helper with redirect_uri
$helper = new FacebookRedirectLoginHelper( 'http://livescoreapp.azurewebsites.net/' );
// see if a existing session exists
if ( isset( $_SESSION ) && isset( $_SESSION['fb_token'] ) ) {
// create new session from saved access_token
$session = new FacebookSession( $_SESSION['fb_token'] );
// validate the access_token to make sure it's still valid
try {
if ( !$session->validate() ) {
$session = null;
}
} catch ( Exception $e ) {
// catch any exceptions
$session = null;
}
} else {
// no session exists
try {
$session = $helper->getSessionFromRedirect();
} catch( FacebookRequestException $ex ) {
// When Facebook returns an error
} catch( Exception $ex ) {
// When validation fails or other local issues
echo $ex->message;
}
}
// see if we have a session
if ( isset( $session ) ) {
// save the session
$_SESSION['fb_token'] = $session->getToken();
// create a session using saved token or the new one we generated at login
$session = new FacebookSession( $session->getToken() );
// graph api request for user data
$friends = (new FacebookRequest( $session, 'GET', '/me/friends' ))->execute()->getGraphObject()->asArray();
echo '<pre>' . print_r( $friends, 1 ) . '</pre>';
// print logout url using session and redirect_uri (logout.php page should destroy the session)
echo 'Logout';
} else {
// show login url
echo 'Login';
}
?>
See the 90 line in FacebookRedirectLoginHelper.php .... it looks like
public function getLoginUrl($scope = array(), $version = null)
I change by
public function getLoginUrl($scope = array('email'), $version = null)
and works!!! PD. Put in &scope array the permissions you need.
Regards!!!
$fb = new Facebook\Facebook([/* . . . */]);
$helper = $fb->getRedirectLoginHelper();
$permissions = ['email', 'user_likes']; // optional
$loginUrl = $helper->getLoginUrl('http://{your-website}/login-callback.php', $permissions);
echo 'Log in with Facebook!';
Related
I am using Google people API client library in PHP.
After successfully authenticating, I want to get email
Help me to find out the problem from my code below.
Can i use multiple scopes to get email, beacuse when i m using different scope it gives me error
function getClient() {
$client = new Google_Client();
$client->setApplicationName('People API');
$client->setScopes(Google_Service_PeopleService::CONTACTS);
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
$str = file_get_contents('credentials.json');
$json = json_decode( $str, true );
$url = $json['web']['redirect_uris'][0];
if (isset($_GET['oauth'])) {
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$redirect_uri = $url;
header('Location: ' . filter_var($redirect_uri,FILTER_SANITIZE_URL));
} else if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
$people_service = new Google_Service_PeopleService($client);
} else {
$redirect_uri = $url.'/?oauth';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
return $people_service;
}
$optParams = array(
'pageSize' => 100,
'personFields' => 'addresses,ageRanges,biographies,birthdays,braggingRights,coverPhotos,emailAddresses,events,genders,imClients,interests,locales,memberships,metadata,names,nicknames,occupations,organizations,phoneNumbers,photos,relations,relationshipInterests,relationshipStatuses,residences,sipAddresses,skills,taglines,urls,userDefined',
);
$people_service = getClient();
$connections = $people_service->people_connections-
>listPeopleConnections('people/me', $optParams);
Is there a way to configure Tomcat 7 to create JSESSIONID cookie with a secure flag in all occasions?
Usual configuration results in Tomcat flagging session cookie with secure flag only if connection is made through https. However in my production scenario, Tomcat is behind a reverse proxy/load balancer which handles (and terminates) the https connection and contacts tomcat over http.
Can I somehow force secure flag on session cookie with Tomcat, even though connection is made through plain http?
In the end, contrary to my initial tests, web.xml solution worked for me on Tomcat 7.
E.g. I added this snippet to web.xml and it marks session cookie as secure even when reverse proxy contacts tomcat over plain HTTP.
<session-config>
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
</session-config>
ServletContext.getSessionCookieConfig().setSecure(true)
Another approach, similar to Mark's, would be to use the SessionCookieConfig, but set it in a context listener from JNDI configuration:
The code:
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.SessionCookieConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JndiSessionCookieConfigListener implements ServletContextListener {
private static final Logger logger = LoggerFactory.getLogger( JndiSessionCookieConfigListener.class );
private volatile Context jndiSessionCookieConfig;
private volatile SessionCookieConfig sessionCookieConfig;
#Override
public void contextInitialized( ServletContextEvent sce ) {
String listenerName = getClass().getSimpleName();
try {
logger.info( "JNDI override session cookie config found for {}", listenerName );
jndiSessionCookieConfig = (Context) new InitialContext().lookup(
"java:comp/env/" + listenerName );
}
catch ( NamingException e ) {
logger.info( "No JNDI override session cookie config found for {}", listenerName );
}
sessionCookieConfig = sce.getServletContext().getSessionCookieConfig();
String comment = getString( "comment" );
if ( comment != null ) {
logger.debug( "\t[comment]: [{}]", comment );
sessionCookieConfig.setComment( comment );
}
String domain = getString( "domain" );
if ( domain != null ) {
logger.debug( "\t[domain]: [{}]", domain );
sessionCookieConfig.setDomain( domain );
}
Boolean httpOnly = getBoolean( "http-only" );
if ( httpOnly == null ) {
sessionCookieConfig.setHttpOnly( true );
}
else {
logger.debug( "\t[http-only]: [{}]", httpOnly );
sessionCookieConfig.setHttpOnly( httpOnly );
}
Integer maxAge = getInteger( "max-age" );
if ( maxAge != null ) {
sessionCookieConfig.setMaxAge( maxAge );
}
String name = getString( "name" );
if ( name != null ) {
logger.debug( "\t[name]: [{}]", name );
sessionCookieConfig.setName( name );
}
String path = getString( "path" );
if ( path != null ) {
logger.debug( "\t[path]: [{}]", path );
sessionCookieConfig.setPath( path );
}
Boolean secure = getBoolean( "secure" );
if ( secure == null ) {
sessionCookieConfig.setSecure( true );
}
else {
logger.debug( "\t[secure]: [{}]", secure );
sessionCookieConfig.setSecure( secure );
}
}
#Override
public void contextDestroyed( ServletContextEvent sce ) {
}
private Boolean getBoolean( String name ) {
Object value;
try {
value = jndiSessionCookieConfig.lookup( name );
if ( value instanceof Boolean ) {
return (Boolean)value;
}
else {
return Boolean.valueOf( value.toString() );
}
}
catch ( NamingException e ) {
return null;
}
}
private Integer getInteger( String name ) {
Object value;
try {
value = jndiSessionCookieConfig.lookup( name );
if ( value instanceof Integer ) {
return (Integer)value;
}
else {
return Integer.valueOf( value.toString() );
}
}
catch ( NamingException e ) {
return null;
}
}
private String getString( String name ) {
Object value;
try {
value = jndiSessionCookieConfig.lookup( name );
return value.toString();
}
catch ( NamingException e ) {
return null;
}
}
}
Inside web.xml:
...
<listener>
<listener-class>
org.mitre.caasd.servlet.init.JndiSessionCookieConfigListener
</listener-class>
</listener>
...
In your context.xml:
...
<Environment name="JndiSessionCookieConfigListener/secure"
type="java.lang.String"
override="false"
value="true" />
...
This allows you to set all the session cookie configurations at runtime in the deployment environment. Thus, you could use the same webapp (war file) to do development locally (where you would not have https) and in production where you would ALWAYS want https.
Note, this approach is mentioned in the OWASP documentation
I'm going to use Prestashop 1.5.4 web-service to get all products with their attributes such as description, name and etc. My problem is whenever I call web-service it returns to me only the products Ids. How can I get attributes too?
Edited :
code :
class ShopApi
{
public $client;
public function __construct()
{
$this->getClient();
}
public function getClient()
{
try {
// creating web service access
$this->client = new PrestaShopWebservice('http://wikibazaar.ir/', 'A38L095W0RHRXE8PM9CM01CZW7KIU4PX', false);
} catch (PrestaShopWebserviceException $ex) {
// Shows a message related to the error
echo 'error: <br />' . $ex->getMessage();
}
}
}
class ProductApi extends ShopApi
{
public function findAll()
{
$products = array();
/// The key-value array
$opt['resource'] = 'products';
$opt['display'] = '[description]';
$opt['limit'] = 1;
$xml = $this->client->get($opt);
$resources = $xml->products->children();
foreach ($resources as $resource)
$products[] = $resource->attributes();
return $products;
}
}
EDIT :
I've found that the response from webservice is ok. but there is a problem during parsing xml with simplexml_load_string() function. any idea?
it's $product var_dump :
SimpleXMLElement#1 ( [products] => SimpleXMLElement#2 ( [product] => SimpleXMLElement#3 ( [description] => SimpleXMLElement#4 ( [language] => SimpleXMLElement#5 ( [#attributes] => array ( 'id' => '1' ) ) ) ) ) )
I think that $opt['display'] = 'full'; would do the job
You can also select only some specific attribute e.g.
$opt['display'] = '[id,name]';
Take a look at the official documentation, you might find it interesting
Everything else works fine except for the location. The actual city/state does not come across. Instead the word Array is displayed. My field type in the database is text but I've tried every field type through mysql. The HTML file is JSON where it comes to the field names. I am very new at this so any help is appreciated.
This is my php file:
<? ob_start(); ?>
<?php
define('FACEBOOK_APP_ID', '');
define('FACEBOOK_SECRET', '');
// No need to change function body
function parse_signed_request($signed_request, $secret) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
// decode the data
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
error_log('Unknown algorithm. Expected HMAC-SHA256');
return null;
}
// check sig
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
if ($_REQUEST) {
$response = parse_signed_request($_REQUEST['signed_request'],
FACEBOOK_SECRET);
/*
echo "<pre>";
print_r($response);
echo "</pre>"; // Uncomment this for printing the response Array
*/
$name = $response["registration"]["name"];
$email = $response["registration"]["email"];
$gender = $response["registration"]["gender"];
$prosecutor = $response["registration"]["prosecutor"];
$location = $response["registration"]["location"];
// Connecting to Database
$con = mysql_connect("my_hosting_site","Database","password");
if (!$response)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("Database", $con);
mysql_query("INSERT INTO my_table (name, email, gender, prosecutor, location)
VALUES ('$name', '$email', '$gender', '$prosecutor', '$location')");
mysql_close($con);
}
$URL="https://www.facebook.com";
header ("Location: $URL");
?>
<? ob_flush(); ?>
Facebook
Basically, it's an array.
[location] => Array
(
[name] => Delhi, India
[id] => 1.1604xxxxxx286E+14
)
Use this for getting location stored in your db, like I have written below:
$location = $response["registration"]["location"]["name"];
I have this error: Fatal error: Uncaught OAuthException: Invalid OAuth access token signature.
I can't get the system (like button to do the like in a photo (page photo - no permissions require I guess) work.. Can somebody help me?
test.php:
<?php
//include "dbc.php";
require './src/facebook.php';
$url = (!empty($_SERVER['HTTPS'])) ? 'https://'.$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF'].$_SERVER['REQUEST_URL'] : 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF'].$_SERVER['REQUEST_URL'];
$facebook = new Facebook(array(
'appId' => '******',
'secret' => '******',
'cookie' => true, // enable optional cookie support
));
$user = $facebook->getUser();
if ($user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');
//$pageInfo = $facebook->api('/'.$pageid.'?access_token='.$_SESSION['fb_112104298812138_access_token].');
//$pageInfoUser = $user_profile[id];
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
}
/* */
if ($user) {
$logoutUrl = $facebook->getLogoutUrl();
} else {
$params = array(
scope => 'read_stream,publish_stream,publish_actions,offline_access',
redirect_uri => $url
);
$loginUrl = $facebook->getLoginUrl($params);
}
$access_token = $facebook->getAccessToken();
// $access_token = $_SESSION['user_id'];
//$_SESSION['fb_135669679827333_access_token'];
if(!$user){
echo ' : Login ';
}else{
echo 'Logout';
}
?>
<?
function GetCH(){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://graph.facebook.com/oauth/access_token?client_id=112115512230132&client_secret=ef3d2a30aa9a3f799130565b8391d42dT&grant_type=client_credentials");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT_MS,20000);
if(substr($url,0,8)=='https://'){
// The following ensures SSL always works. A little detail:
// SSL does two things at once:
// 1. it encrypts communication
// 2. it ensures the target party is who it claims to be.
// In short, if the following code is allowed, CURL won't check if the
// certificate is known and valid, however, it still encrypts communication.
curl_setopt($ch,CURLOPT_HTTPAUTH,CURLAUTH_ANY);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
}
$sendCH = curl_exec($ch);
curl_close($ch);
return $sendCH;
};
echo "Access_token : ".$access_token;
$app_access_token = GetCH();
if($_GET['postid']){
$postid = $_GET['postid'];
echo "test1";
}else{
$postid = "ERROR";//'135669679827333_151602784936066';
}
if($access_token){
echo "test2";
$pageLike = $facebook->api('/'.$postid.'/likes?access_token='.$access_token.'&method=post', 'POST');
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
</head>
<body>
</body>
</html>
Update from OP post, below:
I have changed my code,
Now I have this code:
require_once './src/facebook.php';
class photo_liker {
function __construct()
{
$this->facebook = new Facebook( array('appId' => fb_appID, 'secret' => fb_secret, 'fileUpload' => true, 'cookie' => true));
}
function postPhotoLike($photoid)
{
try {
$args = array('access_token' => $this->facebook->getAccessToken());
$upload_photo = $this->facebook->api('/' . $photoid . '/likes', 'post', $args);
} catch (FacebookApiException $e) {
var_dump($e);
}
}
function login()
{
try {
$uid = $this->facebook->getUser();
} catch (Exception $e) {
var_dump($e);
}
if($uid) {
try {
$user = $this->facebook->api('/me');
} catch (Exception $e) {
var_dump($e);
}
return true;
} else {
$login_url = $this->facebook->getLoginUrl(array('scope' => 'email,publish_stream'));
ob_clean();
echo("<script>top.location.href='" . $login_url . "'</script>");
exit ;
}
return false;
}
}
$test = new photo_liker();
$test->login();
$test->postPhotoLike('103273136379847');
I got the getUser() == 0... I read that is a bug of SDK 3.* .. how can I solve it?