Я использовал аутентификацию zf2 для пользователя аутентификации в моем проекте. Я сохранил Хариб в моей пользовательской таблице в качестве имени пользователя, но если я использую свое имя пользователя Harib, тогда его принимают или я использую хариб, тогда его не принимают, я хочу удалить чувствительность к регистру пользователя имя так как Хариб или Хариб доступ, как я это исправить?
Вот мой код:
public function loginAction() { $this->layout('layout/login-layout.phtml'); $login_error = false; $loginForm = new LoginForm(); $form_elements = json_encode($loginForm->form_elements); if ($this->request->isPost()) { $post = $this->request->getPost(); $loginForm->setData($post); if ($loginForm->isValid()) { $hashed_string = ''; if( array_key_exists('hashed_input' , $post) && $post['hashed_input'] != '' && strpos(urldecode($this->params('redirect')) , 'programdetailrequest') !== false ) { $hashed_string = $post['hashed_input']; } $data = $loginForm->getData(); $authService = $this->getServiceLocator()->get('doctrine.authenticationservice.odm_default'); $adapter = $authService->getAdapter(); $adapter->setIdentityValue($data['username']); $adapter->setCredentialValue(md5($data['password'])); $authResult = $authService->authenticate(); if($authResult->isValid()){ $identity = $authResult->getIdentity(); if( is_object($identity) && method_exists($identity, 'getData') ){ $user_data = $identity->getData(); $authService->getStorage()->write($identity); // for remeber checkbox if ($post['rememberme']) { $token = new UserToken(); $dm = $this->getServiceLocator()->get('doctrine.documentmanager.odm_default'); //if same user already running from other browser then remove previous token. $check_token = $dm->getRepository('Admin\Document\UserToken')->findOneBy(array( "user_id.id" => $user_data['id'] )); if (is_object($check_token) && !is_null($check_token)) { $remove_token = $dm->createQueryBuilder('Admin\Document\UserToken') ->remove() ->field('id')->equals($check_token->id) ->getQuery()->execute(); } //create token $user = $dm->getRepository('Admin\Document\User')->findOneBy(array( "id" => $user_data['id'] )); $token->setProperty('user_id', $user); $token->setProperty('dataentered', new \MongoDate()); $dm->persist($token); $dm->flush($token); //create cookie if(is_object($token) && property_exists($token, 'id')){ $time = time() + (60 * 60 * 24 * 30); // 1 month setcookie('token', $token->getProperty('id'), $time, '/'); } } if ($user_data['user_type'] == 'onlinemarketer') { $this->redirect()->toRoute('admin_program_meta'); } elseif ($user_data['user_type'] == 'bucharestofficemanager') { $this->redirect()->toRoute('admin_program_detail_request'); } else { if ($this->params('redirect') && urldecode($this->params('redirect')) !== '/logout/') { $server_url = $this->getRequest()->getUri()->getScheme() . '://' . $this->getRequest()->getUri()->getHost().urldecode($this->params('redirect') . $hashed_string); return $this->redirect()->toUrl($server_url); } return $this->redirect()->toRoute('admin_index'); } } } else { $identity = false; $login_error = true; } } } return new ViewModel(array( 'loginForm' => $loginForm, 'form_elements' =>$form_elements, 'login_error' => $login_error, )); }
и вот мой код формы входа в систему:
<?php namespace Admin\Form; use Zend\Form\Form; use Zend\Form\Element; use Zend\InputFilter\InputFilterAwareInterface; use Zend\InputFilter\InputFilter; use Zend\InputFilter\Factory as InputFactory; class LoginForm extends Form implements InputFilterAwareInterface { protected $inputFilter; public $form_elements = array( array( 'name' => 'username', 'attributes' => array( 'id' => 'username', 'type' => 'text', 'error_msg' => 'Enter Valid Username', 'data-parsley-required' => 'true', 'data-parsley-pattern' => '^[a-zA-Z0-9_\.\-]{1,50}$', 'data-parsley-trigger' => 'change' ), 'options' => array( 'label' => 'User Name' ), 'validation' => array( 'required'=>true, 'filters'=> array( array('name'=>'StripTags'), array('name'=>'StringTrim') ), 'validators'=>array( array('name'=>'Regex', 'options'=> array( 'pattern' => '/^[a-z0-9_.-]{1,50}+$/', // contain only a to z 0 to 9 underscore, hypen and space, min 1 max 50 'pattern_js' => '^[a-zA-Z0-9_\.\-]{1,50}$' ) ) ) ) ), array( 'name' => 'password', 'attributes' => array( 'id' => 'password', 'type' => 'password', 'error_msg' => 'Enter Valid Password', 'data-parsley-required' => 'true', 'data-parsley-pattern' => '^[a-zA-Z0-9_\.\-]{6,25}$', 'data-parsley-trigger' => 'change' ), 'options' => array( 'label' => 'Password' ), 'validation' => array( 'required' => true, 'filters'=> array( array('name'=>'StripTags'), array('name'=>'StringTrim') ), 'validators'=>array( array('name'=>'Regex', 'options'=> array( 'pattern' => '/^[a-z0-9_.-]{6,25}+$/', // contain only a to z 0 to 9 underscore, hypen and space, min 1 max 50 'pattern_js' => '^[a-zA-Z0-9_\.\-]{6,25}$' ) ) ) ) ), array( 'name' => 'hashed_input', 'attributes' => array( 'type' => 'hidden', 'id' => 'hashed_input', 'value' => '' ) ), array( 'name' => 'rememberme', 'attributes' => array( 'value' => 1, 'id' => 'rememberme', 'type' => 'Checkbox' ), 'options' => array( 'label' => 'Remember Me', 'use_hidden_element' => false, ) ), array( 'name' => 'submit', 'attributes' => array( 'type' => 'submit', 'value' => 'Log in', 'id' => 'submitbutton' ) ) ); public function __construct() { parent::__construct('user'); $this->setAttribute('method', 'post'); $this->setAttribute('data-parsley-validate', ''); $this->setAttribute('data-elements', json_encode($this->form_elements)); $this->setAttribute('autocomplete', 'off'); for($i=0;$i<count($this->form_elements);$i++){ $elements=$this->form_elements[$i]; $this->add($elements); } } public function getInputFilter($action=false) { if(!$this->inputFilter){ $inputFilter = new InputFilter(); $factory = new InputFactory(); for($i=0;$i<count($this->form_elements);$i++){ if(array_key_exists('validation',$this->form_elements[$i])){ $this->form_elements[$i]['validation']['name']=$this->form_elements[$i]['name']; $inputFilter->add($factory->createInput( $this->form_elements[$i]['validation'] )); } } $this->inputFilter = $inputFilter; } return $this->inputFilter; } }
как мы удаляем чувствительность к регистру имени пользователя, чтобы принять как Хариб, так и Хариб?
Добавьте фильтр StringToLower
в loginform
в элемент user_id
.
Для этого класс, определяющий вашу loginform
должен реализовать InputFilterProviderInterface
и вы должны добавить метод getInputFilterSpecification
следующим образом:
public function getInputFilterSpecification() { return [ 'username' => [ 'name' => 'username', 'required' => true, 'filters' => [ 'name' => 'StringToLower', 'name'=>'StripTags', 'name'=>'StringTrim' ], validators => [ [ 'name'=>'Regex', 'options'=> [ 'pattern' => '/^[a-z0-9_.-]{1,50}+$/', 'pattern_js' => '^[a-zA-Z0-9_\.\-]{1,50}$' ] ] ] ], 'password' => [ 'name' => 'password', 'required' => true, 'filters' => [ array('name'=>'StripTags'), array('name'=>'StringTrim') ], 'validators' => [ [ 'name'=>'Regex', 'options'=> [ 'pattern' => '/^[a-z0-9_.-]{6,25}+$/', 'pattern_js' => '^[a-zA-Z0-9_\.\-]{6,25}$' ] ] ] ] ]; }
Таким образом, вы уверены, что значение, возвращаемое в сообщении, находится в нижнем регистре.
Поскольку вы используете MongoDB, вы можете использовать регулярное выражение для получения имени пользователя из базы данных.
Предложение 1:
В вашем примере это будет:
db.stuff.find( { foo: /^bar$/i } );
Предложение 2:
Вы можете использовать $ options => i для поиска без учета регистра. Предоставление некоторых возможных примеров, необходимых для соответствия строк.
Строка с несинхронным регистром
db.collection.find({name:{'$regex' : '^string$', '$options' : 'i'}})
Содержит строку
db.collection.find({name:{'$regex' : 'string', '$options' : 'i'}})
Начать с строки
db.collection.find({name:{'$regex' : '^string', '$options' : 'i'}})
Конец со строкой
db.collection.find({name:{'$regex' : 'string$', '$options' : 'i'}})
Не содержит строку
db.collection.find({name:{'$regex' : '^((?!string).)*$', '$options' : 'i'}})
Подробнее о regex в MongoDb здесь: https://docs.mongodb.com/manual/reference/operator/query/regex/index.html
Вы можете сделать это двумя способами. Вы можете создать собственный адаптер аутентификации или переопределить метод адаптера аутентификации по умолчанию. Я рекомендую переопределить этот метод, который проще, чем создание пользовательского адаптера.
Итак, вот метод CredentialTreatmentAdapter::authenticateCreateSelect()
. Если вы посмотрите около 94 строк (из zf 2.5) этого метода из компонента zend-authentication
вы найдете следующую строку.
$dbSelect->from($this->tableName) ->columns(['*', $credentialExpression]) // See the making of where clause ->where(new SqlOp($this->identityColumn, '=', $this->identity));
Здесь мы сделаем наши изменения. Теперь давайте переопределим этот метод, расширив Zend\Authentication\Adapter\DbTable
. Мы бы сделали предложение where, которое будет искать как Harib
и harib
. См. Следующий расширенный CustomDbTable::class
.
<?php namespace Define\Your\Own\Namespace; use Zend\Authentication\Adapter\DbTable; class CustomDbTable extends DbTable { protected function authenticateCreateSelect() { // build credential expression if (empty($this->credentialTreatment) || (strpos($this->credentialTreatment, '?') === false)) { $this->credentialTreatment = '?'; } $credentialExpression = new SqlExpr( '(CASE WHEN ?' . ' = ' . $this->credentialTreatment . ' THEN 1 ELSE 0 END) AS ?', array($this->credentialColumn, $this->credential, 'zend_auth_credential_match'), array(SqlExpr::TYPE_IDENTIFIER, SqlExpr::TYPE_VALUE, SqlExpr::TYPE_IDENTIFIER) ); // Here is the catch $where = new \Zend\Db\Sql\Where(); $where->nest() ->equalTo($this->identityColumn, $this->identity) ->or ->equalTo($this->identityColumn, strtolower($this->identity)) ->unnest(); // get select $dbSelect = clone $this->getDbSelect(); $dbSelect->from($this->tableName) ->columns(array('*', $credentialExpression)) ->where($where); // Here we are making our own where clause return $dbSelect; } }
Теперь пользовательский адаптер аутентификации готов. Вы должны использовать это внутри фабрики для службы аутентификации вместо Zend\Authentication\Adapter\DbTable
следующим образом
'factories' => array( // Auth service 'AuthService' => function($sm) { $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter'); // Use CustomDbTable instead of DbTable here $customDbTable = new CustomDbTable($dbAdapter, 'tableName', 'usernameColumn', 'passwordColumn', 'MD5(?)'); $authService = new AuthenticationService(); $authService->setAdapter($customDbTable); return $authService; }, ),
Теперь все установлено. Этот переопределенный метод следует вызывать всякий раз, когда вы вызываете это в своем методе контроллера:
$authResult = $authService->authenticate();
Это не проверено. Таким образом, вам, возможно, потребуется изменить то, что вам нужно. При необходимости исправьте их.
Надеюсь, это поможет вам!