I am implementing the facebook connect and its working partially well for me. Its successfully loging the user when some login in with facebook. Here is the link for login http://beta-demo.info/party/users/loginByFacebook but after login when i am trying to fetch user detail from facebook its now displaying anything.
Here is the code of of Fb_Connect.php This file is placed in Libraries folder
<?php
include(APPPATH.'libraries/facebook/facebook.php');
class Fb_connect extends Facebook{
//declare public variables
public $user = NULL;
public $user_id = FALSE;
public $fb = FALSE;
public $fbSession = FALSE;
public $appkey = 0;
//constructor method.
public function __construct()
{
$CI = & get_instance();
$CI->config->load("facebook",TRUE);
$config = $CI->config->item('facebook');
parent::__construct($config);
$this->user_id = $this->getUser(); // New code
$me = null;
if ($this->user_id) {
try {
$me = $this->api('/me');
$this->user = $me;
} catch (FacebookApiException $e) {
error_log($e);
}
}
}
} // end class
and this is loging function
function loginByFacebook(){
$this->load->library('fb_connect');
$param['redirect_uri']=base_url();
redirect($this->fb_connect->getLoginUrl($param));
}
and this is the info function where i am trying to fetch the value.
function facebook() {
print('<pre>');
print_r($this->fb_connect);
if (!$this->fb_connect->user_id) {
echo 'No working ';
//Handle not logged in,
} else {
echo $fb_uid = $this->fb_connect->user_id;
echo $fb_usr = $this->fb_connect->user;
//Hanlde user logged in, you can update your session with the available data
//print_r($fb_usr) will help to see what is returned
}
}
Url of the info page http://beta-demo.info/party/users/facebook
I dont have much of idea about facebook connect API.so please help me
The only thing I can see you are missing are the fields when calling '/me'. This is the function I used to get the info from facebook connect. Working example: http://www.paravegetarianos.com
function facebookConnect()
{
$this->config->load('facebook', TRUE);
$config = array(
'appId' => $this->config->item('facebook_api_id', 'facebook'),
'secret' => $this->config->item('facebook_secret_key', 'facebook'),
'fileUpload' => true,
);
$this->load->library('Facebook', $config);
$user = $this->facebook->getUser();
$profile = null;
if($user):
try {
$profile = $this->facebook->api('/me?fields=id,username,email'); //<--- you are missing the fields
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
endif;
if($profile != null):
$profile['uid'] = $user;
$data = $profile;
var_dump($data); //<--------- Information
die();
endif;
}
This is the working code for me
<?php
function loginByFacebook()
{
$this->load->library('fb_connect');
$param = array(
'scope' =>'email,user_location,user_birthday,offline_access', 'redirect_uri' => base_url()
);
redirect($this->fb_connect->getLoginUrl($param));
}
function facebook()
{
if (!$this->fb_connect->user_id) {
} else {
$fb_uid = $this->fb_connect->user_id;
$fb_usr = $this->fb_connect->user;
$firstname = $fb_usr['first_name'];
}
?>
Related
I try to learn how to manage session with JWT. But now I'm stuck because i always get exception after login, and it always redirect me to login page again and again.
There is no error detected, and i can't find what's wrong in my code. So i hope you all can help me although it is just look like a simple questions
I try to browse to check where is the problem. And i'm sure the problem is in the file session.php. But i don't know whats wrong
<?php
// use Firebase\JWT\JWT;
class Session
{
public $username, $role;
public function __construct(string $username, string $role)
{
$this->username = $username;
$this->role = $role;
}
}
class SessionManager
{
// public $SECRET_KEY = 'ajfhakjdfhah/A203FHkafhiuefhhncueuvuwevwevwev';
public static function login(string $username, string $password): bool
{
if ($username == "eko" && $password == "eko") {
$SECRET_KEY = 'AKDJHFEVN123akdhfvbuevmkc';
$payload = [
"username" => $username,
"role" => "customer"
];
$jwt = \Firebase\JWT\JWT::encode($payload, $SECRET_KEY, 'HS256');
setcookie('USER-SESSION', $jwt);
return true;
} else {
return false;
}
}
public static function getCurrentSession(): Session
{
if ($_COOKIE['USER-SESSION']) {
$jwt = $_COOKIE['USER-SESSION'];
$SECRET_KEY = 'AKDJHFEVN123akdhfvbuevmkc';
$payload = \Firebase\JWT\JWT::decode($jwt, $SECRET_KEY, ['HS256']);
try {
$payload = \Firebase\JWT\JWT::decode($jwt, $SECRET_KEY, ['HS256']);
return new Session($payload->username, $payload->role);
} catch (Exception $exception) {
throw new Exception("User is not login");
}
} else {
throw new Exception("User is not login");
}
}
}
I know that for experienced Laravel developers this question my sound silly, but I followed this article for implementing Facebook SDK.
I followed everything from adding new token column in database to implementing controller.
This is my GraphController.php file:
class GraphController extends Controller
{
private $api;
public function __construct(Facebook $fb)
{
$this->middleware(function ($request, $next) use ($fb) {
$fb->setDefaultAccessToken(Auth::user()->token);
$this->api = $fb;
return $next($request);
});
}
public function getPageAccessToken($page_id){
try {
// Get the \Facebook\GraphNodes\GraphUser object for the current user.
// If you provided a 'default_access_token', the '{access-token}' is optional.
$response = $this->api->get('/me/accounts', Auth::user()->token);
} catch(FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
try {
$pages = $response->getGraphEdge()->asArray();
foreach ($pages as $key) {
if ($key['id'] == $page_id) {
return $key['access_token'];
}
}
} catch (FacebookSDKException $e) {
dd($e); // handle exception
}
}
public function publishToPage(Request $request, $title){
$page_id = 'XXXXXXXXXXXXX';
try {
$post = $this->api->post('/' . $page_id . '/feed', array('message' => $title), $this->getPageAccessToken($page_id));
$post = $post->getGraphNode()->asArray();
} catch (FacebookSDKException $e) {
dd($e); // handle exception
}
}
}
This is my routes/web.php :
Route::group(['middleware' => [
'auth'
]], function(){
Route::post('/page', 'GraphController#publishToPage');
});
FacebookServiceProvider:
class FacebookServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* #return void
*/
public function register()
{
$this->app->singleton(Facebook::class, function ($app) {
$config = config('services.facebook');
return new Facebook([
'app_id' => $config['client_id'],
'app_secret' => $config['client_secret'],
'default_graph_version' => 'v2.6',
]);
});
}
}
Now, I would need to use publishToPage inside of my PostController.php file:
public function store(Requests\PostRequest $request)
{
$data = $this->handleRequest($request);
$newPost = $request->user()->posts()->create($data);
$newPost->createTags($data["post_tags"]);
/*
// My other notifications that are working:
// OneSignal
OneSignal::sendNotificationToAll(
"New warning ".$newPost->title
);
// MailChimp
$this->notify($request, $newPost);
// Twitter
$newPost->notify(new ArticlePublished());
*/
// I WOULD NEED SOMETHING IN THIS WAY ALSO FOR FACEBOOK BUT THIS OBVIOUSLY DOESN'T WORK
GraphController::publishToPage($request, $newPost->title);
}
Can you please suggest good way how to do it from here?
I need to apologize again if this seems to you like basics of Laravel that I should know, but I really struggling to wrap my head around this and your suggestions would really help me to understand it better.
Integrating Twitter, MailChimp, OneSignal notifications was really easy but Facebook restricted policies makes it quite confusing for me.
Thank you guys. I really appreciate it!
Sadly, Facebook still didn't get me permission for auto posting so I cannot try, if it realy works.
I think I found a solution to this particular problem though. Credit goes to Sti3bas from Laracast.
namespace App\Services;
class FacebookPoster
{
protected $api;
public function __construct(Facebook $fb)
{
$fb->setDefaultAccessToken(Auth::user()->token);
$this->api = $fb;
}
protected function getPageAccessToken($page_id){
try {
// Get the \Facebook\GraphNodes\GraphUser object for the current user.
// If you provided a 'default_access_token', the '{access-token}' is optional.
$response = $this->api->get('/me/accounts', Auth::user()->token);
} catch(FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
try {
$pages = $response->getGraphEdge()->asArray();
foreach ($pages as $key) {
if ($key['id'] == $page_id) {
return $key['access_token'];
}
}
} catch (FacebookSDKException $e) {
dd($e); // handle exception
}
}
public function publishToPage($page, $title){
try {
$post = $this->api->post('/' . $page . '/feed', array('message' => $title), $this->getPageAccessToken($page));
$post = $post->getGraphNode()->asArray();
} catch (FacebookSDKException $e) {
dd($e); // handle exception
}
}
}
Then refact controllers:
use App\Services\FacebookPoster;
//...
class GraphController extends Controller
{
public function publishToPage(Request $request, FacebookPoster $facebookPoster)
{
$page_id = 'XXXXXXXXXXXXX';
$title = 'XXXXXXXXXXXXX';
$facebookPoster->publishToPage($page_id, $title);
}
}
use App\Services\FacebookPoster;
//...
public function store(PostRequest $request, FacebookPoster $facebookPoster)
{
$data = $this->handleRequest($request);
$newPost = $request->user()->posts()->create($data);
$newPost->createTags($data["post_tags"]);
//...
$facebookPoster->publishToPage($page, $newPost->title);
}
I'm using yii2-dektrium to allow users login with their facebook's accounts.
After the login is done, I need to make API request from my server to get data of the user's accounts. One example of request is:
$client = Yii::$app->authClientCollection->getClient('facebook');
$response = $client->createApiRequest()
->setMethod('GET')
->setUrl('v2.12/me/accounts')
->send();
The access_token is saved on session so I need to persist it to the database.
I already added a column access_token to the social_account default table of yii2-dektrium but I don't know how to get and save it, and further more, how to apply it to the requests.
After reading for a while. I think the way to save it is overriding the method connect in dektrium\user\controllers\SecurityController.
public function connect(ClientInterface $client)
{
/** #var Account $account */
$account = \Yii::createObject(Account::className());
$event = $this->getAuthEvent($account, $client);
$this->trigger(self::EVENT_BEFORE_CONNECT, $event);
$account->connectWithUser($client);
$this->trigger(self::EVENT_AFTER_CONNECT, $event);
$this->action->successUrl = Url::to(['/user/settings/networks']);
}
And for applying to the request, override applyAccessTokenToRequest on yii\authclient\clients\Facebook
public function applyAccessTokenToRequest($request, $accessToken)
{
parent::applyAccessTokenToRequest($request, $accessToken);
$data = $request->getData();
if (($machineId = $accessToken->getParam('machine_id')) !== null) {
$data['machine_id'] = $machineId;
}
$data['appsecret_proof'] = hash_hmac('sha256', $accessToken->getToken(), $this->clientSecret);
$request->setData($data);
}
I can't get it done. And I'm not sure if it is the right way to do it. What I'm missing?
For save the access_token the first time you have to overwrite the connect action from \dektrium\user\controllers\SecurityController.
class SecurityController extends \dektrium\user\controllers\SecurityController
{
public function connect(ClientInterface $client)
{
// default implementation of connect
$account = \Yii::createObject(Account::className());
$event = $this->getAuthEvent($account, $client);
$this->trigger(self::EVENT_BEFORE_CONNECT, $event);
$account->connectWithUser($client);
$this->trigger(self::EVENT_AFTER_CONNECT, $event);
// get acess_token from $client
$access_token['tokenParamKey'] = $client->getAccessToken()->tokenParamKey;
$access_token['tokenSecretParamKey'] = $client->getAccessToken()->tokenSecretParamKey;
$access_token['createTimestamp'] = $client->getAccessToken()->createTimestamp;
$access_token['_expireDurationParamKey'] = $client->getAccessToken()->getExpireDurationParamKey();
$access_token['_params'] = $client->getAccessToken()->getParams();
// save acess_token to social_account table
$model = SocialAccount::find()->where(['provider' => $client->getName()])->andWhere(['user_id' => Yii::$app->user->id])->one();
$model->access_token = \yii\helpers\Json::encode($access_token);
$model->save(false);
$this->action->successUrl = Url::to(['/user/settings/networks']);
}
}
To get the access_token store in the database for further API Requests create a class that extends yii\authclient\SessionStateStorage and overwrite get method.
namespace app\models\authclient;
class DbStateStorage extends SessionStateStorage
{
public function get($key)
{
// $key is a complex string that ends with 'token' if the value to get is the actual access_token
$part = explode('_', $key);
if (count($part) == 3 && $part[2] == 'token') {
$account = SocialAccount::find()
->where(['provider' => $part[1]])
->andWhere(['user_id' => Yii::$app->user->id])
->one();
if ($account != null) {
$access_token = json_decode($account->access_token);
$token = new \yii\authclient\OAuthToken();
$token->createTimestamp = $access_token->createTimestamp;
$token->tokenParamKey = $access_token->tokenParamKey;
$token->tokenSecretParamKey = $access_token->tokenSecretParamKey;
$token->setParams((array)$access_token->_params);
$token->setExpireDurationParamKey($access_token->_expireDurationParamKey);
return $token;
}
}
if ($this->session !== null) {
return $this->session->get($key);
}
return null;
}
}
Finally set the DbStateStorage to your authclient
class Facebook extends \dektrium\user\clients\Facebook
{
public function __construct()
{
$this->setStateStorage('app\models\authclient\DbStateStorage');
}
}
I'm trying to do Facebook Login in my Codeigniter function. I set configs and redirected to permission page also i got the permission from user and finally redirected page to again this function but still getUser() function is returning 0. What is the problem here? Can anybody help? My codes here;
public function facebook_uye() {
$fb_config = array(
'appId' => 'xxxxx',
'secret' => 'xxxxxxxxxxxxxxx'
);
$this->load->library('facebook', $fb_config);
$user = $this->facebook->getUser();
if ($user) {
try {
$user_profile = $this->facebook->api('/me');
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
print_r($user_profile);
} else {
$url = "https://graph.facebook.com/oauth/authorize?client_id=xxxxxxx&redirect_uri=http://www.blahblah.com/&scope=email";
echo "<script language=javascript>window.open('$url', '_parent', '')</script>";
}
}
Well I just tried updating my script and I keep getting a return of 0 for getUser()
here are a couple snippets that i changed
old code
<?php
require_once("src/facebook.php");
class cfb
{
public $fb;
public $_fb_user;
public $_fb_details;
public $_fb_app_id = '**************';
private $_fb_app_secret = '***************';
private $_user;
function __construct()
{
$this->fb = new Facebook(array(
'appId' => $this->_fb_app_id,
'secret' => $this->_fb_app_secret,
'cookie' => true,
));
$this->_fb_user = $this->fb->getSession();
$this->DB = new db();
$this->_user = new user();
}
public function session_exists()
{
// see if there is a session stored, if so make sure the session is still good on facebooks end
if($this->_fb_user) {
// test if session is still good
try
{
$me = $this->fb->api('/me');
}
catch(FacebookApiException $e){
error_log($e);
}
if(!empty($me)) {
return true;
}
} else {
return false;
}
}
new code
<?php
require_once("src/facebook.php");
class cfb
{
public $fb;
public $_fb_user;
public $_fb_details;
public $_fb_app_id = '*****************';
private $_fb_app_secret = '********************';
private $_user;
function __construct()
{
$this->fb = new Facebook(array(
'appId' => $this->_fb_app_id,
'secret' => $this->_fb_app_secret,
));
$this->_fb_user = $this->fb->getUser();
$this->DB = new db();
$this->_user = new user();
}
public function session_exists()
{
// see if there is a session stored, if so make sure the session is still good on facebooks end
if($this->_fb_user) {
// test if session is still good
try
{
$me = $this->fb->api('/me');
}
catch(FacebookApiException $e){
echo '<pre>'.htmlspecialchars(print_r($e, true)).'</pre>';
}
if(!empty($me)) {
return true;
}
} else {
return false;
}
}
here is my js code
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '<?php echo $fb->_fb_app_id; ?>',
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// whenever the user logs in, we refresh the page
FB.Event.subscribe('auth.login', function(response) {
window.location="<?php echo $fbredirect; ?>";
});
};
(function() {
var e = document.createElement('script'); e.async = true;
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
}());
</script>
I can't figure it out. was hoping it would be simple update but i guess not =/
In your JS code, add oauth:true inside the FB.init function.
You can see the PHP SDK v.3.1.1 working with the JS SDK in the example here: https://developers.facebook.com/blog/post/534/