I want to require the user to choose a strong password with at least one uppercase letter and one digit. How do I enforce this policy when validating a form with CodeIgniter?
-
Using callback and some regular expressions https://stackoverflow.com/a/65401563/7186739 – Billu Dec 22 '20 at 00:03
1 Answers
Extend the default Form_validation
class and create a custom validation rule for your custom password validation.
To extend the default class you need to create a MY_Form_validation
class and put it into your application/libraries/MY_Form_validation.php
. Here's an example:
<?php defined('BASEPATH') OR exit('No direct script access allowed');
/**
* Extension of CI's default form validation library.
*
* @see system/libraries/Form_validation.php
*/
class MY_Form_validation extends CI_Form_validation {
/**
* Custom password validation rule.
*
* @param string $pass Password to check.
*
* @return bool
*/
public function check_pass($pass)
{
// It's a good practice to make sure each validation rule does
// its own job. So we decide that this callback does not check
// for the password field being required. If we need so, we just
// prepend the "required" rule. For example: "required|min_length[8]|check_pass"
//
// So we just let it go if the value is empty:
if (empty($pass))
{
return TRUE;
}
// This sets the error message for your custom validation
// rule. %s will be replaced with the field name if needed.
$this->set_message('check_pass', 'Password needs to have at least one uppercase letter and a number.');
// The regex looks ahead for at least one lowercase letter,
// one uppercase letter and a number. IT'S NOT TESTED THOUGH.
return (bool) preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/', $pass);
}
}
With this custom class in place, the check_pass
validation rule will be available to your controllers when setting rules.
If you're too lazy to add this custom class or you already have the validation function implemented somewhere else, you might want to use custom validation callbacks by prepending callback_
to the name of existing functions and use them as validation rules. See validation callbacks for more on this.
I don't recommend the latter approach though as it messes up with where validation rules reside. There are some cases that we MUST use custom callbacks that not reside in the validation class, outside those cases (which is not yours) all rules better be in your custom class.
P.S. Also consider this:

- 17,110
- 7
- 81
- 119
-
**Severity: Warning Message: preg_match(): Compilation failed: unmatched parentheses at offset 31 Filename: libraries/MY_Form_validation.php Line Number: 130** I get this error when i hit the register button and when i use callback_check_pass in the model where the validation rules are set the registration is still succesful – DEV Sep 03 '15 at 06:42
-
I updated the regex a few minutes ago. It works now. Just strip the extra parenthese at the end. – sepehr Sep 03 '15 at 06:44
-
When you put the rule in your custom `MY_Form_validation` class you don't need the extra `callback_` prepended. It's just `check_pass`. – sepehr Sep 03 '15 at 06:47
-
it is still logging in succesfully with simple lowercase text, the message should contain 1 uppercase letter and 1 digit isn't displaying Below is the code i am using in my model: `'password' => array( 'field' => 'password', 'label' => 'Password', 'rules' => 'trim|min_length[6]|matches[password_confirm]|check_pass' ), 'password_confirm' => array( 'field' => 'password_confirm', 'label' => 'Confirm password', 'rules' => 'trim|min_length[6]|matches[password]|check_pass' ),` – DEV Sep 03 '15 at 07:10
-
First; I had a typo, `preg_match` does not return booleans and it can mess with your passwords, we need to typecast its return value. (I updated the code) Second; to test, change the `check_pass` rule to always return `FALSE` and see if it gets called. If it does, you should work on the regex then. – sepehr Sep 03 '15 at 08:17
-
-