Session is destroyed when browser is closed. | ZF2 - php

I want to implement session and cookies in my zend application. Session is working fine within the tabs but when I reopen the browser then sessionId in the cookie changes and my application shows user is not logged in.
Below is the code of Module.php of Application Module.
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$eventManager->attach('dispatch', array($this, 'loadConfiguration' ));
$this->initSession(array(
'remember_me_seconds' => 864000,
'use_cookies' => true,
'cookie_httponly' => true,
'cookie_secure' => false,
));
}
public function initSession($config){
$sessionConfig = new SessionConfig();
$sessionConfig->setOptions($config);
$sessionManager = new SessionManager($sessionConfig);
$sessionManager->start();
Container::setDefaultManager($sessionManager);
}
public function loadConfiguration(MvcEvent $e)
{
$controller = $e->getTarget();
$session = new Container('user_session_data');
if(isset($session->user_id)){
//user is logged in set his data to viewModel
$controller->layout()->user_id = $session->user_id;
$controller->layout()->firstName = $session->firstName;
$controller->layout()->lastName = $session->lastName;
$controller->layout()->profilePicture = $session->profilePicture;
}
}
I access these values in my layout.phtml file. Below is the code to save session data when user is successfully logged in.
$session = new Container('user_session_data');
if($session->user_id){
echo "You are already logged in";
}
// store user details in session
$session->user_id = $responseDataArray['data']['id'];
$session->firstName = $responseDataArray['data']['firstName'];
$session->lastName = $responseDataArray['data']['lastName'];
$session->profilePicture = $responseDataArray['data' ['profilePicture'];
I don't know what I am missing to persist session data.

Related

How to log user in and out in slim rest framework using slim session middleware?

I am using Slim framework to build a REST API and this is a rough application that I am using for development purposes. I want to log user in and out , and I set the session variable to the user id. The user is able to login perfectly fine in rest API but the remote device doesnt recognize the session (which means my $SESSION['id'] is empty) where as I clearly started this session in my host rest service. Here is my code:
require 'lib/Slim/Slim.php';
use lib\Slim\Middleware\SessionCookie;
\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim(
array(
'cookies.encrypt' => true,
'cookies.secret_key' => 'my_secret_key',
'cookies.cipher' => MCRYPT_RIJNDAEL_256,
'cookies.cipher_mode' => MCRYPT_MODE_CBC
)
);
$app->add(new \Slim\Middleware\SessionCookie(array(
'expires' => '20 minutes',
'path' => '/',
'domain' => '',
'secure' => false,
'httponly' => false,
'name' => 'slim_session',
'secret' => '',
'cipher' => MCRYPT_RIJNDAEL_256,
'cipher_mode' => MCRYPT_MODE_CBC
)));
$app->get("/login/:string", function($string) use ($app)
{
$input = json_decode($string);
try
{
if ($input->username && $input->password)
{
$user = Model::factory('Users')->where("username",$input->username)->where("password",md5($input->password))->find_one();
//$app->setCookie('user_id',$user->id);
session_cache_limiter(false);
session_start();
$_SESSION['id'] = $user->id;
$status = 'success';
$message = 'Logged in successfully.';
}
else
{
$status = false;
$message = 'Could not log you in. Please try again.';
}
}
catch (Exception $e)
{
$status = 'danger';
$message = $e->getMessage();
}
$response = array(
'status' => $status,
'message' => $message
);
$app->response()->header("Content-Type", "application/json");
echo json_encode($response);
});
$app->get("/logout",function() use ($app)
{
try {
unset($_SESSION['id']);
session_destroy();
session_start();
//$app->getCookie('user_id');
$status = 'success';
$message = 'You have been logged out successfully';
}
catch (Exception $e)
{
$status = 'danger';
$message = $e->getMessage();
}
$response = array(
'status' => $status,
'message' => $message
);
$app->response()->header("Content-Type", "application/json");
echo json_encode($response);
});
It is returning 'Logged in successfully' but isn't actually logging me in so in my application when I check isset($_SESSION['id']) , there is nothing in the variable. Does anyone know whats going on? I am really confused because according to the slim documentation , it says :
The session cookie middleware will work seamlessly with the $_SESSION superglobal so you can easily migrate to this session
storage middleware with zero changes to your application code.
If you use the session cookie middleware, you DO NOT need to start a
native PHP session. The $_SESSION superglobal will still be available,
and it will be persisted into an HTTP cookie via the middleware layer
rather than with PHP’s native session management.
The issue would seem to be that you are not starting your session soon enough not anything with session middleware I would place session_start() at the top of the index
require 'lib/Slim/Slim.php';
use lib\Slim\Middleware\SessionCookie;
session_start();
Now it is started every time your application routes. So in login and logout remove your session_start() calls. Now in logout route redirect to your landing page or somewhere like:
$app->redirect('/yourawesomepage');
that recalls session_start() so you can remove that from here your logout route.

Logging a User in Programmatically for a Functional Test with FOSUserBundle

I am attempting to log a user in programmatically in my functional test on SF 2.7 and FOSUserBundle dev-master. I have already found a good reference to log a user in via SO in this answer - Symfony2 - Tests with FOSUserBundle
The problem is that the second answer, logging the user in programmatically, doesn't work. Here is my code:
<?php
namespace Test\BackEnd\UserBundle\Controller;
use Test\Shared\CoreBundle\Tests\AbstractControllerTest;
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Doctrine\Common\DataFixtures\Loader;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\ORM\Tools\SchemaTool;
use FA\BackEnd\UserBundle\DataFixtures\ORM\LoadUserData;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\BrowserKit\Cookie;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
class DefaultController extends AbstractControllerTest
{
public function setUp()
{
$this->client = static::createClient();
$container = $this->client->getContainer();
$doctrine = $container->get('doctrine');
$em = $doctrine->getManager();
$schemaTool = new SchemaTool($em);
$metadata = $em->getMetaDataFactory()->getAllMetadata();
// Drop and recreate tables for all entities
$schemaTool->dropSchema($metadata);
$schemaTool->createSchema($metadata);
$loader = new Loader();
$user = new LoadUserData();
$user->setContainer($container);
$loader->addFixture($user);
$purger = new ORMPurger();
$executor = new ORMExecutor($em, $purger);
$executor->execute($loader->getFixtures());
$session = $container->get('session');
$userManager = $container->get('fos_user.user_manager');
$user = $userManager->findUserBy(array('username' => 'test'));
$firewall = 'default';
$token = new UsernamePasswordToken($user, $user->getPassword(), $firewall, $user->getRoles());
self::$kernel->getContainer()->get('security.token_storage')->setToken($token);
$session->set('_security_'.$firewall, serialize($token));
$session->save();
$cookie = new Cookie($session->getName(), $session->getId());
$this->client->getCookieJar()->set($cookie);
}
public function testProfile()
{
//$this->createAuthorizedClient();
$token = $this->client->getContainer()->get('security.token_storage')->getToken();
$this->client->request('GET', '/profile/');
$this->assertEquals(
200,
$this->client->getResponse()->getStatusCode(),
"/profile isn't accessible"
);
}
}
Whenever I set a break point before the route gets executed, the token is return correctly:
Whenever I get to the function getUser() used by the Controller (http://api.symfony.com/2.7/Symfony/Bundle/FrameworkBundle/Controller/Controller.html#method_getUser) PHPStorm returns an empty token as viewed here:
So I decided to try the following code to log a user in, and it works.
$crawler = $this->client->request('GET', '/login');
$form = $crawler->selectButton('_submit')->form(array(
'_username' => 'test',
'_password' => 'test123',
));
$this->client->submit($form);
$this->client->followRedirect();
Am I not doing something properly whenever I log the user in programmatically? Is the session not being set properly?
Thanks!
Rat
I use this:
protected function createAuthorizedClient()
{
$client = static::createClient();
$container = $client->getContainer();
$session = $container->get('session');
$userManager = $container->get('fos_user.user_manager');
$loginManager = $container->get('fos_user.security.login_manager');
$firewallName = $container->getParameter('fos_user.firewall_name');
$user = $userManager->findUserBy(array('username' => 'USERNAME'));
$loginManager->loginUser($firewallName, $user);
// save the login token into the session and put it in a cookie
$container->get('session')->set('_security_' . $firewallName,
serialize($container->get('security.context')->getToken()));
$container->get('session')->save();
$client->getCookieJar()->set(new Cookie($session->getName(), $session->getId()));
$this->client = $client;
}
and then in your test:
public function testMiInfo()
{
$this->createAuthorizedClient();
//else..
}

getLogoutUrl is not working with facebook graphp api using php codeigniter

My facebook php sdk getLogoutUrl is not working when i click on my logout url.
it takes me back to my given redirect url but it does not destroy my facebook session i can still see my var_dump($fb_data) array on my page and logout url.
Here is my code i am using codeigniter
My lib_login library function facebook code
public function facebook()
{
$facebook_default_scope = explode(',', $this->ci->config->item("facebook_default_scope"));
$facebook_app_id = $this->ci->config->item("facebook_app_id");
$facebook_api_secret = $this->ci->config->item("facebook_api_secret");
// init app with app id and secret
FacebookSession::setDefaultApplication($facebook_app_id, $facebook_api_secret);
// login helper with redirect_uri
$helper = new FacebookRedirectLoginHelper(site_url('login/facebook'));
// 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;
}
}
if (!isset($session) || $session === null) {
// no session exists
try {
$session = $helper->getSessionFromRedirect();
} catch(FacebookRequestException $ex) {
// When Facebook returns an error
// handle this better in production code
print_r($ex);
} catch(Exception $ex) {
// When validation fails or other local issues
// handle this better in production code
print_r($ex);
}
}
// 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
$request = new FacebookRequest($session, 'GET', '/me?fields=id,name,accounts{access_token,category,name,id,perms},permissions');
$response = $request->execute();
// get response
$graphObject = $response->getGraphObject()->asArray();
$logoutUrl = site_url('login');
$fb_data = array(
'me' => $graphObject,
'loginUrl' => $helper->getLoginUrl($facebook_default_scope),
'logoutUrl' => $helper->getLogoutUrl($session,$logoutUrl),
);
$this->ci->session->set_userdata('fb_data', $fb_data);
} else {
$fb_data = array(
'me' => null,
'loginUrl' => $helper->getLoginUrl($facebook_default_scope),
'logoutUrl' => $helper->getLogoutUrl($session,$logoutUrl),
);
$this->ci->session->set_userdata('fb_data', $fb_data);
}
return $fb_data;
}
Here is my function of my controller
public function facebook()
{
$fb_data = $this->lib_login->facebook();
if (isset($fb_data['me'])) {
echo "<pre>";
var_dump($fb_data);
echo "</pre>";
echo 'logout';
} else {
echo 'Login';
}
}
When ever i login to my account using this code then the logout url and $fb_data array appears on my page but when i logout and refresh my page it is still their.Can some one tell what i am doing wrong here.
Try something like this:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Login extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->library(array('session', 'lib_login'));
$this->fb_data = $this->lib_login->facebook();
}
/**
* facebook login
*
* #return void
* #author appleboy
**/
public function facebook()
{
// check login data
if (isset($this->fb_data['me'])) {
var_dump($this->fb_data);
} else {
echo 'Login';
}
}
public function logout()
{
if ( isset($this->fb_data['me']) ) {
$this->session->unset_userdata('fb_data');
}
redirect('login/facebook', 'refresh');
}
}
/* End of file login.php */
/* Location: ./application/controllers/login.php */

I found No way to build facebook integration with my website

I tried in many ways.. i used php-sdk and in many other ways... but i am not able to connect my website with facebook... actually.. i am doing my project in codeigniter. Can anybody plz suggest me to connect to facebook login and share using codeigniter.
<?php
include "libs/facebook.php";
$facebook = new Facebook(array(
'appId' => '376406812408828',
'sec`enter code here`ret' => 'ca1eb65bde82a4009c31b4a5adb047b5',
'cookie' => true
));
print_r($facebook);
$session = $facebook->getUser();
echo $session;
$me=null;
if($session)
{
try
{
$me = $facebook->api('/me');
echo $me;
$facebook->api('/me/feed','post',array('message' => 'Hello World!'));
}
catch(FacebookApiException $e)
{
echo $e->getMessage();
}
}
if($me)
{
$logoutUrl = $facebook ->getLogoutUrl();
echo "Logout";
}
else
{
$loginUrl = $facebook ->getLoginUrl(array(
'req_perms' => 'publish_stream,read_friendlists'
));
echo "Login";
}
?>
Danny Tran has provided A Simple & Easy Facebook Library for CodeIgniter.
CI_Facebook is a Facebook Library for CodeIgniter.
Simply copy/merge all the files into the corresponding locations and
setup config/facebook.php.
There are unit tests written for each function/class. You will need
PHPUnit to execute them.
Accessing the Facebook object is easy since the hook is auto-loading
it.
e.g. $user_data = $this->facebook->fb->api_client->fql_query("select name from user where uid = TARGETUSERID");
Link to library on Github: https://github.com/dannybtran/CI_Facebook
Hope this helps.
A couple of weeks I had to do the same, and after and I came up with this. I needed it for an ajax login, but it mostly suits everyone needs.
This is the first step, it prompts the facebook login (if you are not already logged) and then redirect to your previously set uri.
$this->load->library('facebook_handler');
$this->facebook_handler->loginBegin($this->config->item('endpointfacebook'));
Facebook_handler in libraries folder
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class Facebook_handler extends ML_index
{
var $scope = "email, user_about_me, user_birthday, user_hometown, user_website,read_stream, publish_stream, read_friendlists";
function __construct()
{ parent::__construct();
$this->CI =& get_instance();
$this->CI->config->load('mlogin_config'); //Config where I have the keys
if ( ! $this->CI->config->item('facebook_api_key') || ! $this->CI->config->item('facebook_api_key_secret') )
{
throw new Exception( "Your application id and secret are required in order to connect to {$this->providerId}.", 4 );
}
include_once(APPPATH.'libraries/Facebook/base_facebook.php'); //Place where I've situated the facebook libraries
include_once(APPPATH.'libraries/Facebook/facebook.php');
$this->fb = new Facebook( ARRAY( 'appId' => $this->CI->config->item('facebook_api_key'),'cookie'=>true, 'secret' => $this->CI->config->item('facebook_api_key_secret') ) );
$this->user = $this->fb->getUser();
}
/*The login process starts here, endpoint is the redirect_url for facebook*/
function loginBegin($endpoint)
{
$scope=$this->CI->config->item('facebook_scope');
if( isset( $scope ) && ! empty( $scope ) )
{
$this->scope = $scope;
}
$this->logout();
$url = $this->fb->getLoginUrl( array( 'domain'=>base_url(),'scope' => $this->scope, 'redirect_uri' => $endpoint,'display' => 'popup' ) );
redirect($url);
}
/*Function to get user data*/
function getUser(){
if ($this->user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $this->fb->api('/me');
return $user_profile;
} catch (FacebookApiException $e) {
error_log($e);
return false;
}
}else{
$this->output->set_output('no logueado');
}
}
/*Facebook logout, it destroys facebook sessions. I dont really use this*/
function logout(){
$this->fb->destroySession();
}
}
?>
The function to redirect to
function closewindowfacebook(){
$this->load->library('facebook_handler');
$userprofile=$this->facebook_handler->getUser();
if ($userprofile!=false){
$fb_uid = $this->facebook_handler->fb->getUser();
$fb_email=$userprofile['email'];
$fb_name=$userprofile['name'];
/*My function to connect to the website, that you'd do it yourself*/
//$this->auth->try_fb_login($fb_uid,$fb_email,$fb_name);
/*I use this to close the popup window*/
die('<script type="text/javascript">
window.opener.everythingready();
window.close();
</script>');
} else{
echo 'error ';
}
}
Ask if you have any further question

class gets unset when including smarty and facebook php

I don't understand this:
I use the __autoload feature in php and this works:
include_once '../sys/core/init.inc.php';
$Intro = new Intro();
echo $Intro->ip();
exit();
init.inc.php loads the Intro class and the ip() function prints out the ip.
But this does not work
include_once '../sys/core/init.inc.php';
/*
* Smarty template engine
*/
include_once '../sys/core/smarty/Smarty.class.php';
$smarty = new Smarty;
$smarty->debugging = false;
$smarty->caching = false;
$smarty->cache_lifetime = 86400; // 24 timer
/*
* gettext translation
*/
if( ! defined('PROJECT_DIR')){ define('PROJECT_DIR', realpath('/var/www/v3/')); }
if( ! defined('LOCALE_DIR')){ define('LOCALE_DIR', PROJECT_DIR .'/sys/locale'); }
if( ! defined('DEFAULT_LOCALE')){ define('DEFAULT_LOCALE', 'no_NO'); }
include_once('../sys/core/gettext/gettext.inc');
$encoding = 'utf-8';
$locale = (isset($_COOKIE['lang']))? $_COOKIE['lang'] : DEFAULT_LOCALE;
T_setlocale(LC_MESSAGES, $locale);
$domain = 'messages';
T_bindtextdomain($domain, LOCALE_DIR);
T_bind_textdomain_codeset($domain, $encoding);
T_textdomain($domain);
/*
* facebook
*/
include_once '../sys/core/facebook/facebook.php';
// Create our Application instance (replace this with your appId and secret).
// Create our Application instance.
$facebook = new Facebook(array(
'appId' => 'xxx',
'secret' => 'xxx',
'cookie' => true,
));
$session = $facebook->getSession();
$me = null;
// Session based API call.
if ($session) {
try {
$uid = $facebook->getUser();
$me = $facebook->api('/me'); // me?fields=email
$email = $facebook->api('me?fields=email');
} catch (FacebookApiException $e) {
error_log($e);
}
}
// login or logout url will be needed depending on current user state.
if ($me) {
$logoutUrl = $facebook->getLogoutUrl();
} else {
$loginUrl = $facebook->getLoginUrl(
array('req_perms' => 'email, publish_stream')
);
}
$Intro = new Intro();
echo $Intro->ip();
exit();
Now I get Fatal error: Class 'Intro' not found in ... on line 92
I don't understand this because the only code I have added is required includes for facebook, gettext and smarty. Before the includes I can call classes, but not after I have added the includes. This makes no sense to be. Can someone explain.
Try to call your class directly after the include:
include_once '../sys/core/init.inc.php';
$Intro = new Intro();
/*
* Smarty template engine
*/
include_once '../sys/core/smarty/Smarty.class.php';
$smarty = new Smarty;
$smarty->debugging = false;
$smarty->caching = false;
$smarty->cache_lifetime = 86400; // 24 timer
/*
* gettext translation
*/
if( ! defined('PROJECT_DIR')){ define('PROJECT_DIR', realpath('/var/www/v3/')); }
if( ! defined('LOCALE_DIR')){ define('LOCALE_DIR', PROJECT_DIR .'/sys/locale'); }
if( ! defined('DEFAULT_LOCALE')){ define('DEFAULT_LOCALE', 'no_NO'); }
include_once('../sys/core/gettext/gettext.inc');
$encoding = 'utf-8';
$locale = (isset($_COOKIE['lang']))? $_COOKIE['lang'] : DEFAULT_LOCALE;
T_setlocale(LC_MESSAGES, $locale);
$domain = 'messages';
T_bindtextdomain($domain, LOCALE_DIR);
T_bind_textdomain_codeset($domain, $encoding);
T_textdomain($domain);
/*
* facebook
*/
include_once '../sys/core/facebook/facebook.php';
// Create our Application instance (replace this with your appId and secret).
// Create our Application instance.
$facebook = new Facebook(array(
'appId' => 'xxx',
'secret' => 'xxx',
'cookie' => true,
));
$session = $facebook->getSession();
$me = null;
// Session based API call.
if ($session) {
try {
$uid = $facebook->getUser();
$me = $facebook->api('/me'); // me?fields=email
$email = $facebook->api('me?fields=email');
} catch (FacebookApiException $e) {
error_log($e);
}
}
// login or logout url will be needed depending on current user state.
if ($me) {
$logoutUrl = $facebook->getLogoutUrl();
} else {
$loginUrl = $facebook->getLoginUrl(
array('req_perms' => 'email, publish_stream')
);
}
echo $Intro->ip();
exit();
Shouldn't work either, but may be a good start for debugging. However, it might be useful to post your Intro class.
This is a simple guess, i haven't really used these librairies (except for Smarty) in a while, but it might be that one of the libraries (Facebook or Gettext) also define a __autoload function that gets called instead of your own.
You can display what is used by PHP for autoloading by calling var_dump(spl_autoload_functions()).
Also, your autoload function might be using a constant or variable getting overwritten by the includes.

Categories