I'm running Kohana 3, and having a hard time understanding the Auth module, or even if it's what I need. Basically I want to create a basic user profile site with basic username/password protection.
How do I take my existing controllers...
class Controller_Profile extends Controller
{
function action_index( $user_id )
{
// User should already be authenticated by here I think
}
}
...and use them with some sort of authentication system
For Kohana 3 you'll want to do your check in before and not __construct like JIStone suggests.
public function before()
{
parent::before();
// This automatically checks for an auto login cookie (thanks kemo).
if ( ! Auth::instance()->logged_in())
{
// Redirect to a login page (or somewhere else).
$this->request->redirect('');
}
}
Simple enough to understand. You can put this into a controller and have all the controllers that need authentication to extend that.
If you will be requiring a user to be registered for all pages on the controller you can put a check in your __construct() statement:
function __construct()
{
//Check roles for Access!!!!
parent::__construct();
$this->load_user();
if( ! $this->is_registered )
{
if(request::is_ajax())
die('This ajax call cannot be completed due to permission issues.');
// this will redirect from the login page back to this page
$this->session->set('requested_url', url::current());
url::redirect('user/login');
}
}
This is the code we use, but it is Kohana 2, not 3, so you will need to adjust a bit for your purposes.
I have provided a link to a short walkthrough for the installation and basic usage of the Auth Module in Kohana 3
Once you have your Auth process working, you can protect certain controllers by checking for a logged in user and proper authentication role in your before() method, or create a base controller for all your controllers that will need this check. If the user is not logged in, redirect them to the login page, if they do not have the proper access level (or role), then you can show them an "Access Denied" page.
Related
I started working on a project which should have admin panel and frontend and I want to use CodeIgniter framework on client request. But the problem is I am not able to understand how to start the project as mentioned above.
I want folder similar to the image shared
Besides the Admin_controller (for separeted security rules), for better organization, it's good to use some extension like this one:
HMVC: https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/src
With this you'll be able to that this type os structure:
URLs
http://awesome.site/public_controller
http://awesome.site/*module_name*/*controller_inside_module*
http://awesome.site/admin/login
Try using Codeigniter's session functionality to authenticate the user and his role (e.g., "admin", "customer", etc)
Then add a constructor like this to every controller (this is just an example)
class Admin_only extends CI_Controller {
public function __construct()
{
parent::__construct();
if( !isset($this->session->userdata['logged_in']) || $this->session->userdata['logged_in']['user_type'] != 'administrator' )
{
// you're not welcome here
redirect('welcome/access_error');
}
}
The __construct() is run every time anything within the controller is accessed.
See how in my example (there's cleaner ways, but this will definitely work), I'm constantly checking if the user is logged in AND if the user is an administrator (actually I'm checking the opposite... logged out OR not administrator, but it's pretty much the same thing logically) and if the check fails, the user is redirected away from the controller.
Building an app in Laravel 5.3, one of the functionalities is for the admin to be able to log into the app as a user, to be able to see what that specific user can see, while maintaining his admin session to be able to go back to the user list and be possible to log in as another user without having to re-authenticate.
Currently implemented the basic out-of-the-box Laravel Auth, meaning if I start another auth session it will terminate my admin session making me having to re-login.
I have checked Laravel Multi Auth but seems to work with two tables (user,admin), which in my case we use one user table and use an ACL for managing roles and deciding whos admin and whos user.
What programming logic ideas do you guys have for this solution? Trying to find other opinions/ideas in how this could be implemented in Laravel 5.x
I've implemented the feature on a project recently. I did this using the session and a middleware. This is how I did it:
Create a controller 'ImpersonateController' and Set two routes for impersonateIn and impersonateOut for the purpose.
Route::get('impersonateIn/{user}', 'ImpersonateController#impersonateIn');
Route::get('impersonateOut', 'ImpersonateController#impersonateOut');
In the ImpersonateController#impersonateIn method just set the user id you want to log in and the URL backUrl into the session variable.
public function impersonateIn($id)
{
session(['impersonated' => $id, 'backUrl' => \URL::previous()]);
return redirect()->to('dashboard');
}
public function impersonateOut()
{
$back_url = Request::session()->get('backUrl');
Request::session()->forget('impersonated', 'secretUrl');
return $back_url ?
redirect()->to($back_url) :
redirect()->to('dashboard');
}
The first part is done. Now every request need to check the if the session has the
impersonated variable set. A good place to do that is a middleware.
Create a middleware to check the session on the handle method. If the impersonated found then log as the user using the Auth::onceUsingId() for the current request only.
class ImpersonateMiddleware
{
public function handle($request, Closure $next)
{
if(Request::session()->has('impersonated'))
{
Auth::onceUsingId(Request::session()->get('impersonated'));
}
}
}
Now you just need to apply the middleware for every request. The best place to do this from the Http/Kernel.php
protected $middlewareGroups = [
'web' => [
//....
\App\Http\Middleware\ImpersonateMiddleware::class,
],
];
The only remaining thing is you need to check the session and replace the logout route to the impersonateOut. Now when the admin logged out from the user will be redirected to the old route.
That's it!
Are you sure you really have to login?
I would stay logged in as admin and simulate user login.
You can allow admin access to all the databases.
In your controller you can use User::find($user_id) instead of Auth::user() for accessing user's data.
https://laravel.com/docs/5.3/database
https://laravel.com/docs/5.3/eloquent
Personaly, I would do this with sessions. I have not used Laravel but I use PHP often, so my answer will be in PHP.
In the header page, you most likely have some kind of session check to see if the user is logged in. For example:
<? php
session_start();
if (isset($_SESSION['user'])){
//do stuff with the user session
} else {
die('User not logged in!');
}
?>
I would change this to something like:
<? php
session_start();
if (isset($_SESSION['fakeuser'])){
//do stuff with the user session
//change logout button to destroy this session instead of logging the user out
}
elseif (isset($_SESSION['user'])){
//do stuff with the user session
} else {
die('User not logged in!');
}
?>
In the page in which you swap users, you would just simply copy the way a session starts when a user logs in. To switch users, you destroy the new 'fakeuser' and you are back to your old session + admin permissions without having to log back in again.
That's the logical approach I would take anyways.
my question is trivial byt i am new and do not even know what to look for
i am using kohana framework to build my site. I have already learned how to use auth module (more or less) and created login, logout "arhitecture".
When my user is not logged i redirect to login page and when it is I use a view to show user data.
Now i am trying to do something like a page menu when i can see "login" button when user is not logged in, but "logout" button when logged. Do i make myself clear? I assume i cant redirect anywhere as this is a part of the same view. then how do I deterin a view content accordingly to a user state?
I am not looking for a ready code (although that would me apreciated) but a direction on what to look for and what to read about.
For Kohana 3.2 you could check if a user is logged in by calling
Auth::instance()->logged_in();
An option of integration might be to build a base controller where the user is redirected or set in the before action. That way you always have the redirect in 1 place and the user set if there is a valid login.
class Controller_Custom extends Controller {
protected $user;
public function before()
{
if ( ! Auth::instance()->logged_in()) {
$this->request->redirect('url/login/page');
}
$this->user = Auth::instance()->get_user();
}
}
For Kohana 3.3 the redirect request is changed a bit I believe.
i have built upon this tutorial http://www.jamesfairhurst.co.uk/posts/view/creating_an_admin_section_with_cakephp_updated
and currently have a functional and quite well fleshed out admin section for my application.
Due to poor foresight I haven't taken into account regular users who need to be able to login to their own home page, where they can view bookings etc.
I have an appropriate database set up and have included a 'roles' field for authentication. I have also followed cakePHP's own 'auth' examples however have failed to get them to implement without throwing various errors, at this stage i'm not wanting to go changing the structure of the login system too much, that kind of thing can become a headache quick!!
I have spoken to the original author of the tutorial and he agrees that some simple logic added to the user_controller.php file should suffice.
basically i need something along the lines of an: "if user == 'user' THEN redirect to 'user_index.php' put simply.
below is the current LOGIN function for user_controller.php
function login() {
if(!empty($this->data)) {
// unset unrequired validation rules
unset($this->User->validate['username']['check_username_exists']);
// validate form
$this->User->set($this->data);
if($this->User->validates()) {
// update Last Login date
$this->User->id = $this->User->_user['User']['id'];
$this->User->saveField('last_login',date("Y-m-d H:i:s"));
// save User to Session and redirect
$this->Session->write('User', $this->User->_user);
$this->Session->setFlash('You have successfully logged in.','default',array('class'=>'flash_good'));
$this->redirect(array('action'=>'index','admin'=>TRUE));
}
}
}
All validation is handled in the user.php model and there is some logic in app_controller.php to redirect authentication, it is included below;
app_controller.php
class AppController extends Controller {
// class variables
var $_User = array();
/**
* Before any Controller action
*/
function beforeFilter() {
// if admin url requested
if(isset($this->params['admin']) && $this->params['admin']) {
// check user is logged in
if( !$this->Session->check('User') ) {
$this->Session->setFlash('You must be logged in for that action.','flash_bad');
$this->redirect('/login');
}
// save user data
$this->_User = $this->Session->read('User');
$this->set('user',$this->_User);
// change layout
$this->layout = 'admin';
}
}
}
I faced a similar problem in my application. In my User model, I created a getRole() method which just pulled the role out of the database, and then I used a switch statement to redirect users to the correct controller.
As a different approach, you could just add in an isAdmin column (default 0, 1 would indicate an admin) to your users table. Assuming there are not too many admins already, you could just manually set the admins. In your controller you would just need to check the field and the redirect accordingly.
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.