<p><strong>In Craft 2</strong></p>

<p>Plugins have the power to enforce stricter password requirements using the <a href="http://buildwithcraft.com/docs/plugins/events-reference#users-onBeforeSetPassword" rel="nofollow noreferrer">users.onBeforeSetPassword</a> event.</p>

<p>Add this code to your plugin’s <a href="http://buildwithcraft.com/docs/plugins/setting-things-up#your-primary-plugin-class" rel="nofollow noreferrer">primary class</a>:</p>

<pre class="lang-php prettyprint-override"><code>public function init()
{
    craft()-&gt;on('users.beforeSetPassword', array($this, 'onBeforeSetPassword'));
}

public function onBeforeSetPassword(Event $e)
{
    $user = $e-&gt;params['user'];
    $password = $e-&gt;params['password'];

    // Perform our custom validation logic here
    $validates = true;

    if (mb_strlen($password) &lt; 7)
    {
        $validates = false;
    }
    else if (!preg_match('/(\d.*[A-Z]|[A-Z].*\d)/', $password))
    {
        $validates = false;
    }

    if (!$validates)
    {
        // Set $performAction = false so the password doesn't get saved
        $e-&gt;performAction = false;

        // Add a custom validation error on the user
        $user-&gt;addError('newPassword', 'Sorry but your password must contain an uppercase letter, a number, a haiku, a gang sign, hieroglyph, and the blood of a virgin.');
    }
}
</code></pre>

<p><strong>In Craft 3</strong></p>

<p>Craft 3 doesn't have a <code>beforeSetPassword</code> event, but you can pull the same thing off from your plugin's init() method using the User element's <code>User::EVENT_BEFORE_VALIDATE</code> event like so:</p>

<pre class="lang-php prettyprint-override"><code>public function init()
{
    parent::init();

    Event::on(
        User::class,
        User::EVENT_BEFORE_VALIDATE,
        function (ModelEvent $event) {
            // Check if a new password was set on the user
            if ($event-&gt;sender-&gt;newPassword) {
                $password = $event-&gt;sender-&gt;newPassword;
                $errors = [];

                // Perform our custom validation logic here
                $validates = true;

                if (mb_strlen($password) &lt; 7) {
                    $validates = false;
                    $errors[] = 'Too Short!';
                }
                else if (!preg_match('/(\d.*[A-Z]|[A-Z].*\d)/', $password)) {
                    $validates = false;
                    $errors[] = 'Too Simple!';
                }

                $event-&gt;isValid = $validates;

                if (!$validates) {
                    /** @var User $user */
                    $user = $event-&gt;sender;
                    foreach ($errors as $error) {
                        $user-&gt;addError('newPassword', $error);
                    }
                }
            }
        }
    );
}
</code></pre>

CC BY-SA 3.0
2016-09-19T19:05:22.487Z
I've adapted Brandon Kelly's answer into a plugin, [craft-password-enforcer](https://straightupcraft.com/craft-plugins/craft-password-enforcer).
kotyy
CC BY-SA 3.0
2016-10-01T21:28:02.400Z
@BrandonKelly is there a way to stop the default craft error displaying if the password is less then 6 characters? As it is confusing for the user to show one error stating it needs to be 6 then another error again if I set my default length to be higher than this (10 for example).
Terry Upton
CC BY-SA 3.0
2016-10-11T16:45:32.063Z
@TerryUpton Good question. Right now I don't think that’s possible, unfortunately.
Brandon Kelly
CC BY-SA 4.0
2015-10-29T14:32:11.597Z
2018-05-07T19:20:22.443Z
2018-05-07T19:20:22.443Z
Brandon Kelly
<p>Craft’s only password requirements are that it is between 6 and 160 characters long. I want to require my users to enter passwords that are at least 7 characters long, with at least one number and one capital letter.</p>

<p>Is it possible to enforce these stricter requirements, or do we have to wait for <a href="http://feedback.buildwithcraft.com/forums/285221-feature-requests/suggestions/10459731-better-stricter-rules-for-password-input-upon-regi">this feature request</a> to be accepted?</p>

<users><password>
How do I enforce stronger password requirements on my Craft site?
# How do I enforce stronger password requirements on my Craft site?

(Asked by: username_0 on 2015-10-29)

Craft’s only password requirements are that it is between 6 and 160 characters long. I want to require my users to enter passwords that are at least 7 characters long, with at least one number and one capital letter.

Is it possible to enforce these stricter requirements, or do we have to wait for [this feature request](http://feedback.buildwithcraft.com/forums/285221-feature-requests/suggestions/10459731-better-stricter-rules-for-password-input-upon-regi) to be accepted?

**Tags:** users, password


---

## 1 answers

### Answer by username_0 on 2015-10-29. Score: 10 | Accepted answer

In Craft 2
Plugins have the power to enforce stricter password requirements using the users.onBeforeSetPassword event.
Add this code to your plugin’s primary class:
public function init()
{
    craft()->on('users.beforeSetPassword', array($this, 'onBeforeSetPassword'));
}

public function onBeforeSetPassword(Event $e)
{
    $user = $e->params['user'];
    $password = $e->params['password'];

    // Perform our custom validation logic here
    $validates = true;

    if (mb_strlen($password) < 7)
    {
        $validates = false;
    }
    else if (!preg_match('/(\d.*[A-Z]|[A-Z].*\d)/', $password))
    {
        $validates = false;
    }

    if (!$validates)
    {
        // Set $performAction = false so the password doesn't get saved
        $e->performAction = false;

        // Add a custom validation error on the user
        $user->addError('newPassword', 'Sorry but your password must contain an uppercase letter, a number, a haiku, a gang sign, hieroglyph, and the blood of a virgin.');
    }
}

In Craft 3
Craft 3 doesn't have a beforeSetPassword event, but you can pull the same thing off from your plugin's init() method using the User element's User::EVENT_BEFORE_VALIDATE event like so:
public function init()
{
    parent::init();

    Event::on(
        User::class,
        User::EVENT_BEFORE_VALIDATE,
        function (ModelEvent $event) {
            // Check if a new password was set on the user
            if ($event->sender->newPassword) {
                $password = $event->sender->newPassword;
                $errors = [];

                // Perform our custom validation logic here
                $validates = true;

                if (mb_strlen($password) < 7) {
                    $validates = false;
                    $errors[] = 'Too Short!';
                }
                else if (!preg_match('/(\d.*[A-Z]|[A-Z].*\d)/', $password)) {
                    $validates = false;
                    $errors[] = 'Too Simple!';
                }

                $event->isValid = $validates;

                if (!$validates) {
                    /** @var User $user */
                    $user = $event->sender;
                    foreach ($errors as $error) {
                        $user->addError('newPassword', $error);
                    }
                }
            }
        }
    );
}

> **Comments:**
> **username_1**: I've adapted username_0's answer into a plugin, [craft-password-enforcer](https://straightupcraft.com/craft-plugins/craft-password-enforcer).  
> **username_2**: @BrandonKelly is there a way to stop the default craft error displaying if the password is less then 6 characters? As it is confusing for the user to show one error stating it needs to be 6 then another error again if I set my default length to be higher than this (10 for example).  
> **username_0**: @TerryUpton Good question. Right now I don't think that’s possible, unfortunately.  

---

