I just a newbie in Yii. I have read http://www.yiiframework.com/wiki/328/simple-rbac/ and followed all instructions there, but I had error User.roles is not defined when I tried to login. Here is my UserIdentity.php
<?php
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->username;
$this->setState('roles', $user->roles);
$this->errorCode=self::ERROR_NONE;
}
}
return !$this->errorCode;
}
public function getId(){
return $this->_id;
}
}
And then EWebUser.php
<?php
class EWebUser extends CWebUser
{
public function checkAccess($operation, $params=array())
{
if (empty($this->id)) {
// Not identified => no rights
return false;
}
$role = $this->getState("roles");
if ($role === 'admin') {
return true; // admin role has access to everything
}
// allow access if the operation request is the current user's role
return ($operation === $role);
}
}
At last accessRules method in UserController.php
public function accessRules()
{
.....
return array(
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','delete'),
//'users'=>array('admin'),
'roles'=>array('admin'),
.....
);
}
I hope anyone can help me solve this problwm, thank you very much
Related
I'm trying to do:
when user authorized go to home page
when user not authorized go to Login page
but now when I put (correct) user email and password that always refresh login page and doesn't log in into system.
User(ActiveRecord)
class User extends ActiveRecord implements IdentityInterface
{
public function setPassword($user_password)
{
$this->password = sha1($user_password);
}
public function validatePassword($user_password)
{
return $this->user_password === sha1($user_password);
}
public static function findIdentity($id)
{
return self::findOne($id);
}
public static function findIdentityByAccessToken($token, $type = null)
{
}
public function getId()
{
return $this->user_id;
}
public function getAuthKey()
{
}
public function validateAuthKey($authKey)
{
}
}
Login Model:
class Login extends Model
{
public $user_email;
public $user_password;
public function rules()
{
return [
[['user_email', 'user_password'],'required'],
['user_email','email'],
['user_password','validatePassword']
];
}
public function validatePassword($attribute,$params)
{
if(!$this->hasErrors())
{
$user = $this->getUser();
if(!$user || !$user->validatePassword($this->user_password))
{
$this->addError($attribute, 'Пароль или пользователь введенны не верно');
}
}
}
public function getUser()
{
return User::findOne(['user_email'=>$this->user_email]);
}
}
?>
SiteController(only login function)
public function actionLogin()
{
if(!Yii::$app->user->isGuest)
{
return $this->goHome();
}
else {
$login_model = new Login();
return $this->render('login',['login_model'=>$login_model]);
}
}
Putting username and password is not enough you should also perform a login
public function actionLogin()
{
if(!Yii::$app->user->isGuest)
{
return $this->goHome();
}
if ($model->load(Yii::$app->getRequest()->post())) {
// you should perform login
\Yii::$app->getUser()->login($model->user, $this->rememberMe ? $model->module->rememberFor : 0);
return $this->goBack();
}
else {
$login_model = new Login();
return $this->render('login',['login_model'=>$login_model]);
}
}
I am newbie in yii, I am making an website with yii framework. It is my first time in making USER LEVEL ACCESS. I've created a file EWebUser.php in protected/controllers/, this is my code `
protected function loadUser(){
if ($this->_model === null){
$this->_model= User::model()->findByPk($this->id);
}
return $this->_model;
}
function getLevel(){
$user = $this->loadUser();
if ($user)
return $user->status;
return '';
}
}
then I've also created function namely accessRules in AdminController. This my code
public function accessRules() {
return array(
array('allow',
'actions'=>array('index','delete','btnconf'),
'expression'=>'$user->getLevel()="supadmin"'
)
);
}
`
When I type http://localhost/coretankuyii/index.php/admin/index in URL while I login with user, admin or even has not login can still access it. My hope someone who can access that URL only someone who has status=supadmin. Do you can help me please?
Change the expression to "=="
public function accessRules() {
return array(
array('allow',
'actions'=>array('index','delete','btnconf'),
'expression'=>'$user->getLevel()=="supadmin"'
)
);
}
Or if this does not work try the below
public function accessRules() {
return array(
array('allow',
'actions'=>array('index','delete','btnconf'),
'expression'=>array('AdminController','getLevel');
)
);
}
public function getLevel(){
$user = $this->loadUser();
if($user->status=='supadmin')
return true;
else
return false;
}
I have a employee table which it contains emp_id,email,password and roles. I have given user and admin as a value for the field roles. I have also created webuser component which it extends CWebUser. This is my webuser code.
class WebUser extends CWebUser
{
public function checkAccess($operation, $params=array())
{
if (empty($this->id)) {
// Not identified => no rights
return false;
}
$role = $this->getState("roles");
if ($role === 'admin') {
return true; // admin role has access to everything
}
return ($operation === $role);
}
}
This is my UserIdentity code.
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$user= Employee::model()->find('LOWER(email)=?',array(strtolower($this->username)));
if($user===null)
$this->errorCode=self::ERROR_USERNAME_INVALID;
else if(!$user->validatePassword($this->password))
$this->errorCode=self::ERROR_PASSWORD_INVALID;
else
{
$this->_id=$user->emp_id;
$this->setState('roles',$user->roles);
$this->username=$user->email;
$this->errorCode=self::ERROR_NONE;
}
return $this->errorCode==self::ERROR_NONE;
}
}
This is my controller code.
public function accessRules()
{
return array(
array('allow', // allow all users to perform 'index' and 'view' actions
'actions'=>array('index','view'),
'users'=>array('*'),
),
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions'=>array('create'),
'users'=>array('#'),
),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','update','delete'),
'roles'=>array('admin'),
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}
It seems everything is fine. But when i try to update then it is not working and i have tried this for a person who have a admin value for the roles. Please correct me if am wrong.
I think problem is in checkAccess - you need to access a model Employee
class WebUser extends CWebUser
{
private $_model = null;
public function getModel(){
if (!$this->isGuest && $this->_model === null) {
$this->_model = Employee::model()->findByPk($this->id);
}
return $this->_model;
}
public function checkAccess($operation, $params=array()){
return $this->model->roles == 'admin';
}
}
If your app will not be compicated this should work.
But better use PhpAuthManager (or DbVersion) with full RBAC support
Here is my authentication controller
class AuthController extends Controller
{
public function actionLogin()
{
$model = new LoginForm;
$post = Yii::app()->request->getPost('LoginForm');
// If form is submitted
if($post) {
$identity = new UserIdentity($post['username'], $post['password']);
if($identity->authenticate()) { // loop enters but could not get id
echo Yii::app()->user->id;
echo Yii::app()->user->getId();
} else {
echo 'failed';
}
//exit;
}
$this->render('login', array('model' => $model));
}
}
Here is my UserIdentity.php
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$user = SchLogins::model()->findByAttributes(array('username' => $this->username));
if(is_null($user)) {
$this->errorCode=self::ERROR_USERNAME_INVALID;
} else if($user->password != $this->password) {
$this->errorCode=self::ERROR_PASSWORD_INVALID;
} else {
$this->_id = $user->id;
$this->errorCode=self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId()
{
return $this->_id;
}
}
In the above code I am having problem in getting user id (i.e) Yii::app()->user->getId(); this returns nothing and what wrong I did the above code
You are creating a LoginForm instance $model but you never use it to actually login. If you are using the standard LoginForm model then it is what interacts with the UserIdentity class. It should be this:
if($post) {
$model->attributes = $_POST['LoginForm'];
if ($model->validate() && $model->login()) { // loop enters but could not get id
echo Yii::app()->user->id;
echo Yii::app()->user->getId();
} else {
echo 'failed';
}
//exit;
}
If you look at the login() function of LoginForm you will see it calls Yii::app()->user->login($this->_identity,$duration); which is what actually sets the Yii::app()->user which with your method was being skipped.
I started creating a difference between the authenticated users and guest user. But always when i identify the user and it get the login successfully, it still returns true when i make use Yii::app()->user->isGuest. Here is the code which i am using:
if (Yii::app()->user->isGuest){
echo 'Welcome back Guest';
} else {
echo 'Welcome back '.Yii::app()->user->name;
}
I always get the 'welcome back guest', whether i have logged in (successfully) or not. And if i have logged in again i got this message. and here is the User Identify code.
class UserIdentity extends CUserIdentity {
/**
* Authenticates a user.
*/
private $_id;
public function authenticate() {
$user = Users::model()->findByAttributes(array('username' => $this->username));
if ($user === null)
$this->errorCode = self::ERROR_USERNAME_INVALID;
else if ($user->password !== $this->password)
$this->errorCode = self::ERROR_PASSWORD_INVALID;
else {
$this->_id = $user->id;
$this->setState('title', $this->username);
$this->setState('id', $user->id);
$this->errorCode = self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId() {
return $this->_id;
}
}
Please help me to get rid of this problem.
You should fix LoginForm
/**
* Authenticates the password.
* This is the 'authenticate' validator as declared in rules().
*/
public function authenticate($attribute, $params)
{
// we only want to authenticate when no input errors
if (! $this->hasErrors()) {
$identity = new UserIdentity($this->email, $this->password);
$identity->authenticate();
switch ($identity->errorCode) {
case UserIdentity::ERROR_NONE:
$duration = ($this->rememberMe)
? 3600*24*14 // 14 days
: 0; // login till the user closes the browser
Yii::app()->user->login($identity, $duration);
break;
default:
// UserIdentity::ERROR_USERNAME_INVALID
// UserIdentity::ERROR_PASSWORD_INVALID
// UserIdentity::ERROR_MEMBER_NOT_APPOVED
$this->addError('', Yii::t('auth',
'Incorrect username/password combination.'));
break;
}
}
}
class UsersController extends Controller
{
/**
* Displays the login page
*/
public function actionLogin()
{
$model = new LoginForm;
if (isset($_POST['LoginForm'])) {
$model->attributes = $_POST['LoginForm'];
$valid = $model->validate();
if ($valid) {
$this->redirect(Yii::app()->user->returnUrl);
}
}
$this->render('login', array('model' => $model));
}
}
Can you show your config?
Answer can be found here yii authentication error
You can also read more on yii authentication here authentication and authorisation
Try this and see using Not(!) operator
if (!Yii::app()->user->isGuest){
echo 'Welcome back Guest';
} else {
echo 'Welcome back '.Yii::app()->user->name;
}
You should NOT do this :
$this->setState('id', $user[0]->id);
setState should not be used for the 'id'. For returning the 'id' you have already overridden the getId() method.
If you do need to set it, change it something like this :
$this->_id = $user[0]->id;
Hope this helped.
Regards,