All Yii2 controller not allow action without login or guest must need login - yii2

I'm using Yii2 Advance application and i am new in yii2 so how make
all yii2 controller not allow action without login or guest must me login
i mean controllers can not open without login if user not login so redirect in login page this not for one controller i need many controller

You need to add below code in common/main.php after components part.
'as beforeRequest' => [ //if guest user access site so, redirect to login page.
'class' => 'yii\filters\AccessControl',
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'allow' => true,
'roles' => ['#'],
],
],
],

You could simply create a super controller for this :
class Controller extends \yii\web\Controller
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => false,
'roles' => ['?'],
],
],
],
];
}
}
And of course all your controllers should extend this one.
Read more about Access Control Filter.

You can try write in index.php in your backed public directory
No need to repeat in controllers
<?php
// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require __DIR__ . '/../../vendor/autoload.php';
require __DIR__ . '/../../vendor/yiisoft/yii2/Yii.php';
$config = require __DIR__ . '/../../config/web.php';
$config["controllerNamespace"]='app\controllers\backend';
(new yii\web\Application($config))->run();
if(Yii::$app->user->isGuest){
$request_headers = apache_request_headers();
$srv=$request_headers['Host'];
header("Location: https://".$srv);
die();
}

use RBAC Manager for Yii 2 you can Easy to manage authorization of user.
https://github.com/mdmsoft/yii2-admin.

You could inherit from the yii Controller class where you can override the beforeAction method and in that function you can redirect the user if there is no active logged in session.
Make sure that all of the other controllers what you are using inherited from your new controller class.
EDIT:
In the SuperController beforeAction you can check if the current call is your site/index, if not then redirect to there like:
if($action->controller != "site" && $action->id != "index" ) {
$this->goHome();
}
Make sure that the goHome() take you to your site/index.
And you can split your Site actionIndex() method to an authenticated or not part like:
public function actionIndex() {
if(Yii::$app->user->isGuest) {
return $this->redirect(Url::toRoute('site/login'));
}
else {
...
}
}
Hope this helps.

Related

How to set separate homeUrl for authenticated users and guests in yii2

I'm wondering is it possible to make different homeUrl for authenticated and guest users? I have such rules in SiteController.php
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout', 'signup'],
'rules' => [
[
'actions' => ['signup'],
'allow' => true,
'roles' => ['?'],
'denyCallback' => function() {
return $this->redirect('/account');
}
],
[
'actions' => ['logout', 'condition'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
That shouldn't be much of a problem. My answer is structured as follows:
Config for guest users
Config for logged in users (overwriting)
Alternatives
1. Config for guest users
This one is easy. Simply set the home URL to whatever you want your guest visitors to land on. Put this in your config:
//...
'homeUrl'=>'site/home-guests',
//...
2. Config for logged in users (overwriting)
A login happens on each and every page-load either via form submission, cookie (remember me), session or access token. You won't notice this since it happens automatically except for the actual form-login.
The yii\web\User-class has an event which will be triggered after every login. Its called yii\web\User::EVENT_AFTER_LOGIN. You can find the doc for the triggering method here.
To fulfill your requirement simply extend the user class and within the init()-method attach an event handler. If the event mentioned gets thrown, change the home URL. Done!
Heres the code of the custom user class:
class User extends \yii\web\User {
//...
public function init() {
parent::init();
//listen to after login event
$this->on(static::EVENT_AFTER_LOGIN, function ($event) {
Yii::$app->setHomeUrl(Url::to(['site/home-logged-in']));
});
}
//...
}
For Yii to use your custom and extended class, simply tell it to within the config:
//...
'user'=>[
'class'=>'app\components\User',
],
//...
3. Alternatives
If it's not about the URL but simply to show the users different contents depending on their login-status you have other / easier options:
show a different view when logged in but use the same action
redirect them within the action method
if/else within the actual home-view
Which one is right depends on your detailed requirement. This is difficult to tell with the information you provided.
Tell me if you have further questions. I'll be happy to help!

User login action is not working, showing invalid username and password in CakePHP3

I am trying to implement login functionality in CakePHP3 by following all prescribed ways. I have already tried many alternatives apart from main method found on Authentication page of official Cake website.
The error, I am receiving is "Invalid username or password". Below is a snapshot of code, I have used. Please note, I have followed proper naming conventions of CakePHP so no config issue should be there. Plus the issue is in 3.x version so don't answer for older versions please.
File: UsersController > Login Action
public function login() {
if($this->Auth->user()){
$this->Flash->error(__('You are already logged in!'));
return $this->redirect($this->Auth->redirectUrl());
}
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
$this->Flash->success(__('You\'re successfully logged-in.'));
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Username or password is incorrect'));
}
}
File: AppController > Initialize Function
public function initialize()
{
parent::initialize();
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'loginAction' => [
'controller' => 'Users',
'action' => 'login',
],
'authError' => 'Did you really think you are allowed to see that?',
'authenticate' => [
'Form' => [
'fields' => ['username' => 'username']
]
],
'storage' => 'Session'
]);
$this->Auth->allow(['display']);
$this->Auth->allow(['register']);
}
File: Login View
<?php
echo $this->Form->create();
echo $this->Form->input('username');
echo $this->Form->input('password');
echo $this->Form->button('Login', ['class' => 'btn']);
echo $this->Form->end();
?>
Hope, I haven't missed anything but still it is not working as intended.
Any suggestion will be appreciated.
TIA
It is not working without PasswordHasher in Auth component.
You should add it in /src/Model/Entity/User.php
Add below code at the end. Also add use Cake\Auth\DefaultPasswordHasher;
protected function _setPassword($value){
$hasher = new DefaultPasswordHasher();
return $hasher->hash($value);
}
After this add new user and try to login with it.
Is your user entity using the DefaultPasswordHasher in the file src/Model/Entity/User.php?
Just a thought...

how to limit access url view on yii2 by id

I am basically a PHP developer & learning Yii2. I am working on web application that has account based login system. Like the way i was doing in PHP web applications, i want to stop another user from accessing the view if he/she is not authenticated. Its like if someone tries to access url(any related URL) externally:
www.example.com/permintaanbarang/index.php?r=user/view&id=1
chage to
www.example.com/permintaanbarang/index.php?r=user/view&id=2 by another user
At that time that person should be redirected to login page or Notice NotFound 404 as that person is not authorized to access account based page directly.
What are the directions to implement this in MVC framework???
A simple way for controlling access and avoid to guest user (not authenticated) to access is use filter for access control
<?php
namespace yourapp\controllers;
use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use common\models\LoginForm;
use yii\filters\VerbFilter;
/**
* Site controller
*/
class SiteController extends Controller
{
/**
* #inheritdoc
*/
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'actions' => ['logout', 'index'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
In this sample you can see that you can configure the action you can access ofr all and for authenticated #
You can find useful this guide http://www.yiiframework.com/doc-2.0/guide-security-authorization.html and this reference http://www.yiiframework.com/doc-2.0/yii-filters-accesscontrol.html
In Yii2 you can also use a RBAC authrization component for define class of user and grant to this class specific accessing rules ..
and you can also check programmaticaly the RABC Auth for specific need eg:
if (!Yii::$app->user->isGuest) { // if the user is authenticated (not guest)
if ( Yii::$app->User->can('admin') ){ // if the role is admin
.....
you app code
There are AccessControlFilters for doing this

What is best way to redirect on login page in yii2

If user is not logged in then user should have to be redirect on login page, for that i found function which is working fine for me, i used below function
public function beforeAction($action)
{
if (\Yii::$app->getUser()->isGuest &&
\Yii::$app->getRequest()->url !== Url::to(\Yii::$app->getUser()->loginUrl)
) {
\Yii::$app->getResponse()->redirect(\Yii::$app->getUser()->loginUrl);
}
return parent::beforeAction($action);
}
This is working fine for me, but for this i need to add function in every controller, what i want to do, i need common function where can i perform this action, So can anyone please tell me what is best way to do this ?
You need to add below code in config/web.php after components part.
'as beforeRequest' => [ //if guest user access site so, redirect to login page.
'class' => 'yii\filters\AccessControl',
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'allow' => true,
'roles' => ['#'],
],
],
],
Actually if user does not have rights Yii redirects him to login page by it self.
You can change loginUrl if you have another one. Or you can implement own redirect if for example you use ajax.
http://www.yiiframework.com/doc-2.0/yii-web-user.html
Here is explanation of Yii security
http://www.yiiframework.com/doc-2.0/guide-security-authorization.html

Problems with Yii2 Rules creation

I have a Yii2 with Yii2 admin, user andAdminLTE installed. My problem is I don't know how to create rules, actually I don't know how to define the Class Name. Where "Classes" should be defined? How can I see which Classes do I have or add Classes?
Thanks a lot,
I don't know what is that module that you use but i know how to define rules for controller.please open a controller for example : mycontroller.
when you want create a rule for action in your mycontroller you should use the 'behaviors' function as you can see in bellow.
class MyController extends Controller {
public function behaviors() {
return [
'access' => [
//you can use this class is use for every controller "AccessControl::className()"
'class' => AccessControl::className(),
// use this rules just for these two actions(logout and signup)
'only' => ['logout', 'signup'],
//this is your rules for your controller's actions
'rules' => [
[
'actions' => ['signup'],
'allow' => true,
// '?' is the default roles in yii2
'roles' => ['?'],
],
[
'actions' => ['logout'],
'allow' => true,
// '#' is the default roles in yii2
'roles' => ['#'],
],
],
],
];
}
i have two actions in this controller 'signup','logout'and i give roles to every actions.i give ? role to sign up and # role to logout.
? roles:means every user with out login can see this action.
# roles:means every user with login cans see this action.
as you can see the class in rules definition is static and you don't need to specify class you can just can use AccessControl::className() in your code.
best regards