I was trying to made a post for google plus moment in php, i using below code, but when trying to post i am getting authorization error, I am doing with codeignitter
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
include_once 'base_controller.php';
class Gp_auth extends Base_controller {
private $_gp_client;
public function __construct() {
parent::__construct();
$this->load->library('googleplus');
$this->_gp_client = $this->googleplus->client;
}
public function index() {
if ($this->input->get_post('code')) {
try {
$this->_gp_client->authenticate($this->input->get_post('code'));
$access_token = $this->_gp_client->getAccessToken();
$this->session->set_userdata('access_token', $access_token);
redirect('/gp_auth/me');
} catch (Google_Auth_Exception $e) {
_print($e);
}
} else {
$this->_gp_client->addScope(array(
'https://www.googleapis.com/auth/plus.login',
'https://www.googleapis.com/auth/plus.moments.write'
));
$this->_gp_client->setRequestVisibleActions('http://schemas.google.com/AddActivity');
try {
echo anchor($this->_gp_client->createAuthUrl(), 'Conect Me');
} catch (Google_Auth_Exception $e) {
_print($e);
}
}
}
public function me() {
try {
$this->_gp_client->setAccessToken($this->session->userdata('access_token'));
$response = $this->googleplus->plus->people->get('me');
_print($response->id);
$post_data = array(
'gp_id' => $response->id,
'gp_access_token' => $this->session->userdata('access_token'),
'post_body' => 'Hello Google moment',
'post_attachment' => ''
);
$this->load->library('sns_post');
echo $this->sns_post->gp_post($post_data);
} catch (Google_Auth_Exception $e) {
_print($e);
}
}
}
index function was for authentication
and 'me' function for for post moment
and below code for library code of moment post , which is called from me function
public function gp_post($post_data) {
$this->_CI->load->library('googleplus');
_print($post_data['gp_access_token']);
$this->_CI->googleplus->client->setAccessToken($post_data['gp_access_token']);
$this->_CI->googleplus->client->setRequestVisibleActions('http://schemas.google.com/AddActivity');
$this->_CI->googleplus->item_scope->setId($post_data['gp_id']);
$this->_CI->googleplus->item_scope->setType("http://schema.google.com/AddAction");
$this->_CI->googleplus->item_scope->setName("The Google+ Platform");
$this->_CI->googleplus->item_scope->setDescription($post_data['post_body']);
if (!empty($post_data['post_attachment'])) {
$this->_CI->googleplus->item_scope->setImage($post_data['post_attachment']);
}
$this->_CI->googleplus->moment_body->setTarget($this->_CI->googleplus->item_scope);
// Execute the request
try {
$momentResult = $this->_CI->googleplus->plus->moments->insert('me', 'vault', $this->_CI->googleplus->moment_body);
_print($momentResult);
} catch (Google_Auth_Exception $e) {
_print($e);
} catch (Google_Service_Exception $servic_exception) {
_print($servic_exception);
}
if ($response->meta->status == 201) {
return $response->response->id;
} else {
return false;
}
I think you have get authorization error because of following reason -
Not setting email id & project name using developer console link APIs & Auth->Consent Screen.
You are calling deprecated API $this->_CI->googleplus->item_scope->setId($post_data['gp_id']);. To Call this you have to use this class new Google_Service_Plus_ItemScope();
$this->_CI->googleplus->moment_body->setTarget($this->_CI->googleplus->item_scope); .To call this method you have to use this class new Google_Service_Plus_Moment();
I have setup demo code in git for you. Google-Plus-API-Codeigniter-Starter. You can use same code to start with. I have provided detailed instruction in git repository too.
You have to Register your application using Google Console Settings as below:
Go to Google Developer Console
Create Project
To Get Google+ API Access go to: APIs & Auth->APIs -> enable Google+ API
To Get client_id & client_secret go to: APIs & Auth->Credentials->Create new Client ID
To Get api_key go to: APIs & Auth->Credentials->Create New Key->Browser key
To Get application_name go to: APIs & Auth->Consent Screen
Set Email Address
Product Name
Note: Ensure you have get all the required access from google as mentioned in point 5
Conclustion: You are using Latest google-api-php-client client. And trying to call method in an older way. Hence its not working.
Related
I'm working on a chat application using PubNub and PHP. The publishing of messages is working but I'm not sure how to read from the subscriber.
I ran the subscriber file in the command line and it is showing the messages as they are published but I'm not sure how to read from it or how to return, as per the doc the subscriber is a separate process.
use PubNub\PNConfiguration;
class MySubscribeCallback extends SubscribeCallback {
function status($pubnub, $status) {
if ($status->getCategory() === PNStatusCategory::PNUnexpectedDisconnectCategory) {
// This event happens when radio / connectivity is lost
} else if ($status->getCategory() === PNStatusCategory::PNConnectedCategory) {
} else if ($status->getCategory() === PNStatusCategory::PNDecryptionErrorCategory) {
// Handle message decryption error. Probably client configured to
// encrypt messages and on live data feed it received plain text.
}
}
function message($pubnub, $message) {
print_r($pubnub);
print_r($message);
}
function presence($pubnub, $presence) {
// handle incoming presence data
}
}
$subscribeCallback = new MySubscribeCallback();
$pubnub->addListener($subscribeCallback);
$pubnub->subscribe()
->channels(["Channel-1","Channel-2","Channel-3"])
->execute();
this is the subscriber code present on the PubNub Doc.
I'm calling this file using javascript.
I have been doing this google authentication tutorial to better understand how to use the google signin api and I have recently received this error:
Fatal error: Call to a member function getAttributes() on array.
It occurs whenever I am trying to:
$this->client->verifyIdToken()->getAttributes();
in the getPayload() function. I do not know why this is happening. My configuration is Windows 10 and I am using WAMP server to run this application. Any help would be appreciated.
<?php class GoogleAuth {
private $db;
private $client;
public function __construct(Google_Client $googleClient)
{
$this->client = $googleClient;
$this->client->setClientId('234sfsdfasdfasdf3223jgfhjghsdsdfge3.apps.googleusercontent.com');
$this->client->setClientSecret('fD5g4-B6e5dCDGASefsd-');
$this->client->setRedirectUri('http://localhost:9080/GoogleSigninTutorial/index.php');
$this->client->setScopes('email');
}
public function checkToken()
{
if(isset($_SESSION['access_token']) && !empty($_SESSION['access_token']))
{
$this->client->setAccessToken($_SESSION['access_token']);
}
else
{
return $this->client->createAuthUrl();
}
return '';
}
public function login()
{
if(isset($_GET['code']))
{
$this->client->authenticate($_GET['code']);
$_SESSION['access_token'] = $this->client->getAccessToken();
return true;
}
return false;
}
public function logout()
{
unset($_SESSION['access_token']);
}
public function getPayload()
{
return $this->client->verifyIdToken()->getAttributes();
}
}
?>
I've had the same problem.
From what I seemed to understand,
$attributes = $this->client->verifyIdToken()->getAttributes();
is an outdated way to access the array supposed to return the information of the google account (i.e. after running this line, $attributes was expected to be an array with all the information of the google account corresponding to the token.)
Try this instead
$this->client->verifyIdToken();
It seems that in the latest api (so far), this line in itself returns an array with the expected information (that's why you get an error when you add ->getAttributes(), because this function is not valid when called on an array.)
So simply run this line above to generate the array, and put it in echo if you want to see the values, like so
echo '<pre>', print_r($attributes), '</pre>';
If you don't see any array displayed, it may be that you have a
header('Location: url')
somewhere that is redirecting to another URL address right after executing this echo, thus it never shows. (Or a die)
You can also directly access specific attributes such as email, name, given_name, family_name by doing
$this->client->verifyIdToken()['email'];
$this->client->verifyIdToken()['name'];
//so on
Hope this can help.
BACKGROUND
We have a Wordpress site that requires a special kind of Facebook authentication. The WP site needs to authenticate a user with a different app, and then log the user into the app. The web app is built by us, and it has an API that the WP site uses to interact with it. Before we all get rowdy, this whole authentication process works using a normal login form. Using the API, we can easily see that the user is or is not logged into the app, and display that on the WP site.
PROBLEM
As stated, we need Facebook authentication. I am using Facebooks PHP SDK v4 and have it built into a custom plugin so as to keep the code seperate from the theme. When a user clicks on the FB icon, it shows the popup with the correct redirect URL. After a while, this popup closes, but there is nothing in the result. A few well placed var_dumps reveal that I'm not getting anything back from FacebookRedirectLoginHelper. This means I can't get the session which in turns means no user info.
CODE
As stated, I've created a plugin (ns-social.php) which handles everything. Here is that file:
/**
* Plugin Name: NS Social Plugin
*/
require_once 'ns-social-init.php';
require_once 'ns-callback-functions.php';
require_once 'ns-facebook.php' ;
$fb = null;
add_action('plugins_loaded','load_fb');
function load_fb() {
global $fb;
$fb = new WP_Facebook();
}
/**
* SOCIAL LOGIN CHECK
*/
function get_fb_url()
{
global $fb;
return $fb->login_url();
}
ns-social-init.php starts a session that FB can use:
/**
* Any functions that are required during initialisation of Wordpress or this plugin
*/
add_action('plugins_loaded', 'start_session');
function start_session()
{
if (!session_id()) {
session_start();
}
}
ns-callback-functions.php contains all the callback functions for the redirects. These are all shortcodes that are placed in pages, so the url will be www.site.com/facebook-callback and that page will only have [facebook-callback] in it which will handle the request.
add_shortcode('facebook_callback', 'facebook_callback');
function facebook_callback()
{
global $fb;
if (isset($_GET['error'])) {
if ($_GET['error'] == 'access_denied') {
echo "<script>
if(window.opener != null) {
window.close();
}
</script>";
exit;
}
}
$session = $fb->get_session();
$userArr = $fb->get_user();
$user['name'] = $userArr['first_name'];
$user['surname'] = $userArr['last_name'];
$user['email'] = $userArr['email'];
$user['verified'] = $userArr['verified'];
$_SESSION['registeruser'] = $user;
$_SESSION['registertype'] = 'Facebook';
$action = "";
die(var_dump($_SESSION,true));
if (user_exists($user['email'])) {
$action = '?login';
}
wp_redirect(home_url('social-register/' . $action));
}
And last but not least, my ns-facebook.php file:
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookSession;
use Facebook\FacebookRequest;
class WP_Facebook
{
var $helper;
var $session;
var $permissions;
var $loginurl;
public function __construct()
{
// Initialize the SDK
FacebookSession::setDefaultApplication('0appId145', '00hahaitsmysecret23523');
$this->permissions = ['public_profile', 'email'];
$this->helper = new FacebookRedirectLoginHelper(home_url('facebook-callback'));
$this->loginurl = $this->helper->getLoginUrl($this->permissions);
}
/**
* Returns the login URL.
*
* #return string
*/
public function login_url()
{
return $this->loginurl;
}
/**
* Returns the current user's info as an array.
*/
public function get_user($session = null)
{
if(empty($session)) $session = $this->session;
if($session) {
/**
* Retrieve User's Profile Information
*/
// Graph API to request user data
$request = new FacebookRequest($session, 'GET', '/me');
$response = $request->execute();
// Get response as an array
$user = $response->getGraphObject()->asArray();
return $user;
}
return false;
}
public function get_session() {
try {
$this->session = $this->helper->getSessionFromRedirect();
} catch(FacebookRequestException $ex) {
// When Facebook returns an error
} catch(\Exception $ex) {
// When validation fails or other local issues
}
if ($this->session) {
return $this->session;
}
}
}
WHAT HAVE I TRIED
I've gone through quite a few questions on SO. What I have noticed is, when I first run the page, my FBRLH_state in my session is, abcdef for example. But when I get a response after clicking the login button, my FBRLH_state is xyz. I don't know if this has an effect on the outcome. If it could, how would I use this state? I don't set it, I'm assuming that the FB SDK does.
TL;DR
FB PHP SDK v4 is not sending back anything when I use FacebookRedirectLoginHelper. Why would it do this, and how do I fix it?
did you make a test with just the offical FacebookRedirectLoginHelper from official GitHub?
I have used the Facebook SDK a couple of times and never had a problem with missing returns.
So I fixed my issue with help from corvuszero's comment.
Here's the code in my ns-facebook.php file:
use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use Facebook\FacebookRedirectLoginHelper;
class WP_Facebook
{
var $helper;
var $session;
var $permissions;
var $loginurl;
public function __construct()
{
// Initialize the SDK
FacebookSession::setDefaultApplication('303664476506500', '0197b7f08cc46f051ddb92dfba077484');
$this->permissions = ['public_profile', 'email'];
$this->helper = new FacebookRedirectLoginHelper( home_url('facebook-callback') );
try {
$this->session = $this->helper->getSessionFromRedirect();
} catch (FacebookRequestException $e) {
// handler
} catch (Exception $e) {
// handler
}
if(isset($_SESSION['fb_token'])) {
$this->session = new FacebookSession( $_SESSION['fb_token'] );
}
if($this->session) {
$_SESSION['fb_token'] = $this->session->getToken();
} else {
$this->loginurl = $this->helper->getLoginUrl($this->permissions);
}
}
/**
* Returns the login URL.
*
* #return string
*/
public function login_url()
{
return $this->loginurl;
}
/**
* Returns the current user's info as an array.
*/
public function get_user()
{
if($this->session) {
/**
* Retrieve User’s Profile Information
*/
// Graph API to request user data
$request = new FacebookRequest($this->session, 'GET', '/me');
$response = $request->execute();
// Get response as an array
$user = $response->getGraphObject()->asArray();
return $user;
}
return false;
}
public function get_session() {
return $this->session;
}
}
I am using Facebook-sdk bundle for Laravel and everything works fine, except the logout link. When I click logout, I get redirected and all looks like it is working, but when it loads the page back, I'm still logged in?
Is this a Laravel problem maybe? Does it store sessions differently?
I've built this class, but as I said, I don't think this is a problem because all is working fine, except logout session is not getting cleared.
Code:
class Fb{
// -----------------------------------------------------------------------
// Variables
private $ioc; // IOC container
public $state; // If logged or not
public $data; // Data that came from request
public $settings = array("name,gender");
// -----------------------------------------------------------------------
// Logical functions
public function __construct(){
$this->ioc = IoC::resolve('facebook-sdk');
if ($this->getUser()) {
try {
$this->request();
$this->state = true;
} catch (FacebookApiException $e) {
error_log($e);
}
}else{
$this->state = false;
}
}
public function getUser(){
return $this->ioc->getUser();
}
public function request(){
$this->data = $this->ioc->api("/me?fields=".implode($this->settings));
}
public function debug(){
return dd($this->data);
}
// -----------------------------------------------------------------------
// Login & Logout links
public function login(){
return $this->ioc->getLoginUrl();
}
public function logout(){
return $this->ioc->getLogoutUrl();
}
// -----------------------------------------------------------------------
// Get data via SDK
// Name
public function name(){
return $this->data['name'];
}
// Picture
public function picture($w=50,$h=50){
return "https://graph.facebook.com/". $this->data['id'] ."/picture?width=$w&height=$h";
}
// Gender
public function gender(){
return $this->data['gender'];
}
}
Thanks for any help!
Cheers!
The underlying facebook php sdk uses the built in php sessions (by default) to store persistent information like the authenticated facebook user's id.
However the sdk won't destroy this information on its own since it's difficult to tell when that should happen automatically.
You can clear this persisted information with the destroySession method on the facebook sdk object. The best place to call this method is on the logout url's redirect back endpoint, since that is where the visitor gets directly after facebook done with it's own logout.
This would look like:
// method on Fb class
public function destroySession() {
// just forward the call down to the sdk object
$this->ioc->destroySession();
}
You probably want to set up a route where users will arrive after logout and pass it into getLogoutUrl() like this:
// method on Fb class
public function logout(){
// tell explicity where to send the user when facebook is done, otherwise the current url will be used
return $this->ioc->getLogoutUrl(array('next' => URL::to_route('after_logout')));
}
And have a route like this:
Route::get('after_logout', array('as' => 'after_logout', 'do' => function() {
$fb = new Fb();
// call the session clearing
$fb->destroySession();
// send the user to its merry way
return Redirect::to('/');
}));
Going over the Facebook API and I'm a bit confused on the right approach. I want users to skip registration, or auto-register them if they sign in with Facebook. So if they sign into Facebook I collect their id, email and create a record in my user table.
If an id exists already in the user table they skip the auto-registration and go directly to the members page. This is my code so far (taken from Facebook's PHP SDK example). When I run the signup script the page shows up as blank, I do not get redirected.
EDIT: seems to be failing right after the require, if I use the following code 'test' never gets printed.
EDIT: I'm using Codeigniter and this script is part of a controller, would that cause a problem with the require?
require 'http://localhost/facebook-php-sdk-6c82b3f/src/facebook.php';
echo "test";
-
public function signup()
{
require 'http://localhost/facebook-php-sdk-6c82b3f/src/facebook.php';
// Create our Application instance (replace this with your appId and secret).
$facebook = new Facebook(array(
'appId' => 'xxxxxxxxxxxxxxx',
'secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxx',
));
// Get User ID
$user = $facebook->getUser();
// We may or may not have this data based on whether the user is logged in.
//
// If we have a $user id here, it means we know the user is logged into
// Facebook, but we don't know if the access token is valid. An access
// token is invalid if the user logged out of Facebook.
if ($user)
{
try
{
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');
}
catch (FacebookApiException $e)
{
error_log($e);
$user = null;
}
}
// Login or logout url will be needed depending on current user state.
if ($user)
{
$logoutUrl = $facebook->getLogoutUrl();
}
else
{
$loginUrl = $facebook->getLoginUrl(array('scope' => 'email'));
redirect($loginUrl);
}
print_r($user_profile);
$this->load->model("user_model");
$privileges = 1;
$loginLocation = ip2long($_SERVER['REMOTE_ADDR']);
$active = 1;
$this->user_model->add_user($user_profile->id, $user_profile->name, $user_profile->email, $loginLocation, $privileges, $active);
}
I suggest you read the framework documentation. Adding a library to CodeIgniter is not a hard task. And Facebook library is no exception.
Here's a quick integration I've just come up with:
1.create a config file:application/config/facebook.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
$config['appId'] = 'app_id';
$config['secret'] = 'app_secret';
2.place the sdk files in the libraries folder application/libraries/ and rename the facebook.php file to Facebook.php and replace the php tag with this:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
3.in your controller load the config file and then load the Facebook library:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Welcome extends CI_Controller {
public function __construct()
{
parent::__construct();
// Your own constructor code
$CI = & get_instance();
$CI->config->load("facebook",TRUE);
$config = $CI->config->item('facebook');
$this->load->library('facebook', $config);
}
public function index()
{
$user = $this->facebook->getUser();
if($user) {
try {
$user_info = $this->facebook->api('/me');
echo '<pre>'.htmlspecialchars(print_r($user_info, true)).'</pre>';
} catch(FacebookApiException $e) {
echo '<pre>'.htmlspecialchars(print_r($e, true)).'</pre>';
$user = null;
}
} else {
echo "Login using Facebook";
}
}
}
Now in the constructor method, you have just initialized the Facebook library (sdk) and it can be accessed by using: $this->facebook.
Notes:
You can always use an existing library, just google it
A common practice is to extend the core Controller class and add the Facebook library initialization there.
Or create another library, extend the Facebook library, load the config file there and then autoload this new library.
After getting the $user, check session parameters with print_r($_SESSION). After that, check some variables by if(isset($_SESSION['some session var'])). If this condition is true, then navigate to your main page with header("location:main.php"); exit;
You can try using my extension http://github.com/deth4uall/Facebook-Ignited it is set up to work with Facebook. Just update the config file and it will allow you to do what you need to do, as well as some additional methods that I added myself.
do not know why, but it always runs this line:
echo "Login using Facebook";
This is the error message:
couldn't connect to host
But this worked.