I am working on a symfony project which is made of 2 applications (frontend & backend) and I have been asked to manually create a second session in the backend so that the administrator could access user data (the frontend) from the backend without logging in.
I've set different names in factory.yml so that each application has its own cookie.
Basicalyy, I need to retrieve a user from the backend, manually create the frontend cookie without destroying the backend session then redirect to the frontend.
I've tried the following code but this doesn't work :
$user = $this->getUser()->getAttribute('some_attribute');
$session = new sfSessionStorage();
$option = array(
'session_name' => 'frontend_session_name'
);
$session->initialize($options);
// some code to push the user in the new cookie
$this->redirect('https://frontend.php');
I haven't been using symfony for long and must admit that I'm a bit lost here. I know I need to populate the new cookie with the user data but I can't figure out how.
Any help will be very much appreciated.
edit: I forgot to mention that I'm using propel.
edit #2: I've come up with the following solution which does what intended :
$user = $this->getUser()->getAttribute('some_attribute'); //retrieving the user whose data I'd like to access
$currentSessionId = session_id();
session_write_close();
session_name('frontend_session_name');
session_start();
session_regenerate_id();
$_SESSION['symfony/user/sfUser/culture'] = 'en';
$_SESSION['symfony/user/sfUser/lastRequest'] = time();
$_SESSION['symfony/user/sfUser/authenticated'] = 1;
$_SESSION['symfony/user/sfUser/credentials'] = array('frontend_user');
$_SESSION['symfony/user/sfUser/attributes'] = array(
'symfony/user/sfUser/attributes' => array(
'user' => $user
)
);
session_write_close();
session_name('backend_session_name');
session_id($currentSessionId);
session_start();
$this->redirect('/frontend.php');
So I just manually recreated the session and pushed in the necessary data.
Thanks to those who tried to help.
As sharing a session doesn't seem to be an option for you, I'd suggest:
creating a unique key for each user, not the id, but a separate string that is hard to guess
create a module / action on the frontend that accepts the key as a parameter, finds the corresponding user in the database, and logs them in
You could then generate the required links in the backend that an admin can click and be redirected to.
Not very secure, make sure your keys are long. You'd need to add code to prevent brute forcing, and limit access to the action by IP address maybe?
You could also require the key of the admin user, and check that it is valid too, which would make it harder to guess.
Related
I have built a SSO (Single Sign-On) system for use between our main site and the Invision Power Board software but I'm not sure how to go about logging the user out of IPB when they log out from the main site?
Additionally, what files would I need to load in the external file to be able to do this?
Edit: to use IPB code for this, you have to include
require_once( IPS_ROOT_PATH . 'applications/core/modules_public/global/login.php' );
then to extend public_core_global_login and to call it's doLogout() method
for this to work you have to set $this->member->setMember( $member_id );
I, personally, have never done it this way, so bellow is how you can do it manually:
IPB sets the data in session and stores several cookies for auto-login. You can perform without using any IPB sources; what you have to do is (note query and updatecookie are some pseudofunctions, for performing DB queries and setting cookie values respectively):
query("DELETE FROM ".$ibf_prefix."sessions WHERE member_id = $userid");
updatecookie($ibf_cookieid."member_id",0,time()-1800);
updatecookie($ibf_cookieid."pass_hash",0,time()-1800);
updatecookie($ibf_cookieid."session_id",0,time()-1800);
You can read $ibf_prefix from conf_global.php :
$ibf_prefix = $INFO[sql_tbl_prefix];
and $ibf_cookieid is:
$ibf_cache = query_first("SELECT cs_value FROM " . $ibf_prefix . "cache_store WHERE cs_key = 'settings'");
$ibf_cache = unserialize($ibf_cache['cs_value']);
$ibf_cookieid = $ibf_cache['cookie_id'];
You can read the source of doLogout method in admin/applications/core/modules_public/global/login.php
I'm not aware of any IPB API for this.
You can try to destroy the session with session_destroy();
If the user has "Remember me" checked, you have to delete the cookie pass_hash too.
I read many question and post about my question but all were not helpful.
I develop website, and in login page i use session.
As i know session is end when browser close,, but my session is not end on browser close..
I want to access my web with out login
here is code that create session
$_SESSION['session_name'] = 'session value';
$_SESSION['is_admin'] = '1';
$general->redirect('home.php');
by this code session is created and i access website definitely,
i try to add session manually , and set these session name in manually session, and then i want to access website,..
you Not give me full detail, but please give me initialize suggestion and helpful source where i read about this.
Thank you.
Simply create a separate page on your website’s root (preferably protected by a HTACCESS password). Call it something like *hack_login.php* (or something more cryptic).
<?php
session_start();
$_SESSION['session_name'] = 'session value';
$_SESSION['is_admin'] = '1';
?>
Now when you access that page, and provided your session cookie is written correctly, you should be authorized when you access your website through the front page.
Don't forget to remove that page once your tests are done ;)
I am trying to login to a CakePHP app through session with credentials created from external custom PHP code. But I am unable to figure out how to do this exactly. I don't want to do it with form.
For example:
I am logged in at site A and my CakePHP app is site B (both hosted on same server, but in different folders).
I have retrieved the username/password set from site A into B.
But I don't know that now how to use this in site B.
Any thought on the same ?
Thanks.
Note:
Well I am receiving the username in CakePHP session
i.e $this->Session->read('Username');
Now want to login through Auth
e.g $this->Auth->login($this->Session->read('Username'));
So that I can then get user through $this->Auth->user();
Can you help me in that?
I am doing this in AppController, method: beforeFilter() , _checksession()
If you already have the username and password sent from site A, couldn't you just verify the credentials against the database again? Or create a table that stores sessions and link them to the usernames and just pass that session variable through the PHP $_SESSION variable
SITE A:
session_start();
$this->Session->write('session','ABCDEFGHIJKL12345' ); // random generated string
// store in DB
and then when you get to site B:
SITE B:
session_start();
// if $this->Session->read('session') == '' force login again
//else
//compare the session in the db and check for valid session
//if valid
//load page.
If you already have the username/password in the session as you say, try building a User model data array which Auth will then try to automatically verify for you:
// Construct model data array like what AuthComponent would usually expect
$userData = array(
'User' => array(
'username' => $this->Session->read('username'), // Use your stored values (change as appropriate)
'password' => $this->Session->read('password')
)
);
// Attempt to authenticate the user
if ($this->Auth->login($userData)) {
// Login worked
} else {
// Login failed
}
Thanks All,
I got a solution that rather then sending the password, i only send username and after proper validation i try to login as:
$username = $this->Session->read('userName');
//validation
$user = $this->User->find('first',array('conditions'=>array('username'=>"$username")));
$this->Session->write('Auth',$user);
//now I can use:
$this->Auth->login()
Previously I was saving session at wrong index.
I'm wondering if there's a way to dump all of the values of
$this->session->userdata()
so I can troubleshoot?
I'm working within Facebook, and have a login page, and once that's successful I want to pass around the UID of the current user, and I thought this would work well.
I currently have the uid set as follows:
require_once 'facebook.php';
$appapikey = 'XXXX';
$appsecret = 'XXXX';
$facebook = new Facebook($appapikey, $appsecret);
$user_id = $facebook->require_login();
$this->db->like('uid', $user_id);
$this->db->from('users');
$has_signed_up = $this->db->count_all_results();
if ($has_signed_up == 0) {
redirect('/setup/signup/', 'location');
}
else {
$this->session->set_userdata('uid', $user_id);
redirect('/preferences/index/', 'location');
}
So the redirection occurs, and I have a very simple setup over at preferences/index:
echo "this is the preferences form <br />";
echo $this->session->userdata('uid');
echo $this->session->userdata('session_id');
And the result is an inscrutable:
this is the preferences form
858f500e167e359edc1942a96f3bac35
So it totally skips over the middle echo containing the uid. Am I not setting this correctly? Is there a way to dump all values of the session array to see what's getting through? Any help would be just great.
UPDATE
I have run var_dump($this->session->userdata) on each the raw website and through Facebook.
On the website it exposes all set values in an array containing 5 values (session_id, IP, User_agent, last_activity, and uid).
Within the Facebook chrome however, it only shows the 4 values set by CodeIgniter. I've heard cookies can only be 4k and that encryption could be a problem. Could FB be filling up cookies with its own encrypted (read:larger) data?
UPDATE 2
When I comment out the redirect, and just have:
else {
$this->session->set_userdata('uid', $user_id);
echo ':test_'.$this->session->userdata('uid').'_test:';
//redirect('/preferences/index/', 'location');
}
It dutifully returns :test_1234_test: within Facebook. So somewhere during the redirect it's losing this part of the array (but not the whole array).
Is it possibly just creating a new session on the redirect page? So that's why it only has the four "stock" variables? If this is the case, I'll need to research how it creates the sessions, and if Facebook clears cookies I suppose.
UPDATE 3
So I've turned to using a DB to store session information instead of cookies, thinking FB was either stripping them or colliding with them. I currently have the app set up to
Set $user_id = 1234
$this->session->set_userdata('uid', $user_id)
Redirect to the new page
Var_dump all possible information
What occurs in the DB is this:
DB records http://nikolausjj.facebook.joyent.us/Picture2.png
So it creates one good record, with the user data, then immediately upon the redirect creates a new session without recognizing the prior one. Can someone explain where the CI framework checks to see if it has a prior session existing? The user manual explains it as "magic" basically.
You can use var_dump() to output the session. Something like this
var_dump($this->session);
The set_userdata call looks ok. Are you sure $user_id is set. Because the echo is surley executed but uid isn't set or set to empty string.
Try replacing the echo with
echo ':test_'.$this->session->userdata('uid').'_test:';
Other information helpful for answering
What browser are you using?
Do you have an underscore _ in your domain name?
Are you using CI sessions or some wrapper for native PHPsessions
Is the value for uid also lost/not set when you comment out the redirect?
Other suggestions:
try redirect('/preferences/index/', 'refresh'); instead of location
I'm not familiar with facebook development but is /preferences/index under your control? If yes try removing (if present) $this->load->library(‘session’) and instead load it in autoload.php.
try changing $config[‘sess_match_ip’] to `FALSE
try setting $config[‘sess_encrypt_cookie’] to FALSE
try replacing the use of CI-Session with CI Native session
Is UID sensible information if not store it in a cookie. If it matters if it can be spoofed don't.
I didn't solve how to pass session variables from one page to another via Facebook. My solution was simply to call the Facebook API for the user's UID again on each page. Not great programming, but it works alright for me. :-/
I am fairly new to PHP. What is the best way to control access to a class throughout a PHP application and where is the best place to store these classes that will need to be accessed throughout the entire application? Example; I have a user class that is created on during the login process, but each time the page post it appears that the object is reinitialized.
I have tried to set property IsLoggedIn and then check that variable each time before creating the object as new again, but this doesn't seem work. I have also tried to use the isSet function in PHP to see if the class variable already exists
You're right, the state of your application is not carried over from request to request.
Contrarily to desktop applications, web applications won't stay initialized because to the server, every time it can be a another visitor, wanting something completely different. You know who's using the desktop application, but you don't necessarily know who's requesting the page. Imagine 10 users doing different thing simultaneously on your web application? You wouldn't keep the whole application running necessarily for each of those visitors. Imagine with 10,000 visitors...
There are ways to keep some data from request to request though. The application will be reinitialized each time, yes, but you can then reload the state of what you were doing. It always revolve around around the same general methods:
Cookies; Cookies are a small file that is kept on the client side and which content will be available on each request to you. In PHP, this is available using $_COOKIE variable. In all cases, you could serialize your classes instances and reload them afterwards. The problem is, you wouldn't want to put sensitive data there as any(malicious)body can see and modify it.
POST or GET; In each request, you pass a state in the $_GET request (the URL such as http://localhost/myscript.php?iamatstep=4. Or via a $_POST such as using a hidden input field in a form. This data could be encrypted and make sense only to you, but still, you are putting sensitive data back to the client and anybody could fiddle with it.
Database, Disk; Or anything else on the server. Again, you serialize your data in a file for example at the end of a request ready to be used again for the next request. The main advantage is that it stays on your server. The downside is that at this point, you don't know which data to extract back for which request as there might be multiple users on your application at the same time...
And this is where the notion of $_SESSION comes into play. It's just a packaged way of using all of this at the same time. It's not magical as often it's perceived by beginners. When you use a session, the data put into the $_SESSION is stored somewhere on the server (normally a file in a temporary directory although it can be changed to something else like a database) and a unique ID is attributed to this session and passed in a cookie that will follow the visitor from request to request. So the only thing on the client's side is a big number in the cookie. On the next request, the browser tells PHP on the server that it's session number 12345, loads the corresponding file if it exists and then the data is available to you again. If cookies are not enabled, it could be passed in a GET or POST, although it's often better not to go there (see session.use_trans_sid's note).
It often looks like that on each of your pages you need authentication.
<?php
// verify if we have a current session
if (isset($_SESSION['login'])) {
// get data in current session
$username = $_SESSION['login']['username'];
$isLoggedIn = $_SESSION['login']['isLoggedIn'];
} else {
$username = '';
$isLoggedIn = false;
}
// take care of the unauthorized users
if (!$isLoggedIn) {
// maybe a redirection here...
}
// do the things a logged in users has the permission to do
And to set the session, it'll probably look like that:
<?php
// handle the form post of your login page for example
if (isset($_POST['username']) && isset($_POST['password'])) {
$username = $_POST['username'];
$password = $_POST['password'];
// verify the username and password against a database
if ($everythingIsOkay) {
// we can consider this user logged in and create a session
$_SESSION['login']['username'] = $username;
$_SESSION['login']['isLoggedIn'] = true;
// and now maybe redirect the user to the correct page
}
}
// raise an error about an invalid login
And finally, maybe a logout.php page that would do something like that:
<?php
unset($_SESSION['login']);
// redirect the user to the login page
This kind of data is going to have to be stored in a session, the only thing that is carried from page to page is Session data (sessions/cookies/...) so your class initialization is not carried over.
You can add information like the users username to the session with:
$username //username from db
$name //name from db
$_SESSION['username'] = $username;
$_SESSION['name'] = $name;
or if you just want to have easy access to all the information about the user you can do:
$_SESSION['user'] = mysql_fetch_assoc($result); //where $result is the response from the db to your login query
after you do this $_SESSION['user'] will be an array with all the details you selected from the database.