Password strategies for Yii

Overview

Yii Password Strategies

Password strategies are specifications for how passwords should be encoded and verified and how complicated user supplied passwords should be. Out of the box it contains strategies for bcrypt and multiple rounds of hash functions e.g. sha1, as well as support for legacy password hashes like unsalted md5 and unsalted sha1. The aim is to allow multiple different password strategies to co-exist and to upgrade users from legacy hashes to new hashes when they login.

Instalation

Install compser (following instructions from https://getcomposer.org/) then run:

composer require phpnode/yiipassword

Why do I want this?

Imagine that you have a legacy application that uses simple, unsalted md5 based password hashing, which, in 2012 is considered completely insecure. You want to upgrade your password hashes, but you don't have access to the plain text passwords. In this scenario you can configure two password strategies, your old legacy one that uses md5, and your new shiney one that uses bcrypt. Then when users login to their accounts, their password will be verified using the legacy strategy, and if it matches, they will be seamlessly upgraded to the new bcrypt password strategy. For example:

array( "class" => "YiiPassword\Behavior", "defaultStrategyName" => "bcrypt", "strategies" => array( "bcrypt" => array( "class" => "YiiPassword\Strategies\Bcrypt", "workFactor" => 14 ), "legacy" => array( "class" => "YiiPassword\Strategies\LegacyMd5", ) ), ) ); } .... } $user = User::model()->findByPK(1); // a user using the legacy password strategy echo $user->password; // unsalted md5, horrible $user->verifyPassword("password"); // verifies the password using the legacy strategy, and rehashes based on bcrypt strategy echo $user->password; // now hashed with bcrpt">
class User extends CActiveRecord
{
	public function behaviors()
	{
		return array(
			"PasswordBehavior" => array(
				"class" => "YiiPassword\Behavior",
				"defaultStrategyName" => "bcrypt",
				"strategies" => array(
					"bcrypt" => array(
						"class" => "YiiPassword\Strategies\Bcrypt",
						"workFactor" => 14
					),
					"legacy" => array(
						"class" => "YiiPassword\Strategies\LegacyMd5",
					)
				),
			)
		);
	}

	....
}

$user = User::model()->findByPK(1); // a user using the legacy password strategy
echo $user->password; // unsalted md5, horrible
$user->verifyPassword("password"); // verifies the password using the legacy strategy, and rehashes based on bcrypt strategy
echo $user->password; // now hashed with bcrpt

But this is also useful for modern applications, let's say you have a new webapp and you're doing The Right Thing and using bcrypt for your password hashing. You start off with a work factor of 12, but after a few months you decide you'd like to increase it to 15. Normally this would be quite difficult to accomplish because of all the users who've already signed up using the less secure hashes, but with password strategies, you can simply add another bcrpyt strategy with the desired work factor, set it to the default, and your users will be upgraded to the new strategy next time they login.

By default, YiiPassword\Behavior assumes that your model contains the following fields:

* *salt* - holds the per user salt used for hashing passwords
* *username* - holds the username
* *password* - holds the hashed password
* *passwordStrategy* - holds the name of the current password strategy for this user
* *requiresNewPassword* - a boolean field that determines whether the user should change their password or not

You can configure the field names on the behavior.

Also info: Using Bcrypt Strategy For New Application? - #10

Comments
  • Using Bcrypt Strategy For New Application

    Using Bcrypt Strategy For New Application

    How to use Bcrypt strategy in new application?

    This extension is useful, but i didn't still use it. I open a topic on Stackoverflow: http://stackoverflow.com/questions/15714387/yiipassword-extension-usage

    I very tried any way, i want now you how to use this extension for your application? Mainly encode the user password and verify it at user-login.

    opened by msoa7 6
  • How about some tags

    How about some tags

    It would be nice if you'd tag your versions so that we can use this extension properly through Composer.

    I would also strongly suggest that you use Git flow to manage the versioning of the project. http://nvie.com/posts/a-successful-git-branching-model/

    opened by crisu83 5
  • PSR-0 Compliant / HTTP-Digest strategy

    PSR-0 Compliant / HTTP-Digest strategy

    • Adds support for PSR-0 (Enable PSR-0 autoloading)
    • Fixes useless test in ABcryptPasswordStrategy.php
    • Uses idiomatic markdown instead of HTML
    • Support for HTTP-Digest Strategy
    • Bug Fix an infinite loop during save
    opened by luxcem 5
  • Change casing to lowercase

    Change casing to lowercase

    I would like to suggest a change to the casing of the project name to yiipassword as Composer uses lowercase letters for project names. That's also the way GitHub prefers the projects to be named.

    Would this be possible?

    opened by crisu83 2
  • Why the inclusion of 'packages.passwordStrategy' ?

    Why the inclusion of 'packages.passwordStrategy' ?

    Hi there,

    I am making extensive use of your extension that I think is awesome but found a new line on your code at APasswordBehavior class:

    Yii::import("packages.passwordStrategy.*");
    

    IMHO there is no need for this inclusion and also it is not specified on the README file.

    opened by tonydspaniard 2
  • Alias

    Alias "packages.passwordStrategy.*" is invalid

    There was 1 error:

    1. ABcryptPasswordStrategyTest::testEncode CException: Alias "packages.passwordStrategy.*" is invalid. Make sure it points to an existing directory or file.

    C:\Apache2\htdocs\yii\framework\YiiBase.php:343 C:\Apache2\htdocs\x\protected\components\YiiPassword\APasswordBehavior.php:2 C:\Apache2\htdocs\yii\framework\YiiBase.php:423 C:\Apache2\htdocs\yii\framework\YiiBase.php:298 C:\Apache2\htdocs\yii\framework\YiiBase.php:198 C:\Apache2\htdocs\yii\framework\base\CComponent.php:327 C:\Apache2\htdocs\yii\framework\base\CComponent.php:298 C:\Apache2\htdocs\yii\framework\db\ar\CActiveRecord.php:389 C:\Apache2\htdocs\x\protected\models\User.php:28 C:\Apache2\htdocs\x\protected\tests\unit\ABcryptPasswordStrategyTest.php:22 C:\php\phpunit:46

    FAILURES! Tests: 1, Assertions: 2, Errors: 1.

    more: http://www.yiiframework.com/forum/index.php/topic/30077-yii-password-strategies/page__view__findpost__p__199149

    opened by msoa7 2
  •  save only password related/changed fields when changing password

    save only password related/changed fields when changing password

    by execution of changePassword will be good to save only related fields:

    --- APasswordBehavior.php   2012-12-09 18:03:26.000000000 +0200
    +++ APasswordBehavior.php.new   2012-12-09 18:06:35.000000000 +0200
    @@ -187,7 +187,7 @@
        {
            $owner = $this->getOwner(); /* @var CActiveRecord $owner */
            $this->changePasswordInternal($password);
    -       return $owner->save($runValidation);
    +       return $owner->save($runValidation, array($this->passwordAttribute, $this->saltAttribute, $this->strategyAttribute));
        }
     
        /**
    
    opened by mariroz 2
  • Update package on Packagist

    Update package on Packagist

    You will most likely need to re-configure the service hook for Packagist because you renamed the package. The package is currently not being updated so the version tags I pushed are not available through composer.

    Alternatively you can give me administration privileges so that I can fix this myself.

    opened by crisu83 1
  • Update Bcrypt.php

    Update Bcrypt.php

    Put "" in front of Yii to make sure the autoload takes it from the base name space rather than what define in the file.

    I used PHP 5.3.5. May be in other version of PHP doesn't have this problem? I'm not sure about this.

    opened by sitawit 1
  • How to verify password in model Rules

    How to verify password in model Rules

    I want change password, but befor i want verify current password that is correct. my controller is:

        public function actionCPass()
        {
            $model=$this->loadModel(Yii::app()->user->id);
            $model->scenario='CPass';
            $this->performAjaxValidation($model,'pass-form');
    
            if(isset($_POST['User']))
            {
                $model->attributes=$_POST['User'];
                $validate=$model->validate();
    
                if(!$validate and Yii::app()->request->isAjaxRequest)
                    $this->getErrorSummary($model);
    
                if($validate)
                if($model->changePassword($model->newPass))
                    if(Yii::app()->request->isAjaxRequest)
                        Yii::app()->end(CJSON::encode(array('status'=>'success')));
                    else
                        Yii::app()->user->setFlash('status','success');
            }
    
            if(Yii::app()->request->isAjaxRequest)
                $this->renderPartial('_cpass',array('model'=>$model),false,true);
            else
                $this->render('update',array('model'=>$model,'form'=>'_cpass'));
        }
    

    model is:

    <?php
    /**
     * This is the model class for table "tbl_user".
     *
     * The followings are the available columns in table 'tbl_user':
     * @property integer $id
     * @property string $username
     * @property string $password
     * @property string $email
     * @property string $salt
     * @property string $strategy
     */
    class User extends CActiveRecord
    {
    
        public $currentPass;
        public $newPass;
        public $newPass_repeat;
        /**
        ...
    
        public function behaviors()
        {
            return array(
                "APasswordBehavior" => array(
                    "class" => "APasswordBehavior",
                    "defaultStrategyName" => "bcrypt",
                    "strategies" => array(
                        "bcrypt" => array(
                            "class" => "ABcryptPasswordStrategy",
                            "workFactor" => 10,
                            'minLength' => 4,
                        ),
                    ),
                )
            );
        }
    
        public function rules()
        {
                return array(
                array('currentPass,newPass','required', 'on'=>'CPass', 'message'=>'Required'),
                array('newPass','length','min'=>4,'tooShort'=>'At last 4 char'),
                array('newPass', 'compare', 'on'=>'CPass', 'message'=>'Didn't match'),
                array('newPass_repeat', 'safe', 'on'=>'CPass'), 
                array('currentPass','verify_password', 'on'=>'CPass'),
            );
        }
    
    
        public function verify_password()
        {
            if(!$this->hasErrors())
                if($this->verifyPassword($this->currentPass)==false)
                    $this->addError('currentPass','current Password don't correct');
                else
                    $this->clearErrors('currentPass');
        }
    
    

    The problem is: public function verify_password() in model(Rules) runs twice. in fact validation runs twice, one in $model->validate() and other in $model->changePassword. My current temporally practice is: $model->changePassword($model->newPass,false). How can i verify password in model Rules?

    question 
    opened by msoa7 1
  • Verity password issue

    Verity password issue

    In verify password why do you use

    if (!$strategy->compare($password,$owner->{$this->passwordAttribute}))
    

    istead of

    if (!$strategy->compare($password, $this->_hashedPassword)
    

    This way I can't use same attribute for verification (on update for example when i need old password) like:

    if ($this->verifyPassword($this->password))
    
    opened by rinatio 1
  • breaking changes

    breaking changes

    Notice the breaking changes on the commit April 17th.

    Do you have a strategy for introducing breaking changes? How should someone use this lib without risking future breaks?

    opened by adamaltman 2
  • Improve password logic

    Improve password logic

    The way this behavior works now, you hand out the hashed password to the user during an update. If the password content equals the hashed content, the password is not changed.

    I don't particularly like the idea of sending pw hashes to the user. And it makes the behavior logic unneccessarly complex, as you have to save the original DB value in afterFind().

    I'd find it much better, if the behavior used a dedicated property for new passwords from forms:

    class X extends CActiveRecord
    {
        // Used in forms to let users enter a *new* password
        public $newPassword;
        //...
    }
    

    The DB column (e.g. password) is never exposed to the user, only newPassword is. You can think of it as a one-way road for new passwords into our DB. Only if newPassword is not empty, a new hashed password is written to password.

    This would simplify the behavior code quite a bit - and make it more transparent to the user, in case he wants to add additional validation to the newPassword column.

    enhancement 
    opened by mikehaertl 15
Owner
Charles Pick
Founder of @codemix where most of my open source projects live.
Charles Pick
Yii 2: The Fast, Secure and Professional PHP Framework

Yii 2 is a modern framework designed to be a solid foundation for your PHP application. It is fast, secure and efficient and works right out of the bo

Yii Software 14k Dec 31, 2022
Yii 2 Bootstrap 5 Extension

Twitter Bootstrap 5 Extension for Yii 2 This is the Twitter Bootstrap extension for Yii framework 2.0. It encapsulates Bootstrap 5 components and plug

Yii Software 48 Dec 14, 2022
Yii-specific middleware

Yii Middleware The package ... Requirements PHP 8.0 or higher. Installation The package could be installed with composer: composer require yiisoft/yii

Yii Software 9 Nov 4, 2022
Yii2-symfonymailer - Yii 2 Symfony mailer extension.

Yii Mailer Library - Symfony Mailer Extension This extension provides a Symfony Mailer mail solution for Yii framework 2.0. For license information ch

Yii Software 28 Dec 22, 2022
Yii 2 widget for the Froala WYSIWYG HTML Editor.

Yii Framework Froala WYSIWYG HTML Editor Yii 2 widget for Froala Wysiwyg editor. Installation The preferred way to install this extension is through c

Froala 99 Sep 21, 2022
Geography module for Yii 2

Geography module for Yii 2

Sergey Fedorov 13 Oct 20, 2018
Code generation with logic-less templates for Yii

Caviar Code generation with logic-less templates for Yii. Caviar vs Gii You might be wondering why you should use Caviar instead of Gii, so let us tak

Christoffer Niska 10 Dec 19, 2015
This extension provides a view renderer for Pug templates for Yii framework 2.0 applications.

This extension provides a view renderer for Pug templates for Yii framework 2.0 applications.

Revin Roman 9 Jun 17, 2022
Extends Yii Menu widget

Extends Yii Menu widget. This widget offers a scrollspy and affixed enhanced navigation (upto 2-levels) to highlight sections and secondary sections in each page.

Kartik Visweswaran 15 Mar 12, 2022
DepDrop widget is a Yii 2 wrapper for the dependent-dropdown jQuery plugin by Krajee.

yii2-widget-depdrop The DepDrop widget is a Yii 2 wrapper for the dependent-dropdown jQuery plugin by Krajee. This plugin allows multi level dependent

Kartik Visweswaran 82 Nov 27, 2022
An enhanced Yii 2 widget encapsulating the HTML 5 range input (sub repo split from yii2-widgets)

yii2-widget-rangeinput The RangeInput widget is a customized range slider control widget based on HTML5 range input. The widget enhances the default H

Kartik Visweswaran 19 Mar 12, 2022
Extension for creating and sending emails for the Yii PHP framework.

yii-emailer Extension for creating and sending emails for the Yii PHP framework. Usage Migrate the email_message database table by this command: yiic

Digia 12 Mar 30, 2022
This extension provides Flysystem integration for the Yii framework

This extension provides Flysystem integration for the Yii framework. Flysystem is a filesystem abstraction which allows you to easily swap out a local filesystem for a remote one.

Alexander Kochetov 276 Dec 9, 2022
A easy way to install your basic yii projetc, we have encrypt database password in phpfile, my class with alot funtions to help you encrypt and decrypt and our swoole server install just run ./yii swoole/start and be happy!

Yii 2 Basic Project Template with swoole and Modules Yii 2 Basic Project Template is a skeleton Yii 2 application best for rapidly creating small proj

null 3 Apr 11, 2022
Auth is a module for the Yii PHP framework that provides a web user interface for Yii's built-in authorization manager

Auth is a module for the Yii PHP framework that provides a web user interface for Yii's built-in authorization manager (CAuthManager). You can read more about Yii's authorization manager in the framework documentation under Authentication and Authorization.

Christoffer Niska 134 Oct 22, 2022
Laravel Users (Roles & Permissions, Devices, Password Hashing, Password History).

LARAVEL USERS Roles & Permissions Devices Password Hashing Password History Documentation You can find the detailed documentation here in Laravel User

Pharaonic 8 Dec 14, 2022
🔒 Password Exposed Helper Function - Check if a password has been exposed in a data breach.

?? Password Exposed Helper Function This PHP package provides a password_exposed helper function, that uses the haveibeenpwned.com API to check if a p

Jordan Hall 212 Oct 24, 2022
User authentication REST API with Laravel (Register, Email verification, Login, Logout, Logged user data, Change password, Reset password)

User Authentication API with Laravel This project is a user authentication REST API application that I developed by using Laravel and MySql. Setup Fir

Yusuf Ziya YILDIRIM 3 Aug 23, 2022
File uploads with validation and storage strategies

Upload This component simplifies file validation and uploading. Usage Assume a file is uploaded with this HTML form: <form method="POST" enctype="mult

Brandon Savage 1.7k Dec 27, 2022
PHP library providing retry functionality with multiple backoff strategies and jitter support

PHP Backoff Easily wrap your code with retry functionality. This library provides: 4 backoff strategies (plus the ability to use your own) Optional ji

Signature Tech Studio 145 Dec 21, 2022