Yii2 AccessControl - php

I am new in Yii2 and I try to make AccessControl and success
but the problem is after I success for login and redirect to other page
my Identity _attributes always are null.So if I check with Yii::$app->user->isGuest the return value is always true
this is my LoginHandler.php
<?php
namespace app\models;
use Yii;
use yii\base\Model;
/**
* Login form
*/
class LoginHandler extends Model
{
public $user_name;
public $user_password;
public $rememberMe = true;
private $_user;
/**
* #inheritdoc
*/
public function rules()
{
return [
[['user_name', 'user_password'], 'required'],
[['user_name', 'user_password'], 'string', 'max' => 100],
['user_password','authenticate'],
];
}
public function authenticate($attribute, $params){
// return true;
}
public function login()
{
if ($this->validate()) {
return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);
} else {
return false;
}
}
protected function getUser()
{
if ($this->_user === null) {
$this->_user = User::findByUsername($this->user_name);
}
return $this->_user;
}
}
LoginController
<?php
namespace backend\controllers;
use Yii;
use app\models\user;
use app\models\LoginHandler;
class LoginController extends \yii\web\Controller
{
public function actionIndex()
{
return $this->render('index');
}
public function actionSignin(){
$user = User::findByUsername('admin');
$model = new LoginHandler();
if(Yii::$app->request->post()){
$data = Yii::$app->request->post();
$model->attributes = $data;
if ($model->login()) {
return $this->redirect(['/user/test']);
}else{
die('test');
}
}
return $this->render('login');
}
}
My User.php as model
namespace app\models;
use Yii;
/**
* This is the model class for table "user".
*
* #property integer $user_id
* #property string $user_name
* #property string $user_password
*/
class User extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface{
public $id;
public $authKey;
/**
* #inheritdoc
*/
public static function tableName()
{
return 'user';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['user_name', 'user_password'], 'required'],
[['user_name', 'user_password'], 'string', 'max' => 100]
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'user_id' => 'User ID',
'user_name' => 'User Name',
'user_password' => 'User Password',
];
}
public static function findIdentity($id)
{
return static::findOne($id);
}
public static function findIdentityByAccessToken($token, $type = null)
{
return static::findOne(['access_token' => $token]);
}
public function getId()
{
return $this->id;
}
public function getAuthKey()
{
return $this->authKey;
}
public function validateAuthKey($authKey)
{
return $this->authKey === $authKey;
}
public static function findByUsername($username){
return static::findOne(['user_name' => $username]);
}
}
and the last is my configuration main.php
<?php
$params = array_merge(
require(__DIR__ . '/../../common/config/params.php'),
require(__DIR__ . '/../../common/config/params-local.php'),
require(__DIR__ . '/params.php'),
require(__DIR__ . '/params-local.php')
);
return [
'id' => 'app-backend',
'basePath' => dirname(__DIR__),
'controllerNamespace' => 'backend\controllers',
'bootstrap' => ['log'],
'modules' => [],
'components' => [
'user' => [
'identityClass' => 'backend\models\User',
'loginUrl' => ['login/signin'],
'enableAutoLogin' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'errorHandler' => [
'errorAction' => 'site/error',
],
],
'params' => $params,
];
Thanks in advance.

You mentioned AccessControl in your question. In Yii2 AccessControl is the special behavior class to manage access rules inside controller:
http://www.yiiframework.com/doc-2.0/yii-filters-accesscontrol.html
and I don't see AccessControl in you code.
Anyway.
Most probably the problem is in your implementation of User class.
Looking at your code I can imagine that the table structure is: user_id (PK), user_name, user_password.
If so, then the method getId() returns variable
($this->id) which is never initialized. But this method is used by Yii to store current user in session. In your case it should return $this->user_id.
And if you wish to make remember me working, you should implement correctly getAuthKey and validateAuthKey too.
Here is details:
http://www.yiiframework.com/doc-2.0/guide-security-authentication.html
If this not helps, then show your table structure and code of view which pass authentication data to LoginController

It looks you should check for
Yii::$app->user->identity

Related

How do I solve Unknown database error in Yii2?

My Friend Suggested me to use Yii2 Framework And sent me all the files of a project he has worked upon, including the .sql file which he exported from phpmyadmin. I am trying to edit the same project (with his permission). After importing the .sql file i changed the database name username and password in \config\db.php and got this error
Database Exception – yii\db\Exception
SQLSTATE[HY000] [1049] Unknown database 'mydb'
Here is my db.php :
<?php
return [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=mydb',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
];
Then I Downloaded basic Yii2 application from official Yii Site (which works working fine), then i replaced \controllers\SiteController.php from the directory of the project that my friend sent me with the one i downloaded. To my Surprise the error was gone but it still looked like same as the one i downloaded (The one my friend sent was a educational school website, so it is supposed to look the same).
Here is SiteController.php of the one that my friend sent me
<?php
namespace app\controllers;
use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\web\Response;
use yii\filters\VerbFilter;
use app\models\LoginForm;
use app\models\User;
use app\models\ContactForm;
use app\modules\admin\models\AdmissionEnquiryForm;
use app\models\Article;
use app\models\ArticleSearch;
use app\modules\admin\models\SidebarModule;
use app\modules\admin\models\SidebarModuleSearch;
use app\modules\admin\models\Gallery;
use app\modules\admin\models\Activities;
use app\modules\admin\models\Newsletter;
use app\modules\admin\models\VisitorCounter;
class SiteController extends Controller
{
/**
* {#inheritdoc}
*/
public $enableCsrfValidation = false;
public function behaviors() {
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout', 'change-password'],
//'except' =>['login'],
'rules' => [
[
'actions' => ['logout', 'change-password'],
'allow' => true,
'roles' => ['#'],
],
],
],
];
}
/**
* {#inheritdoc}
*/
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
];
}
/**
* Displays homepage.
*
* #return string
*/
/*
public function actionIndex()
{
$model = Article::find()->where(['id' => 1])->one();
return $this->render('index').
$this->renderPartial('//article/overview', [
'model' => $this->findModel(1),
]);
}
public function actionIndex()
{
$this->layout='articles';
return $this->render('index', [
'model' => $this->findModel(1),
]);
}
*/
public function actionIndex()
{
$this->layout='home';
$sidebar=new SidebarModule;
$newsletter= new Newsletter;
/*$counter=new VisitorCounter;
$counter->counter=+1;
$counter->save();
$visits=VisitorCounter::find()->max('id');
$visits->counter=+1;
$visits->save();
//var_dump($visits);
*/
$visits=VisitorCounter::find()->where(['id'=>1])->One();
$visits->counter=$visits->counter+1;
$visits->save();
$this->view->params['newsletter'] = $newsletter;
// var_dump($_POST);
if ($newsletter->load(Yii::$app->request->post()) && $newsletter->save()) {
//Yii::$app->user->setFlash('success', "you are successfully subscribed to our Newsletter");
Yii::$app->session->setFlash('success', "you are successfully subscribed to our Newsletter");
// $newsletter->email=($_POST['email']);
}
return $this->render('index',['sidebar'=>$sidebar]);
}
/**
* Login action.
*
* #return Response|string
*/
/*
public function actionLogin()
{
if (!Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
return $this->goBack();
}
$model->password = '';
return $this->render('login', [
'model' => $model,
]);
}
*/
public function actionLogin() {
if (!Yii::$app->user->isGuest) {
return $this->goHome();
}
$this->layout = '#app/themes/backend/login';
$model = new LoginForm(['scenario' => 'login']);
if (Yii::$app->request->isAjax && $model->load($_POST)) {
Yii::$app->response->format = 'json';
return \yii\bootstrap\ActiveForm::validate($model);
}
if ($model->load(Yii::$app->request->post()) && $model->login()) {
return $this->redirect(Yii::$app->user->getReturnUrl());
}
return $this->render('login', [
'model' => $model,
]);
}
/**
* Logout action.
*
* #return Response
*/
public function actionLogout()
{
Yii::$app->user->logout();
return $this->goHome();
}
/**
* Displays contact page.
*
* #return Response|string
*/
public function actionContact()
{
$model = new ContactForm();
$model->subject = "Enquiry from website";
if ($model->load(Yii::$app->request->post()) && $model->contact(Yii::$app->params['adminEmail'])) {
Yii::$app->session->setFlash('contactFormSubmitted');
return $this->refresh();
}
//return $this->redirect(Yii::$app->request->referrer);
return $this->render('contact', ['model' => $model]);
}
public function actionAdmissionEnquiryForm()
{
$model = new AdmissionEnquiryForm();
$model->subject = "Enquiry for admission";
if ($model->load(Yii::$app->request->post()) && $model->admission(Yii::$app->params['adminEmail'])) {
Yii::$app->session->setFlash('AdmissionEnquiryFormSubmitted');
return $this->refresh();
}
//return $this->redirect(Yii::$app->request->referrer);
return $this->render('AdmissionEnquiryForm', ['model' => $model]);
}
public function actionChangePassword() {
$this->layout = '#app/themes/backend/main';
$userId = Yii::$app->user->identity->id;
$model = User::find()->where(['id' => $userId])->one();
$model->scenario = 'changeP';
if ($model->load(Yii::$app->request->post())) {
$oldpassword = $model->oldpassword;
$password = $model->password;
$hash = $model->password_hash;
$result = Yii::$app->getSecurity()->validatePassword($oldpassword, $hash);
$NewPassword = Yii::$app->getSecurity()->generatePasswordHash($password);
if ($result) {
$model->password_hash = $NewPassword;
$confirm = $model->save();
if ($confirm) {
Yii::$app->session->setFlash('passwordChanged');
$link = Yii::$app->urlManager->createAbsoluteUrl(['site/signin']);
return $this->refresh();
}
} else {
$model->addError('oldpassword', 'Incorrect old password.');
}
}
return $this->render('change-password',
['model' => $model]);
}
/**
* Displays about page.
*
* #return string
*/
public function actionAbout()
{
return $this->render('about');
}
protected function findModel($id)
{
if (($model = Article::findOne($id)) !== null) {
return $model;
}
throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.'));
}
public function actionGallery($id=null) {
$activities = Activities::find()->where(['status' => 1])->orderBy(['id'=>SORT_DESC])->all();
$model = Activities::find()->where(['id' => $id])->one();
// var_dump($model1);
$latestActivity = Activities::find()->max('id');
if($id==null){
$gallery = Gallery::find()->where(['status' => 'active','activity_name'=>$latestActivity])->all();
}else{
$gallery = Gallery::find()->where(['status' => 'active','activity_name'=>$id])->all();
}
return $this->render('gallery', ['gallery' => $gallery,'activities'=>$activities,'model'=>$model]);
}
}
And here is the SiteController.php of the one i downloaded
<?php
namespace app\controllers;
use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\web\Response;
use yii\filters\VerbFilter;
use app\models\LoginForm;
use app\models\ContactForm;
class SiteController extends Controller
{
/**
* {#inheritdoc}
*/
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout'],
'rules' => [
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
/**
* {#inheritdoc}
*/
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
];
}
/**
* Displays homepage.
*
* #return string
*/
public function actionIndex()
{
return $this->render('index');
}
/**
* Login action.
*
* #return Response|string
*/
public function actionLogin()
{
if (!Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
return $this->goBack();
}
$model->password = '';
return $this->render('login', [
'model' => $model,
]);
}
/**
* Logout action.
*
* #return Response
*/
public function actionLogout()
{
Yii::$app->user->logout();
return $this->goHome();
}
/**
* Displays contact page.
*
* #return Response|string
*/
public function actionContact()
{
$model = new ContactForm();
if ($model->load(Yii::$app->request->post()) && $model->contact(Yii::$app->params['adminEmail'])) {
Yii::$app->session->setFlash('contactFormSubmitted');
return $this->refresh();
}
return $this->render('contact', [
'model' => $model,
]);
}
/**
* Displays about page.
*
* #return string
*/
public function actionAbout()
{
return $this->render('about');
}
}
Note : The Files he sent me are of Sailor theme of Yii2.
How do solve the database not found error? Also please help me understand how replacing config.php from basic yii2 application (which I downloaded) with the one which is already there isn't showing error. Thanks in Advance.
Strictly speaking, the error is because in db.php have you specified the database name mydb, but that database doesn't exist (or, perhaps you don't have permission on it, although that's unlikely since you're using the root user).
Are you certain the database exists on your local database instance? Does your user (root) have the correct permissions to see and access the database?
Most likely this is the problem, either the database is called something else or doesn't exist at all, so you should either create the database on your local system or change the name db.php is looking for.

Yii2 rest api with bearer auth

I created the api structure/config and it works but now i need to set it up with bearer authentication and every GET request i send to the api (with Authentication Bearer XXXXXXXXXXXX) gives me a 401 error:
{"name":"Unauthorized","message":"Your request was made with invalid credentials.","code":0,"status":401,"type":"yii\\web\\UnauthorizedHttpException"}
Sorry about the length of this question with all snippets but i tried several changes, read all what i found here about this with no success and im starting to lose control on this. What could i be missing?
My app uses the advanced template with the next folder structure (the same as in all howtos ive read):
> -api
> --config
> --main.php
> --params.php
> --modules
> --v1
> --controllers
> --OrdersController.php
> --models
> --Orders.php
> --Module.php
> --web
> --index.php
> -backend
> -common
> -frontend...
api/config/main.php
<?php
$params = array_merge(
require(__DIR__ . '/../../common/config/params.php'),
require(__DIR__ . '/../../common/config/params-local.php'),
require(__DIR__ . '/params.php')
//require(__DIR__ . '/params-local.php')
);
return [
'id' => 'app-api',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'modules' => [
'v1' => [
'basePath' => '#app/modules/v1',
'class' => 'api\modules\v1\Module'
]
],
'components' => [
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => false,
'enableSession' => false,
'loginUrl' =>'',
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'v1/countries',
'tokens' => [
'{id}' => '<id:\\w+>'
]
],
[
'class' => 'yii\rest\UrlRule',
'controller' => 'v1/orders',
'tokens' => [
'{id}' => '<id:\\w+>'
]
]
],
]
],
'params' => $params,
];
api/config/params.php
<?php
return [
'adminEmail' => 'admin#domain.com',
];
api/modules/v1/Module.php
<?php
namespace api\modules\v1;
class Module extends \yii\base\Module
{
public $controllerNamespace = 'api\modules\v1\controllers';
public function init()
{
parent::init();
\Yii::$app->user->enableSession = false;
}
}
api/modules/v1/controllers/OrdersController.php
<?php
namespace api\modules\v1\controllers;
use yii\rest\ActiveController;
use yii\web\Response;
use yii\filters\auth\CompositeAuth;
use yii\filters\auth\HttpBasicAuth;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\auth\QueryParamAuth;
class OrdersController extends ActiveController
{
public $modelClass = 'api\modules\v1\models\Orders';
public function actions() // Just read only rest api
{
$actions = parent::actions();
unset($actions['delete'], $actions['create'], $actions['update']);
return $actions;
}
public function behaviors() {
$behaviors = parent::behaviors();
$behaviors['contentNegotiator']['formats']['text/html'] = Response::FORMAT_JSON;
$behaviors['authenticator'] = [
//'class' => HttpBasicAuth::className(),
'class' => HttpBearerAuth::className(),
//'class' => QueryParamAuth::className(),
];
return $behaviors;
}
}
common/models/User.php
<?php
namespace common\models;
use Yii;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
/**
* User model
*
* #property integer $id
* #property string $username
* #property string $password_hash
* #property string $password_reset_token
* #property string $email
* #property string $auth_key
* #property integer $status
* #property integer $created_at
* #property integer $updated_at
* #property string $password write-only password
*/
class User extends ActiveRecord implements IdentityInterface
{
const STATUS_DELETED = 0;
const STATUS_ACTIVE = 10;
/**
* #inheritdoc
*/
public static function tableName()
{
return '{{%user}}';
}
/**
* #inheritdoc
*/
public function behaviors()
{
return [
TimestampBehavior::className(),
];
}
/**
* #inheritdoc
*/
public function rules()
{
return [
['status', 'default', 'value' => self::STATUS_ACTIVE],
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],
];
}
/**
* #inheritdoc
*/
public static function findIdentity($id)
{
return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
}
/**
* #inheritdoc
*/
public static function findIdentityByAccessToken($token, $type = null)
{
//throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
return static::findOne(['auth_key' => $token]);
}
/**
* Finds user by username
*
* #param string $username
* #return static|null
*/
public static function findByUsername($username)
{
return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
}
/**
* Finds user by password reset token
*
* #param string $token password reset token
* #return static|null
*/
public static function findByPasswordResetToken($token)
{
if (!static::isPasswordResetTokenValid($token)) {
return null;
}
return static::findOne([
'password_reset_token' => $token,
'status' => self::STATUS_ACTIVE,
]);
}
/**
* Finds out if password reset token is valid
*
* #param string $token password reset token
* #return boolean
*/
public static function isPasswordResetTokenValid($token)
{
if (empty($token)) {
return false;
}
$timestamp = (int) substr($token, strrpos($token, '_') + 1);
$expire = Yii::$app->params['user.passwordResetTokenExpire'];
return $timestamp + $expire >= time();
}
/**
* #inheritdoc
*/
public function getId()
{
return $this->getPrimaryKey();
}
/**
* #inheritdoc
*/
public function getAuthKey()
{
return $this->auth_key;
}
/**
* #inheritdoc
*/
public function validateAuthKey($authKey)
{
return $this->getAuthKey() === $authKey;
}
/**
* Validates password
*
* #param string $password password to validate
* #return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
return Yii::$app->security->validatePassword($password, $this->password_hash);
}
/**
* Generates password hash from password and sets it to the model
*
* #param string $password
*/
public function setPassword($password)
{
$this->password_hash = Yii::$app->security->generatePasswordHash($password);
}
/**
* Generates "remember me" authentication key
*/
public function generateAuthKey()
{
$this->auth_key = Yii::$app->security->generateRandomString();
}
/**
* Generates new password reset token
*/
public function generatePasswordResetToken()
{
$this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
}
/**
* Removes password reset token
*/
public function removePasswordResetToken()
{
$this->password_reset_token = null;
}
}
Thank you in advance,
After checking this question i was able to find what was happening. Just added
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
to api/web/.htaccess and it works
Is this the best approach?

YII2 REST Identity Interface returns all users?

I have a REST API endpoint that i use to get a user logged in and retrieve informations about his account.
That implementation was running fine...but now it's broken.
I am using basicauth override to use USERNAME:PASSWORD instead of the token
Below controller and MODEL code
Into the response i find now all the users...instead of one
can't understand as in the first place we use findOne to select ONE user and THEN password is checked.
Maybe i missed something here :/
USER MODEL :
<?php
namespace common\models;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
class User extends ActiveRecord implements IdentityInterface
{
public static function tableName()
{
return '{{%user}}';
}
public function behaviors()
{
return [
TimestampBehavior::className(),
];
}
public function rules()
{
return [
[['username', 'auth_key', 'password_hash', 'email'], 'required'],
[['status', 'created_at', 'updated_at', 'background'], 'integer'],
[['username', 'password_hash', 'password_reset_token', 'email', 'hmac_shopify', 'shop_address', 'room_id', 'wp_address', 'blog_address', 'iosRegisterID', 'androidRegisterID', 'timeZone'], 'string', 'max' => 255],
[['auth_key'], 'string', 'max' => 32],
[['account_level'], 'string', 'max' => 45],
[['username'], 'unique'],
[['email'], 'unique'],
[['password_reset_token'], 'unique'],
];
}
public static function findIdentity($id)
{
return static::findOne(['id' => $id]);
}
public static function findIdentityByAccessToken($token, $type = null)
{
return static::findOne(['auth_key' => $token]);
}
public static function findByUsername($username)
{
return static::findOne(['username' => $username]);
}
public static function findByPasswordResetToken($token)
{
if (!static::isPasswordResetTokenValid($token)) {
return null;
}
return static::findOne([
'password_reset_token' => $token,
'status' => self::STATUS_ACTIVE,
]);
}
public static function isPasswordResetTokenValid($token)
{
if (empty($token)) {
return false;
}
$timestamp = (int) substr($token, strrpos($token, '_') + 1);
$expire = Yii::$app->params['user.passwordResetTokenExpire'];
return $timestamp + $expire >= time();
}
public function getId()
{
return $this->getPrimaryKey();
}
public function getAuthKey()
{
return $this->auth_key;
return $this->hmac_shopify;
}
public function validateAuthKey($authKey)
{
return $this->getAuthKey() === $authKey;
}
public function validatePassword($password)
{
return Yii::$app->security->validatePassword($password, $this->password_hash);
}
public function setPassword($password)
{
$this->password_hash = Yii::$app->security->generatePasswordHash($password);
}
public function generateAuthKey()
{
$this->auth_key = Yii::$app->security->generateRandomString();
$this->room_id = "_r_".Yii::$app->security->generateRandomString();
}
public function generatePasswordResetToken()
{
$this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
}
public function removePasswordResetToken()
{
$this->password_reset_token = null;
}
public static function find()
{
return new UserQuery(get_called_class());
}
}
This is controller :
<?php
namespace api\controllers;
use yii;
use yii\rest\ActiveController;
use \common\models\User;
class RestController extends ActiveController
{
public $modelClass = '\common\models\User';
public $password_hash;
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['verbs'] = [
'class' => \yii\filters\VerbFilter::className(),
'actions' => [
'index' => ['get', 'head'],
],
];
$behaviors['access'] = [
'class' => \yii\filters\AccessControl::className(),
'only' => ['index'],
'rules' => [
[
'actions' => ['index'],
'allow' => true,
'roles' => ['#'],
],
],
];
$behaviors['authenticator'] = [
'class' => \yii\filters\auth\HttpBasicAuth::className(),
'auth' => function ($username, $password) {
$user = \common\models\User::findByUsername($username);
if ($user ) {
$password_valid = \common\models\User::validatePassword($password,$user->password_hash);
if($password_valid)
return $user;
}
}
];
return $behaviors;
}
}
Data response from REST AUTH
<pre>
<response>
<item>...</item>
<item>...</item>
<item>...</item>
<item>...</item>
<item>...</item>
<item>...</item>
<item>...</item>
</response>
</pre>
That was def. the default behavior, i had to edit the prepareDataProvider function in in \yii2\rest\indexAction.php

How to call a method from model in YII 2 framework?

I am newbie in YII framework. I have installed correctly and created a Test Controller & Test Model using GII extension of YII. I have created a method in Model and want to access in Controller but unable to access.
Test controller
<?php
namespace app\controllers\api;
use Yii;
use app\models\api\Test;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
class TestController extends \yii\web\Controller
{
public $modelClass = 'app\models\api\Test';
private $model;
public function filters(){
return array(
'accessControl', // perform access control for CRUD operations
array(
'RestfullYii.filters.ERestFilter +
REST.GET, REST.PUT, REST.POST, REST.DELETE, REST.OPTIONS'
),
);
}
public function actions(){
return array(
'REST.'=>'RestfullYii.actions.ERestActionProvider',
);
}
public function accessRules(){
return array(
array('allow', 'actions'=>array('REST.GET', 'REST.PUT', 'REST.POST', 'REST.DELETE', 'REST.OPTIONS'),
'users'=>array('*'),
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}
protected function loadModel( $id = null )
{
if($this->model===null)
{
if($id!==null)
$this->model=TestModel::model()->findByPk($id);
}
return $this->model;
}
public function actionIndex()
{
//return $this->render('index');
//$array = $modelClass::model()->listUserData();
//$array = Yii::app()->model()->listUserData();
//$array = $modelClass->listUserData();
// echo TestModel()->listUserData();
print "<pre>";print_r($this->model->listUserData());
exit;
}
}
Test Model
<?php
namespace app\models\api;
use Yii;
/**
* This is the model class for table "users".
*
* #property integer $id
* #property string $username
* #property string $password
* #property string $email
* #property string $activkey
* #property integer $createtime
* #property integer $lastvisit
* #property integer $superuser
* #property integer $status
*/
class Test extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'users';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['username', 'password', 'email'], 'required'],
[['createtime', 'lastvisit', 'superuser', 'status'], 'integer'],
[['username'], 'string', 'max' => 50],
[['password', 'email', 'activkey'], 'string', 'max' => 128],
[['username'], 'unique'],
[['email'], 'unique'],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'username' => 'Username',
'password' => 'Password',
'email' => 'Email',
'activkey' => 'Activkey',
'createtime' => 'Createtime',
'lastvisit' => 'Lastvisit',
'superuser' => 'Superuser',
'status' => 'Status',
];
}
public static function listUserData(){
$UserData = Test::model()->findAll('status = "0"');
return $UserData;
}
}
i tried to search on forum but not able to resolve, please can you help me to resolve ?
Thanks in advance.
In the controller.
use pathtotestmodel/Test
public function actionIndex()
{
$model = new Test();
$userdata = $model->listUserData();
}
OR
public function actionIndex()
{
$userdata = Test::listUserData();
}
Its simple create a instance of Model and then call the required function
like
public function actionIndex()
{
$model = new Test();
print "<pre>";print_r($model->listUserData());
exit;
}
Try this
public static function listUserData(){
$UserData = Test::findAll(['status' =>0]);//in Yii2
//$UserData = Test::model()->findByAttributes(array( 'status' => 0 )); in yii 1.1
return $UserData;
}

Yii2 Login with database

I have a table in my DB called 'member' where I intend to store username, password and all other related info of a user and I want to use those username/password for login instead yii2's default User.php model. I have been trying for almost a day and modified the Member.php model but can't make it work. Every time I use my custom username/password from db, it says username or password is incorrect.
Can anyone please help me out? Thanks in advance. :)
FYI, I have no such field in member table such as authKey or accessToken. I have tried all the related stackoverflow posts but in vein.
Member.php Model
namespace app\models;
use Yii;
use yii\web\IdentityInterface;
class Member extends \yii\db\ActiveRecord implements IdentityInterface
{
public static function tableName()
{
return 'member';
}
public function rules()
{
return [
[['username', 'password', 'first_name', 'last_name', 'role'], 'required'],
[['created_by_date', 'last_modified_by_date'], 'safe'],
[['username', 'password', 'role', 'created_by_id', 'last_modified_by_id'], 'string', 'max' => 50],
[['first_name', 'last_name', 'middle_name', 'phone', 'mobile'], 'string', 'max' => 100],
[['email'], 'string', 'max' => 250],
[['address_line1', 'address_line2', 'address_line3'], 'string', 'max' => 512]
];
}
public function attributeLabels()
{
return [
'id' => 'ID',
'username' => 'Username',
'password' => 'Password',
'first_name' => 'First Name',
'last_name' => 'Last Name',
'middle_name' => 'Middle Name',
'email' => 'Email',
'phone' => 'Phone',
'mobile' => 'Mobile',
'address_line1' => 'Address Line1',
'address_line2' => 'Address Line2',
'address_line3' => 'Address Line3',
'role' => 'Role',
'created_by_id' => 'Created By ID',
'created_by_date' => 'Created By Date',
'last_modified_by_id' => 'Last Modified By ID',
'last_modified_by_date' => 'Last Modified By Date',
];
}
public static function find()
{
return new MemberQuery(get_called_class());
}
public static function findIdentity($id)
{
$dbUser = self::find()
->where([
"id" => $id
])
->one();
if (!count($dbUser)) {
return null;
}
return new static($dbUser);
}
public static function findIdentityByAccessToken($token, $userType = null)
{
$dbUser = self::find()
->where(["accessToken" => $token])
->one();
if (!count($dbUser)) {
return null;
}
return new static($dbUser);
}
public static function findByUsername($username)
{
$dbUser = self::find()
->where(["username" => $username])
->one();
if (!count($dbUser)) {
return null;
}
return $dbUser;
}
public function getId()
{
return $this->id;
}
public function getAuthKey()
{
return $this->authKey;
}
public function validateAuthKey($authKey)
{
return $this->authKey === $authKey;
}
/**
* Validates password
*
* #param string $password password to validate
* #return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
return $this->password === $password;
}
}
config/web.php
'user' => [
'identityClass' => 'app\models\Member',
'enableAutoLogin' => true,
],
I didnt change the User.php model. Here it is:
namespace app\models;
class User extends \yii\base\Object implements \yii\web\IdentityInterface
{
private static $users = [
'100' => [
'id' => '100',
'username' => 'admin',
'password' => 'admin',
'authKey' => 'test100key',
'accessToken' => '100-token',
],
'101' => [
'id' => '101',
'username' => 'demo',
'password' => 'demo',
'authKey' => 'test101key',
'accessToken' => '101-token',
],
];
/**
* #inheritdoc
*/
public static function findIdentity($id)
{
return isset(self::$users[$id]) ? new static(self::$users[$id]) : null;
}
/**
* #inheritdoc
*/
public static function findIdentityByAccessToken($token, $type = null)
{
foreach (self::$users as $user) {
if ($user['accessToken'] === $token) {
return new static($user);
}
}
return null;
}
/**
* Finds user by username
*
* #param string $username
* #return static|null
*/
public static function findByUsername($username)
{
foreach (self::$users as $user) {
if (strcasecmp($user['username'], $username) === 0) {
return new static($user);
}
}
return null;
}
/**
* #inheritdoc
*/
public function getId()
{
return $this->id;
}
/**
* #inheritdoc
*/
public function getAuthKey()
{
return $this->authKey;
}
/**
* #inheritdoc
*/
public function validateAuthKey($authKey)
{
return $this->authKey === $authKey;
}
/**
* Validates password
*
* #param string $password password to validate
* #return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
return $this->password === $password;
}
}
You should make sure you change the getUser() method on models/LoginForm.php to use your Member model class, otherwise it will keep validating against the default User model.
public function getUser() {
if ($this->_user === false) {
$this->_user = Member::findByUsername($this->username);
}
return $this->_user;
}
Also, here is an example of my own User model class
namespace app\models;
use Yii;
class User extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface {
const SCENARIO_LOGIN = 'login';
const SCENARIO_CREATE = 'create';
public static function tableName() {
return 'user';
}
public function scenarios() {
$scenarios = parent::scenarios();
$scenarios[self::SCENARIO_LOGIN] = ['username', 'password'];
$scenarios[self::SCENARIO_CREATE] = ['username', 'password', 'authKey'];
return $scenarios;
}
public function rules() {
return [
[['username', 'email'], 'string', 'max' => 45],
[['email'], 'email'],
[['password'], 'string', 'max' => 60],
[['authKey'], 'string', 'max' => 32],
[['username', 'password', 'email'], 'required', 'on' => self::SCENARIO_CREATE],
[['authKey'], 'default', 'on' => self::SCENARIO_CREATE, 'value' => Yii::$app->getSecurity()->generateRandomString()],
[['password'], 'filter', 'on' => self::SCENARIO_CREATE, 'filter' => function($value) {
return Yii::$app->getSecurity()->generatePasswordHash($value);
}],
[['username', 'password'], 'required', 'on' => self::SCENARIO_LOGIN],
[['username'], 'unique'],
[['email'], 'unique'],
[['authKey'], 'unique'],
];
}
public function attributeLabels() {
return [
'id' => 'Id',
'username' => 'Username',
'password' => 'Password',
'email' => 'Email',
'authKey' => 'authKey',
];
}
public static function findIdentity($id) {
return self::findOne($id);
}
public static function findIdentityByAccessToken($token, $type = null) {
throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}
public static function findByUsername($username) {
return static::findOne(['username' => $username]);
}
public function getId() {
return $this->getPrimaryKey();
}
public function getAuthKey() {
return $this->authKey;
}
public function validateAuthKey($authKey) {
return $this->authKey === $authKey;
}
public function validatePassword($password) {
return Yii::$app->getSecurity()->validatePassword($password, $this->password);
}
}
Make sure the methods from IdentityInterface you implement but don't want to use throw an exception, just like i do on the findIdentityByAccessToken method.
You should extend User class with your Member class and set in main config:
[...]
'modules' => [
'user' => [
'class' => 'member class
'modelMap' => [
'User' => 'app\models\member',
More info: yii 2 : override user model

Categories