I'm having application in codeigniter already, now i'm developing the android from this application. Using this application as a server side and doing client console in android. In server i'm maintained the session. But in android request i can't maintain the session. Instead of that i'm creating GUID in server at the first request of login request and storing at client side and also storing at customer table, afterwards for each request client will send the GUID for authentication.
Now what is my problem is each request getting from android codeigniter create session with different session id(each request generating new session id). How to avoid creating session and storing into database.(Only for android request, but browser request it have to store)
I managed to extend CI_Session in Codeigniter 3.1.3.
Here is what I did:
Create a file application/libraries/Session/MY_Session.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class MY_Session extends CI_Session {
public function __construct(array $params = array())
{
if ( $this->ignore_sessions() )
return;
parent::__construct();
}
function ignore_sessions()
{
$uri = str_replace ("//", "/", $_SERVER['REQUEST_URI']);
if ( strpos($uri, '/ignore_this_controller/') === 0 )
return true;
return false;
}
}
You might also want to add 'session' to your config/autoload.php:
$autoload['libraries'] = array('session',....)
Your question is rather old now, but for anyone who has this problem you should extend the CI_Session library and override the sess_create method. Within your method, test to see what user agent is making the request.
Then you only allow a session to be created if the user agent is NOT an android platform.
public function sess_create
{
//load user agent library
$this->CI->load->library('user_agent');
/**test request to see if its from android
* you can update the user_agents collection to suit more specific needs
*/
if($this->agent->platform() !== 'android'):
//create session for all non-android platforms
parent::sess_create();
endif;
}
Related
I am working on an application built on CodeIgniter. This application extends its controllers using a custom controller CP_Controller which lives in application/core. It looks like this:
class CP_Controller extends CI_Controller {
var $settings;
var $body_classes = array();
var $data = array('theme' => 'cmodule');
public function __construct() {
parent::__construct();
// print_r($_SESSION);
}
...
}
The problem is, print_r($_SESSION);. If I uncomment it, it prints [__ci_last_regenerate] => 1589186369. That's fine. No custom session data.
But for a particular request only, this returns a whole array filled up with session stuff. Even if it is the only request I run in a brand new browser session or private mode.
In this scenario, what's stranger is that business logic has not yet reached execution and no sessions have been set before this point. Then how's it possible that at this point, in a blank browser session, I am getting session data. I am not able to figure out the origin of this session data, where is it being set into the session? It only calls parent::__construct(); before print_r.
Is there really any way a Codeigniter application can hook into session and populate a session at a very initial system bootstrap level (for that particular request only)? Or there could be any other way?
Thanks.
When I perform HTTP tests in Laravel 5 using built-in tools, the framework remembers the session data from request to request.
class HttpTest extends TestCase
{
public function testApplication()
{
// Suppose this endpoint creates a session and adds some data to it
$this->get('/action/fillSession');
// Suppose this endpoint reads the session data
$this->get('/action/readSession'); // The session data from the first request is available here
}
}
How to perform a request with another session between the requests above without destroying the original first session?
Remember the first session data, flush the application session, make the "another session" request and return the original session data back to the application:
class HttpTest extends TestCase
{
public function testApplication()
{
// Suppose this endpoint creates a session and adds some data to it
$this->get('/action/fillSession');
$session = $this->app['session']->all();
$this->flushSession();
$this->get('/noSessionHere');
$this->flushSession();
$this->session($session);
// Suppose this endpoint reads the session data
$this->get('/action/readSession'); // The session data from the first request is available here
}
}
You can carry out this algorithm to a separate method to reuse it easily:
class HttpTest extends TestCase
{
public function testApplication()
{
// Suppose this endpoint creates a session and adds some data to it
$this->get('/action/fillSession');
$this->asAnotherSession(function () {
$this->get('/noSessionHere');
});
// Suppose this endpoint reads the session data
$this->get('/action/readSession'); // The session data from the first request is available here
}
protected function asAnotherSession(callable $action)
{
$session = $this->app['session']->all();
$this->flushSession();
$action();
$this->flushSession();
$this->session($session);
}
}
In order to implement cross application authentication (getting logged in in my Symfony2 app if the user already logged in in an other application), I made a Symfony2 listener class that checks if specific data concerning the user is in the session. This data comes from a non-Symfony2 (but PHP) app.
The problem is that the session data from the other app is not present in the session object I use in my class.
Here is the listener (simplified) class:
<?php
class OldAppAuthenticationListener
{
/** #var \Symfony\Component\Security\Core\SecurityContext */
private $context;
public function __construct(SecurityContext $context)
{
$this->context = $context;
}
public function onKernelRequest(GetResponseEvent $event)
{
if (HttpKernel::MASTER_REQUEST != $event->getRequestType()) {
// don't do anything if it's not the master request
return;
}
if (!$this->context->isGranted('IS_AUTHENTICATED_FULLY')) {
$request = $event->getRequest();
$session = $request->getSession();
$userName = $session->get('nomUtilisateur');
$token = new PreAuthenticatedToken($userName, null, 'secured_area', array('ROLE_USER'));
$session->set('_security_secured_area', serialize($token));
}
}
}
It is registered in services.yml like this:
services:
my_app.listener.old_app_authentication:
class: Acme\MyAppBundle\Listener\MyAppAuthenticationListener
arguments: ["#security.context"]
tags:
- { name: kernel.event_listener, event: kernel.request }
But the $session->get('nomUtilisateur') always returns NULL (and $session->all() and $_SESSION only return some Symfony2 specific vars) although the other app stores all this data in the session.
Of course, I use the same cookie session domain for both apps (as configured in config.yml) and I can easily check that the PHPSESSID is the same.
So here is my question: why are the old app session variables not available and how can I get them from my listener class?
As stated here, Symfony2 uses session bags to store session stuff. This means that you have to directly access the $_SESSION superglobal for such a functionality.
For me the solution was to use directly the php session fonctions.
also I had to check if session name, domain and save path are the same on both applications.
In my symfony I had to add:
session_save_path('c:/wamp/tmp');
session_name(_SESSION_ID_);
session_start();
and then use $_SESSION
an other way that was given to me, but I didn't use is to use the sessions files directly like this:
"The trick was using the session cookie sent by the browser.
For example, an old web application, written in PHP, sent a cookie
called IntranetSession to the browser. As I knew where does PHP store
the session files, I simply opened that file, and decoded its contents
with session_decode(). The drawbacks of this is that session_decode()
puts its output directly into $_SESSION, overwriting you current
session data (even the stuff put there by Symfony). Basically the rule
is as follows:
$sessionData = file_get_contents($sessionFile);<br>
$tmpSess = $_SESSION;<br>
session_decode($sessionData);<br>
$otherAppSession = $_SESSION;<br>
$_SESSION = $tmpSess;<br>
"
hope this helps!
I suppose I'm just looking for a bit of guidance as to how to set up my User + Authentication area on my website with cakephp 2.0.
I have a basic login and register functionality set up within my UserController.php, which also contains functions for looking up and displaying other users.
I also want to use the hybridauth plugin to allow for users to login/register using their social media / oauth account (allowing for more than one social account per user in the database, so that the same user could use either their twitter or facebook details, for example). I'm only having 3 providers at this time, so I plan to just create 6 columns in my user database, with the token and outhid in the same user row. This is in another controller - HybridauthController.php.
I have the hybridauth set up so that it creates its 'hybridauth' object from the account details, which is fine - but I want to be able to merge the whole 'authentication' together, so that my cakephp session contains the hybridauth session data (object) creating my general "current user" array that I can use, and set some generic variables within, depending on whether they are from oauth or not.
I don't currently store sessions in a database, and ideally I would like for allow persistent sessions for all, whether they use an oauth account or not. I don't really understand how persistent sessions are supposed to work with hybridauth, because how in this example would the $current_user_id be filled in when the user returns the next day? Not via a cookie, surely?
http://hybridauth.sourceforge.net/userguide/HybridAuth_Sessions.html
So in summary I'm looking for a simple solution to combine all of my 'session' / 'auth' / 'user' data into one simple array in the users session. Hopefully that all makes sense!
Thanks
Late to answer, but hopefully it'll help you or someone else searching.
I had a tough time integrating HybridAuth into a preexisting CakePHP (1.3) app that was already using Cake Sessions and the Auth component. I initially tried using the Cake example that I downloaded from the HybridAuth website, but that did not work for me.
Our preexisting User controller already had a bunch of logic in it including a beforeFilter method. That's where I inserted my session_start() as opposed to above the class declaration in the HybridAuth Cake example:
class UsersController extends AppController {
...
var $components = array('Session','Auth','Email');
...
public function beforeFilter(){
// following two lines may not be necessary for your setup
$this->Auth->allow('oauth', 'oauthLogout');
$excludeBeforeFilter = array('oauth', 'oauthLogout');
if ( ! in_array($this->action, $excludeBeforeFilter) ) {
// preexisting Auth logic -- I had to bypass it because
// calling `session_start` was messing up Cake's Auth
...
} else {
/* THIS IS NECCESSARY FOR HYBRIDAUTH (OAUTH) */
/* setting the session ID made it so users could NOT log
in from a 3rd party and our site */
session_id($_COOKIE['CAKEPHP']);
session_start();
}
}
...
public function oauth($provider){
$this->autoRender = false;
// include HybridAuth
require_once( WWW_ROOT . 'hybridauth/Hybrid/Auth.php' );
try {
// I stored my provider config in a Cake config file
// It's essentially a copy from the site/Cake example
$hybridAuth = new Hybrid_Auth(Configure::read('HAuth.config'));
$adapter = $hybridAuth->authenticate($provider);
$userProfile = $adapter->getUserProfile();
// method on the User model to find or create the 3rd party user
$user = $this->User->findOrCreate($userProfile, $provider);
if ( ! $user ) {
echo 'Unable to find/create user';
} else {
// configure your fields as necessary
$this->Auth->fields = array(...);
$this->Auth->login($user);
}
} catch (Exception $e) {
echo $e->getMessage();
}
}
}
At this point the 3rd party (HybridAuth) user is accessible in the Auth Component. This way a user was only logged in one 3rd party service or the preexisting login (but not both).
I also had an issue logging out. To do that I basically destroyed all sessions/cookies to be safe. In the oauthLogout method of the UsersController:
// probably overkill/paranoia
$this->Auth->logout();
$this->Session->destroy();
session_destroy($_COOKIE['CAKEPHP']);
/* these two seemed to make the difference
especially the 4th parameter */
setcookie( 'PHPSESSID', '', 1, '/' );
setcookie( 'CAKEPHP', '', 1, '/' );
Seems super hacky -- sorry for that. Hope it helps though!
I'm about to embark on developing a front-end that will let users login to a service and perform certain tasks. All of the tasks are being performed through a 3rd party's API using.
I'm doing this with PHP & Zend Framework.
My question: how does one persist the login credentials if every API call requires the login to be passed in the headers?
A user will be authenticated first through a /login controller and then will stay authenticated for their session.
I had simple suggestion
you can write your custom Zend_auth_adapter and I'd like to make it singleton class that can validate your login data over the API
and save the result object inside the session object
class My_Auth_adapther implements Zend_Auth_Adapter_Interface {
public static function getinstance($username , $password ){
return $this->authenticate($username , $password );
}
private function authenticate($username , $password ){
// make sure to check if the session has been already created in order to save one api request
// do your api call (login request ) her
// return false if its not valid
// or return stdobject that contain ($username , $password ) , for any post usage
}
}
and don't allow any further call to your api if that object doesn't exist (in other words == not logged in )