Laravel: How to see if user is logged in in Base Controller? - laravel-6

I want to be able to change a field called "last_accessed" in the users table on each and every request the user makes.
I have a controller called "ContentController" which extends "Controller". So I figured just adding code in the constructor of "Controller":
public function __construct()
{
$user = \Auth::user();
if (Auth::check()) {
print 'Good';
}
else print "Bad";
}
No matter what I do, I can't it to see that I'm authorized.
Can someone please tell me:
Why is AUTH not working in the base controller?
How can I update the last_accessed field upon each view if this controller idea of mine isn't possible?

Because that doesn't work in __construct(). There is a workaround. It works but I'm not sure if some other Laravel users will accept my answer. What you should do is create a middleware and work from there. You can use an anonymous function, which in this case, mimics a middleware:
public function __construct(Request $request)
{
$this->middleware(function ($request, $next) {
$user = $request->user();
if ($user) {
print 'Good';
}
else print "Bad";
return $next($request);
});
}
If no user is logged in, $user will be null.

Related

Authentication with basic type api

After a good amount of time, I found the solution through an authentication plugin that is easy to install via composer with the command:
composer require "cakephp/authentication:^2.0"
After that, just generate the crud via terminal and check them to send json type data. It can be done as follows:
$this->response
->withType('application/json')
->withStatus(200)
->withStringBody(json_encode($dataOrMessage));
Add the function in entity to encrypt the password that the user registers:
protected function _setPassword(string $password) : ?string {
if (strlen($password) > 0) {
return (new DefaultPasswordHasher())->hash($password);
}
}
Implementing the AuthenticationServiceProviderInterface interface in the Application class and adding its requirements, in addition to the login and logout functions of the aforementioned plugin, you can view here
The login function will look something like this:
public function login() {
if ($this->request->is('post')) {
$result = $this->Authentication->getResult();
if ($result && $result->isValid()) {
return $this->response
->withType('application/json')
->withStatus(200)
->withStringBody(json_encode($result->getData()));
} else {
return $this->response
->withType('application/json')
->withStatus(401)
->withStringBody(json_encode(['message' => 'User or password incorrect!']));
}
}
}
There is not only this solution, but it was the one I found and that I found to be easier to implement.

How to check permissions in my controller

I'm new to Laravel and I'm writing a user management System on my own.
At this time,
I can CRUD permissions, roles and users,
I can check the permissions by the AuthServiceProvider#boot method like this:
public function boot()
{
Gate::before( function (User $user , $permission) {
// App administrator
if($user->getPermissions()->contains('appAll'))
{
return true;
}
// Permission check
return $user->getPermissions()->contains($permission);
});
}
In my AdminUserController, I can check the permissions like that:
public function index()
{
if( Gate::check('createUser') || Gate::check('readUser') || Gate::check('updateUser') || Gate::check('deleteUser')) {
return view('userMgmt/users/index', [
'users' => User::getUsersWithRolesWithTexts()
]);
}
else
{
return redirect(route('home'))->withErrors('You do not have required permission');
}
}
That is working well.
BUT
Is this the right way to wrap each controller method with:
if( Gate::check(...) ...) {
//Do what the method is supposed to do
}
else
{
return redirect(route('SOME.ROUTE'))->withErrors('SOME ERROR OCCURRED');
}
It would be nice if someone can give me some ideas.
Tank you
There is a controller helper function named authorize that you can call from any method in a controller that extends App\Http\Controllers\Controller. This method accepts the action name and the model, and it will throw an exception if the user is not authorized. So instead of the if...else statement, it will be one line:
public function update(Request $request, Post $post)
{
$this->authorize('update', $post);
// The current user can update the blog post...
}

how can I redirect login page if do not login in yii framework?

I have the actionLogin and create cookie like here :
public function actionLogin()
{
$this->layout = 'login';
$model=new LoginForm;
if(isset($_POST['LoginForm']))
{
$model->attributes=$_POST['LoginForm'];
if($model->validate() && $model->login()){
$cookie = new CHttpCookie('loginSuccess',$model->username);
$cookie->expire = 604800;
Yii::app()->request->cookies['loginSuccess'] = $cookie;
$this->redirect('/ktbeauty/index.php/categories/index');
}
}
$this->render('login',array(
'model'=>$model,
));
}
And Now I have some controllers which must check to login before access controllers, if not login, it must redirect to login page, how can I work for this ?
thankyou very much
in the action of your controller you can try something like this
public function actionGoToLogin()
{
if(!Yii::app()->user->isGuest)
{
// do something if user is authenticated
}
else
{
Yii::app()->user->loginRequired();
// or if you want you can redirect using Yii::app()->createUrl('controller/login');
}
}
In Controller, you have a function as below:
public function accessRules() {
Here you can define the actions and users who can access those functions.
If you are not logged in, then it'll redirected to login page by default.
This feature available by default in YII.
check this URL:
http://www.yiiframework.com/wiki/169/configuring-controller-access-rules-to-default-deny/

How to set default action dynamically in Yii

i want to change default action of a controller depends on which user is logged in.
Ex. There are two users in my site : publisher and author and i want to set publisher action as default action when a publisher is logged in, and same for author.
what should i do? when can I check my roles and set their relevant actions?
Another way to do this would be setting the defaultAction property in your controller's init() method. Somewhat like this:
<?php
class MyAwesomeController extends Controller{ // or extends CController depending on your code
public function init(){
parent::init(); // no need for this call if you don't have anything in your parent init()
if(array_key_exists('RolePublisher', Yii::app()->authManager->getRoles(Yii::app()->user->id)))
$this->defaultAction='publisher'; // name of your action
else if (array_key_exists('RoleAuthor', Yii::app()->authManager->getRoles(Yii::app()->user->id)))
$this->defaultAction='author'; // name of your action
}
// ... rest of your code
}
?>
Check out CAuthManager's getRoles(), to see that the returned array will have format of 'role'=>CAuthItem object, which is why i'm checking with array_key_exists().
Incase you don't know, the action name will be only the name without the action part, for example if you have public function actionPublisher(){...} then action name should be: publisher.
Another, simpler, thing you can do is keep the default action the same, but that default action simply calls an additional action function depending on what kind of user is logged in. So for example you have the indexAction function conditionally calling this->userAction or this->publisherAction depending on the check for who is logged in.
I think you can save "first user page" in user table. And when a user is authenticated, you can load this page from database. Where you can do this? I think best place is UserIdentity class. After that, you could get this value in SiteController::actionLogin();
You can get or set "first page" value:
if (null === $user->first_page) {
$firstPage = 'site/index';
} else {
$firstPage = $user->first_page;
}
This is a complete class:
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$user = User::model()->findByAttributes(array('username' => $this->username));
if ($user === null) {
$this->errorCode = self::ERROR_USERNAME_INVALID;
} else if ($user->password !== $user->encrypt($this->password)) {
$this->errorCode = self::ERROR_PASSWORD_INVALID;
} else {
$this->_id = $user->id;
if (null === $user->first_page) {
$firstPage = 'site/index';
} else {
$firstPage = $user->first_page;
}
$this->errorCode = self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId()
{
return $this->_id;
}
}
/**
* Displays the login page
*/
public function actionLogin()
{
$model = new LoginForm;
// if it is ajax validation request
if (isset($_POST['ajax']) && $_POST['ajax'] === 'login-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
// collect user input data
if (isset($_POST['LoginForm'])) {
$model->attributes = $_POST['LoginForm'];
// validate user input and redirect to the previous page if valid
if ($model->validate() && $model->login())
$this->redirect(Yii::app()->user->first_page);
}
// display the login form
$this->render('login', array('model' => $model));
}
Also, you can just write right code only in this file. In SiteController file.

Save user's last log out

I am trying to save user's last logout time into a DB in Yii framework.
I have WebUser as:
<?php
// this file must be stored in:
// protected/components/WebUser.php
class WebUser extends CWebUser {
public function afterLogout()
{
$user=user::Model();
$user->logOutDateTime='TEST';
$user->saveAttributes(array('logOutDateTime'));
parent::afterLogout();
}
}
?>
and in config\main.php I have these lines
// application components
'components'=>array(
'user'=>array(
// enable cookie-based authentication
'class'=>'WebUser',
'allowAutoLogin'=>true,
)
For now I have set logOutDateTime datatype to varchar, to test, and I assume every time user logs out, it should write 'TEST' into database but it does nothing.
Where did I go wrong?
I don't think the afterLogout() still has the Yii::app()->user set, so I would do something like (untested):
public function beforeLogout()
{
if (parent::beforeLogout()) {
$user = User::model()->findByPk(Yii::app()->user->id); // assuming you have getId() mapped to id column
$user->logOutDateTime='TEST';
$user->saveAttributes(array('logOutDateTime'));
return true;
} else {
return false;
}
}
$user = user::Model();
should be:
$user = user::Model()->find(/* model_conditions */);