Yii Framework 2.0 Login With User Database
You can implement database user management using extesions like https://github.com/amnah/yii2-user.
OR
If you want to write your own custom script to manage the users you can override Yii2 identityClass.
In the component section of your config add:
'user' => [
'identityClass' => 'app\models\User',
'enableAutoLogin' => true,
],
Please note that your user model MUST IMPLEMENT \yii\web\IdentityInterfaceHere is the example of the model class that you can use to implement database authentication
namespace app\models;
//app\models\gii\Users is the model generated using Gii from users table
use app\models\gii\Users as DbUser;
class User extends \yii\base\Object implements \yii\web\IdentityInterface {
public $id;
public $username;
public $password;
public $authKey;
public $accessToken;
public $email;
public $phone_number;
public $user_type;
/**
* @inheritdoc
*/
public static function findIdentity($id) {
$dbUser = DbUser::find()
->where([
"id" => $id
])
->one();
if (!count($dbUser)) {
return null;
}
return new static($dbUser);
}
/**
* @inheritdoc
*/
public static function findIdentityByAccessToken($token, $userType = null) {
$dbUser = DbUser::find()
->where(["accessToken" => $token])
->one();
if (!count($dbUser)) {
return null;
}
return new static($dbUser);
}
/**
* Finds user by username
*
* @param string $username
* @return static|null
*/
public static function findByUsername($username) {
$dbUser = DbUser::find()
->where([
"username" => $username
])
->one();
if (!count($dbUser)) {
return null;
}
return new static($dbUser);
}
/**
* @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;
}
}
I hope that would be helpful to you . Cheers :) Yii2 framework cannot login using a custom database
I answer my own question. I added the following code in the find
public static function findByUsername($username, $password)
{
$user = self::find()->where(['USR_USERNAME' => $username, 'USR_STATUS' => '1'])->one();
if (hash('sha256', $password) == $user->USR_PASSWORD)
{
return new static($user);
}
}
now this will validate if the password is matched with the database in sha256 encryption and then on my validatePassword method I revise it to simple always return true because, on the LoginForm, they always search for the username first then check for the password validation, so If username/password is wrong it will instantly validate the user doens't exist public static function validatePassword($password)
{
return true;
}
I find yii2 hard, very hard with the lack of documentation. Yii2 step-by-step guide on login from table in MySQL
Yii2 advanced app comes by default with a working example of the login part from the DB (I see the basic ones uses a static username and password). You do not have to install anything extra, just look at the code. Install the advanced app and take a look at the frontend.
In short SiteController uses LoginModel for validation then uses the login() of the LoginModel to login the User model to the User component.
If you do not want to use the User model, just create your own model and use that one. You do not want to use the default User component, just create your own. It is quite easy to do.
Edit:
mate, remove the public declarations of variables bellow.
class User extends ActiveRecord implements \yii\web\IdentityInterface
{
public $id;
public $username;
public $password;
public $authKey;
public $accessToken;
You are telling Yii to ignore what is in the database. custom login in yii2 framework
Yii Framework 2.0 Login With User Database , This link about custom login in Yii 2.0 framework solved my above question :)
Login from Different Databases Yii2
If you use that scenario, avoid using roles "@" in your accessControl. Roles "@" only applied to Yii::$app->user, so if you login with different component (such as Yii::$app->userPerusahaan->login()) it will not count as registered user with roles "@". Modified your siteController like this example.
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['index', 'login'],
'allow' => true,
'roles' => ['?'],
],
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['@'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
public function actionIndex()
{
if(Yii::$app->user->isGuest && Yii::$app->userPerusahaan->isGuest) return $this->redirect(['login']);
// ......
Connect Yii2 Login form to DB
You need to change in User.php
model (mainly three methods findIdentity
, findByUsername
, validatePassword
). Below link will surely help you to go through this.
Link 1, Link 2 and Link 3
<?php
namespace app\models;
use app\models\Users; // generated using Gii; user master table in db
class User extends \yii\base\Object implements \yii\web\IdentityInterface
{
public $id;
public $username;
public $password;
public $authKey;
public $accessToken;
/**
* @inheritdoc
*/
public static function findIdentity($id)
{
$user = Users::findOne(['id'=>$id]);
if(!$user)
{
return null;
}
else
{
$user_info =
[
'id' => $user->id,
'username' => $user->username,
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'email' => $user->email,
'image'=>$user->image,
// assign other attributes too if needed
];
return new static($user_info);
}
}
/**
* Finds user by username
*
* @param string $username
* @return static|null
*/
public static function findByUsername($username)
{
$user = Users::findOne(['id'=>$id]);
if(!$user)
{
return null;
}
else
{
$user_info =
[
'id' => $user->id,
'username' => $user->username,
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'email' => $user->email,
'image'=>$user->image,
// assign other attributes, too if needed
];
return new static($user_info);
}
return null;
}
/**
* 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; // apply any encryption algo here to $password, if you have used any
}
// ...
// ... other functions here
}
Yii2 Login with database
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 classnamespace 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.
Related Topics
Send Zip File to Browser/Force Direct Download
Jquery:: Ajax Powered Progress Bar
How to Retrieve Date from Table Cell Using PHPspreadsheet
Combining And/Or Eloquent Query in Laravel
Ssl Alternative - Encrypt Password with JavaScript Submit to PHP to Decrypt
Determine If User Is Using Proxy
Docx File Type in PHP Finfo_File Is Application/Zip
How to Connect an Oracle Database from PHP
PHP Sort a Multidimensional Array by Number of Items
MySQL Insert ....On Duplicate Update - Adds One to the Autoincrement
Storing Leading Zeros of Integers in MySQL Database as Integer
Zend Framework - Multiplate Navigation Blocks