how to acess user session in sfDoctrineRoute with symfony ?
var_dump(sfContext::getInstance()->getUser());
returns NULL
i cant access current user session in routing
Accessing user session from a custom routing class = bad response
You should use the sfDoctrineRoute::setQuery() method from your controller, and generate a query using its sfUser reference and, for example, the user credentials it contains:
protected function executeIndex(sfWebRequest $request)
{
$query = Doctrine::getTable('Foo')
->createQuery('f')
->whereIn('f.access_level', $this->getUser()->getCredentials())
;
$this->getRoute()->setListQuery($query);
$this->foo_list = $this->getRoute()->getObjects();
}
Hope it helps.
PS: you should ALWAYS avoid calling sfContext::getInstance().
Related
I'm working on a client project that wasn't conceived with services and authorizations, so the user gets logged in and creates a user session.
I have to control the access in a basic "UserboardController".
I have a constructor before any methods :
class UserboardController extends Controller
{
public function __construct() {
$session = new Session();
$uSession = $session->get('user');
if (!isset($uSession)){
return $this->redirectToRoute('logout');
}
}
I tried many ways to redirect and always get this error :
Call to a member function get() on null
Symfony will show me two other traces inside redirectToRoute from ControllerTrait.php :
return $this->redirect($this->generateUrl($route, $parameters), $status);
and
return $this->container->get('router')->generate($route, $parameters, $referenceType);
Any idea how I could simply redirect the user to the logout route ?
This is an important step as the logout method will do other actions based on cookies before logging out and redirecting to the login form.
Logout route is defined and works if the user accesses it from the URL.
Thank you
First of all, if you want to access session you should pass it as argument and get benefit of autowiring. Secondly, this shouldn't be done in a controller's constructor.
Thirdly this looks like the case for the security module of symfony. Symfony when properly configure will return use by default to /logout route of any route that is defined as logout route
So what you need to do is define in security.yaml your firewalls and define in access_control the path that should be under the firewall
Check this for more clues https://symfony.com/doc/current/security/form_login_setup.html
I'm having my first interaction with the core laravel code so I want to be careful not to break anything.
In my project, my users also correspond to person records (via user->person_id), so I have a get_person_from_user() function that takes the \Auth::user() (conveniently accessible anywhere) and returns the person object, so I can grab the person record for the authenticated user from any controller and pass it to a view.
The problem: there's a piece of data from the person record that I'd like to include in a nav partial in my default blade view (which gets extended by a bunch of different views), so it's the one case where I'm not going through a controller first. I'm unclear on how I can make the logged in user's person record available here. Any suggestions?
I think I need to add some step after the user logs in, to save the person record (globally? in the session?) so it's generally accessible. The login stuff happens in AuthenticatesUsers.php, and reading around it sounds like I'll want to add an override of postLogin to my AuthController.
But I tried copying that function from AuthenticatesUsers.php into my AuthController (not adding anything else to it yet), and AuthController gives me a new error when I try to log in:
ReflectionException in RouteDependencyResolverTrait.php line 81:
Class App\Http\Controllers\Auth\Request does not exist
Any advice on a good way to go about accessing the person object for the authenticated user, when I don't have a controller to pass it along?
You can setup the correct relationship on the User model to Person model.
public function person()
{
return $this->belongsTo(Person::class);
}
Then you can do:
Auth::user()->person;
For having a variable available to a particular view you can use a View Composer. (You can create and register a Service Provider and add this to the register method.) Potentially something like this:
view()->composer('someview', function ($view) {
if ($user = Auth::user()) {
$somevar = $user->person->somevar;
} else {
$somevar = null; // or some default
}
$view->with('somevar', $somevar);
});
If this view is also used in a scenario where someone doesn't have to be authed you will want to check if Auth::user() is null before trying to use the relationship.
Laravel Docs - Views - View Composers
I suggest you to use Eloquent relation
User.php
public function person()
{
return $this->belongsTo('NAMESPACE_TO_YOUR_MODEL\Person'); //also you can specify FK, more info in docs
}
then you can access Auth facade in your view
Auth::user()->person
im doing this;
example core/MY_CONTROLLER.php
private $action_user=null;
public function __construct()
{
parent::__construct();
##listen for post attempts;
$this->validate();
##set action_user; return null if no session else return user object
$this->action_user = $this->session->userdata('loged_user');
##extra check step
if($this->user->pwd_has_changed($this->action_user)){
$this->session->sess_destroy();
alerts('error','the password you used to login has changed ! please relogin');
return $this->failed_login();
}
}
public function alerts(){return die(json_encode(alerts()));}#a helper function.. just ignore it for this example
public function logout(){$this->session->sess_destroy();redirect();}
#AUTH
private function failed_login(){
//$callers=debug_backtrace();
alerts('warning','failed login');//.' '.$callers[1]['function']);
ob_clean();//clear flush just to make sure !
if($this->input->is_ajax_request())$this->load->view('base/ajax/landing');
else $this->load->view('base/landing');
die($this->output->get_output());//kill request and load landing in same uri. this in case he attempt login again he will be at same url; also helps with partials views
}
private function success_login(){
unset($_POST['login'],$_POST['password']);
alerts('success','welcome '.$this->action_user->login);
//nothin much to do.. just dont die
}
private function validate(){
//listen to posts if so logout and relog in
if( !$this->input->post('login') || !$this->input->post('password'))return FALSE;
$this->session->sess_destroy();#destroy session
#1. validation
$this->form_validation->set_rules('login', 'User Login', 'required|min_length[4]|max_length[12]|xss_clean');
$this->form_validation->set_rules('password', 'Password', 'required|min_length[4]|max_length[12]|xss_clean');
#1.2 Failed validation
if( ! $this->form_validation->run() )return alerts('error',$this->form_validation->error_string(),false);#set message and return false
#2. Login
$this->user->login(set_value('login'),set_value('password'));
//i dont want it to return anything ! $this->user->login should set messages of success OR fail + set user session
}
public function auth($role = null){
if(!isset($this->action_user->id))
return alerts('error',"this is a users restricted area",$this->failed_login());
//ACCESS LEVELS CONDITIONS
if($this->user->in_group($this->action_user->id,$role))return $this->success_login();
return alerts('error',"this is a {$role} restricted area",$this->failed_login());
}
#END AUTH
now in my controller constructor; since MY_CONTROLLER constructor is called first; so i should hv retrieved $action_user object; or already attempted to log him in.
if i want to restrict a page i just add
$this->auth();
//or $this->auth('admin');
to its constructor and if user is not allowed page will die and send him my view page without redirect;
the reason im using such approach is let user be able to login,logout from any controller;
if he visit http://localhost/RANDOMECONTROLLER/logout he will still logout.. same for login.
also its helpful that sometimes when i get page partials by ajax; it will just return a landing page into this div with login form.
example
a statistics page have 4 widgets, 1 of them is only viewable by admin;
then when ajax fitch 4 widgets, it will show 3 and a div with login form saying you need to be an admin to login..
...
so do you think this is a good way to do this ? or is it bug gable spaghetti ** ?
This is not a good practice. The best practice is to create a Secure_Controller that extends MY_Controller. If you have a controller with auth you need to extend Secure_Controller, but if you have another without auth you need yo extend MY_Controller.
There are lots of libraries for codeigniter auth easy to extend and adapt to your requirements, for example Ion Auth.
In CakePHP we can use $this->Auth->allow('someMethod'); to make a page viewable without having to login. How do I make some the same page is not viewable when a user is logged in? An example of this would be a register page which we want to be accessible without user logged in ... but not accessible once a user logged in.
I put $this->Auth->deny('someMethod') in isAuthorized() but it seems to me that if the method is in the allow list then isAuthorized is not called when we try to run that page.
Any input? Thank you
There are no complex rules like that built into Cake Auth. You'll have to manually check for conditions like this. It's very simple though:
// Controller
function register() {
if ($this->Auth->user()) {
$this->redirect(/* somewhere else */);
}
}
Contrary to mlevits answer, you don't need to store anything in the Session, the info is readily available from the AuthComponent itself. http://book.cakephp.org/view/387/user
There's also an example how to do it by dynamically using deny(), but that's not as clear in a simple case like this IMHO. http://book.cakephp.org/view/383/deny
Also, deny() produces an error message ("You're not authorized to access this location"), which is probably not what you want for the user experience in this case.
EDIT:
Wasn't aware that CakePHP used a different syntax.
You can then use the following to set the Session variable:
$this->Session->write('user_id', '<some_user_name>');
Then use this to redirect the user if they are logged in:
if ($this->Session->check('user_id'))
{
$this->redirect('http://google.com');
}
And then to destroy a Session use:
$this->Session->destroy()
More information about CakePHP Sessions
Thanks
You can check it in method beforeFilter in AppController to allow aplication-wide check. For example:
<?php
class AppContoller extends Controller {
var $components = array('Session', 'Auth');
function beforeFilter(){
$this->Auth->allow('register', 'home');
// Check if current action allowed to access without authorization and User has login
if(array_key_exists($this->params['action'], $this->Auth->allowedActions) && $this->Auth->user()){
$this->redirect(/* somewhere else */);
}
}
}
?>
Of course you can also implements it in some controller instead of AppController.
I'm trying to make the Auth module to 'remember' the user session with a checkbox on the login page. What happens is that no cookie is created, only session as usually. I've noticed the user_tokens table, but don't see any use of user_token model's methods at all. I do pass (bool) TRUE as a third parameter to login() method, but there's no difference.
Is this feature complete at all or I have to add my own by overwritting the login() method of Model_Auth_User ?
What's the best practice for this ?
I also opened a topic on Kohana Forums
Answer from the Kohana forum (credit to biakavero) pasted here for reference:
Call Auth::instance()->login() with $remember = TRUE
DB Token for current user created. Cookie authautologin generated.
Destroy user object : Session::instance()->delete('auth_user'); // dont call logout() method as it will delete cookie & token
Call Auth::instance()->auto_login() and check for Auth::instance()->get_user() // should return Model_User object