I just want to know if I am able to hand over session variables from Laravel to my custom code. What I mean is: I want to handle log-in through Laravel and pass it to my profile section which is not in Laravel. Most of the routes are handled by a .htaccess file. The goal is to just login with Laravel auth and save that to $_SESSION['user'] var and redirect to /profile. Somehow I don't get that. The session name is the same in both, in Laravel's session.php's cookie name and my custom code's constant. Is there any other factor I should consider ?
Okay here's the code:
namespace Services\Session;
class OldSessionAuth
{
protected $auth;
function __construct()
{
$this->auth = \Auth::user();
}
public function setSession()
{
$_SESSION['user'] = $this->auth->toArray();
$_SESSION['auth'] = 'TRUE';
return true;
}
public function destroy()
{
session_destroy();
session_unset();
}
}
So, this is sort of my Session services, which is initialized only if it passes the Auth from the controller, Now I think I don't need to do that. so I skiped it, Basic Stuffs (Auth::Check()) really. So, I'd just do this in my login method.
$old = new Services\Session\OldSessionAuth();
$old->setSession();
return Redirect::to('/');
The home page is controlled by my custom made MVC and I want to grab the session, which in this case I can't. It shows Array(). There is no session manipulation when retrieving the session.
Laravel already has a pretty good session abstraction so I don't think you needed to use session_start(), $_SESSION etc directly. Sharing an session across two applications is a bit tricky. If you are tied to using the cookie approach, then you have to make sure that the session driver in use is the cookie one. You would also need to ensure that the restrictions on the cookie aren't such that your other application isn't being sent them by the user's browser.
By default, PHP will use a file cookie driver. In this case, what you would have to do in your other application is to read the "PHPSESSID" cookie, set the session ID using session_id() to this and only then would you have access to the session data using the $_SESSION variable in the other application.
This is all pretty hacky though. I would recommend that if you need to share sessions that you make use of a database session driver instead. This way, you are able to share arbitrary session data across applications using a standard interface. In this case, you would just read the "laravel_session" cookie instead to be able to look up the session in the database. There would be many hidden pitfalls if you then wanted to also modify this data from the other application as well though.
Related
I am building a new Laravel application (v5.4) that will run alongside (installed in the same environment) an existing PHP application that has it's own authentication system. I want the users who have successfully logged in to the existing system to be automatically authenticated in the Laravel app so they can navigate seamlessly between the applications.
My Laravel app has read-only access (through a second db connection) to the existing system's database so it can safely check that the PHP Session matches the session cookie recorded in the database and I can even pull out the user object and hand it to Auth's login() method.
I want to know the best way to put Auth into an authorised state (not guest) and where is the best place to put such code?
Options I've thunked of so far:
Middleware: Check session and call the login() method on Auth from some application-wide middleware?
Extend Illuminate/Auth/SessionGuard.php and override the attempt() method? If so, how do I tell the other parts to use my extended SessionGuard? (I suspect this was not designed to be easily overridden)
Super hacky disgusting way of dynamically setting the user's password to a random hash and then calling Auth/LoginController#login() in the background with a faked request containing that hash as the password field. (I seriously hope this doesn't end up being the most popular answer)
Some other option (?)...
Thanks in advance for your help SO community!
The solution I ran with in the end was creating a middleware that contains this:
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
if (isSet($_SESSION['intranet_user_id']) && $_SESSION['intranet_user_id']) {
// Log them in manually
$intranet_user_id = $_SESSION['intranet_user_id'];
if (!Auth::guest() && Auth::user()->getId() !== $intranet_user_id ) {
Auth::logout();
}
if (Auth::guest()) {
Auth::login( User::find($intranet_user_id), true);
}
} else {
Auth::logout();
}
I am building an API in CakePHP. I have a function that as part of its execution first destroys the cookies associated with the session. I am using the following code to do this.
public function new_thing () {
// I first call another controller to use functions from that controller
App::import('Controller', 'Person');
$PersonsController = new PersonsController;
// This function call is the problem
// This does not throw any errors but does not destroy the cookie as requested
$PersonsController->_kill_auth_cookie()
}
// This is from the Person controller, these are the functions used in the API
// This is the function that sets the cookies
public function _set_auth_cookie( $email ) {
setcookie(Configure::read('auth_cookie_name'), $email);
}
// this is the function that does not properly destroy the cookie from the API
// interestingly, it does work when called from in this controller
public function _kill_auth_cookie() {
setcookie(Configure::read('auth_cookie_name'), 'xxx', time()-7200);
}
I cannot get the API to properly expire the cookie that is created earlier in the session, I am not sure why. Additionally—what is maddening—is that the logs are empty and no error is being thrown of any kind, so I am not sure what to do next.
There is so much wrong in this code and concept…
DON'T instantiate controllers anywhere. It is plain wrong, broken by design and violates the MVC pattern. Only one controller should be dispatched by the framework itself based on the request; you don’t instantiate them manually.
An API using cookies? Well, not impossible but definitely not nice to work with. It’s possible but I’ve never seen one in the wild. I feel sorry for the person who has to implement it. See this question.
Why are you not using the CookieComponent? It has a built-in destroy() method to remove a cookie.
If you have an “auth” cookie, why are you not using CakePHP’s built-in Auth system? It will deal with all of that.
Use App::uses() not App::import() here
By convention, only protected functions should be prefixed with _
The first point is very likely the reason why cookie and sessions are messed up because the second controller instance initiates components again, and by this cookie and session maybe a second time as well. However, this can lead to “interesting” side effects.
I first call another controller to use functions from that controller
This is the evidence that your architecture is broken by design. The code that needs to be executed somewhere else; should be in a model method in this case. Or at least a component if there are controller-related things to be shared between different controllers.
On every page I see that new session is generated with null userdata
On model constructor
$this->config->set_item('sess_table_name', 'xx_sessions');
Because I want to store this session in another table because the other session table is being used for another login activity
Login function
function login($username,$password)
{
$this->db->where('login',$username);
$this->db->where('pass',$password);
$q=$this->db->get('prof');
// print $this->db->last_query();
if($this->db->count_all_results())
{
$arr=$q->row();
// creating the session
$this->session->set_userdata('login',$arr->id);
$this->session->set_userdata('prof',$arr->profile_id);
// print_r( $arr);
}
else
return FALSE;
}
This login function is on a model. After login and generating the session the page redirects to another page, on that page I see the session builds without any problem but when I move to another page the session losses along with the userdata.
I use the following function to check session data
function print_session()
{
print_r( $this->session->all_userdata());
}
Where I'm wrong ? Tank_auth library and ion_auth library works fine .. I had already used the
Put the session library name into the autoloader configuration, in application/config/autoload.php:
$autoload['libraries'] = array('session');
Then it's available automatically in each controller and everywhere in your application and you get your session data from anywhere:
$session_id = $this->session->userdata('session_id');
And if you don't want to auto load session library then you have to initialize the Session class manually in your controller constructor, use the $this->load->library function:
$this->load->library('session');
For details have a look here:http://ellislab.com/codeigniter/user-guide/libraries/sessions.html
Edit /application/config/config.php and set cookie domain variable
$config['cookie_domain'] = ".yourdomain.com";
It will work!
.yourdomain.com makes the cookie available throughout the domain and its sub-domains.
I have met same problem, and i have searched lots of pages.
I figured out that changing sess_cookie_name solves the problem(new sessions generating issue)
$config['sess_cookie_name'] = 'somenewname'
After the user has logged in I want to be able to save the userId for later use within the application. The only place in the application I retrieve the username is from the login form, through the login controller. However, that structure in my application is that the only thing that is passed to my master controller from the login controller is HTML.
Of course I could include the userId in a hidden field inside the HTML that's passed back to the master controller, but that seems too hacky.
So, is there a way that I can save a value (in this case the username) so that it's accessible from other classes/namespaces/functions whatever? I have read a bit about 'global', but haven't managed to get it work in my application.
from LoginController.php:
if ($loginView->TriedToLogin()){
$loginUsername = $loginView->GetUserName(); //Retrieved from form
$loginPassword = $loginView->GetPassword();
}
Upon login, you need to store your user token in a session.
See: http://au1.php.net/manual/en/features.sessions.php
Store user when logging in:
$_SESSION['user_id'] = 32; // fetch from your user provider
You can then write a class/function that utilises the session to check their login status and fetch their details when required.
Like so:
function getUserId()
{
return isset($_SESSION['user_id']) ? $_SESSION['user_id'] : false;
}
function isLoggedIn()
{
return isset($_SESSION['user_id']) && is_numeric($_SESSION['user_id']);
}
Then use anywhere in your application:
echo isLoggedIn() ? getUserId() : 'Anonymous';
Also, for great information on how to build an MVC framework, check out "Create your own framework... on top of the Symfony2 Components".
How about Sessions?
Session support in PHP consists of a way to preserve certain data
across subsequent accesses.
http://de2.php.net/manual/en/features.sessions.php
If it's only the username you want store, I would go with $_SESSION[].
It's not the most secure in a (shared) hosted environment, but it's so easy to call session_start(); first thing on pages using the stored data.
I was hoping someone could help me with a question I've come up on.
I have a Session object that handles storage of general session data, I also have a Authentication object which validates a users credentials.
Initially I passed the desired Authentication class name to my Session object then had a login method that created an instance of the Authentication object and validate the credentials. I stored the result of this validation in a Session variable and made it available via a getter. The user data was also stored in the Session for later use. In addition to all this, I have a logout method, which removes the user data from the Session and thus logging the user out.
My question is what role should the Session object play in users logging into their account?
And what other ways might one suggest I go about handling user login, as it stands right now I feel as though I'm getting too much wrapped up in my Session object.
Simply calling your authenticate method should trigger logic within Auth to store the proper data in the session (or some other data store) and Auth should also be used exclusively to retreive/revoke this info. So using the example form your comment it might be:
class Auth {
public static function authenticate($identity, $pass)
{
// do lookup to match identity/pass if its good then
/* assume $auth is an array with the username/email or
whatever data you need to store as part of authentication */
Session::set('auth', $auth);
return true;
// if auth failed then
Session::set('auth', array('user'=>'anonymous'));
return false;
}
public function isAuthenticated()
{
$auth = Session::get('auth');
if(!$auth)
{
return false;
}
return (isset($auth['user']) && $auth['user'] !== 'anonymous');
}
}
[...] as it stands right now I feel as
though I'm getting too much wrapped up
in my Session object.
And id agree. Idelaly for authentication/credentials you shoudl only be interacting with the Auth/Acl object(s). They would then utilize the session as stateful store... but you shouldnt care that its even stored in session. The code utilizng the Auth/Acl object(s) should be completely unaware of this fact.
For example:
//Bad
if($session->get('authenticated', 'auth'))
{
// do stuff
}
// also bad
if(isset($_SESSION['authenticated']))
{
// do stuff
}
//Good
if($auth->isAuthenticated())
{
// do stuff
}
// inside $auth class it might look like this
public function isAuthenticated()
{
$store = $this->getSotrage(); // assume this returns the $_SESSION['auth']
return isset($store['authenticated']);
}
The session is a good place for holding user data that you want to have managed in some sort of state across various pages or if you need a fast accessible way to get at it without hitting the database. It is a bad idea to keep secure information (re: passwords/etc) in the session, but rapid access information like username, name, email address, preferences, etc is all good data to put in the session. Try to keep it simple though.
Keep in mind though, that the session (or related cookie) should only ever be used for identification. It should not be used for authentication.
Authentication object is a good method. Make sure that it only holds secure information as long as it needs to and that it has all the necessary functions available to keep sensitive data protected.