Autenticar contra BD pero usando 3 campos: EMPRESA, OPERADOR, CONTRASEÑA.

Buenos días.

Ya se como autenticar a un usuario (nombre-password) contra mi tabla ‘usuarios’ de mi base de datos.

Lo que necesito ahora es autenticar por tres campos:

EMPRESA: (introduzca CIF empresa)

OPERADOR: (introduzca NIF operador)

CONTRASEÑA: ******

En la tabla ‘usuarios’ ya tengo esos campos creados. Y pueden existir varios registros con la misma empresa y varios registros con el mismo operador. Pero lo que es UNICO, es la unión de los campos EMPRESA-OPERADOR

Yii genera la estructura para 2 campos y no se como modificarlo para añadir ese otro campo extra.

Les agradecería sugerencias.

Muchas gracias.

que estas usando en Yii para hacer esa validacion, podrias mostrar el Modelo, control y vista que hace la autenticacion para modificar tu codigo

hola indudablemente tendrás que hacer un nuevo formulario de login cuyo modelo valide con esos tres campos, para luego invocar a CWebUser::login() manualmente. Debes entender un poco mas a fondo la logica de el paquete de autenticacion de yii.se esta creando una nueva extension llamada "Cruge", la cual solventa esos problemas mediante extensiones al paquete auth de yii. entre las mejoras incorporadas hay filtros de autenticacion personalizables, con cruge tu resolevrias este problema simplemente creando una nueva clase que implementa una interfaz llamada ICrugeAuth y alli tu harias tu validacion sin meterte muy adentro. Te pido disculpas de antemano, la extension que te cuento esta en fase de pruebas en este momento por tanto no esta publica aun, pero pronto lo estará.saludos !

Muchas gracias por tu pronta respuesta.

1º He añadido un campo al formulario /protected/views/site/login.php:




<?php

$this->pageTitle=Yii::app()->name . ' - Login';

$this->breadcrumbs=array(

	'Login',

);

?>


<h1>Login</h1>

<p>Please fill out the following form with your login credentials:</p>


<div class="form">

<?php $form=$this->beginWidget('CActiveForm', array(

	'id'=>'login-form',

	'enableClientValidation'=>true,

	'clientOptions'=>array(

		'validateOnSubmit'=>true,

	),

)); ?>


	<p class="note">Fields with <span class="required">*</span> are required.</p>


        <!-- AÑADO CAMPO IDENTIFICACION CLIENTE (=EMPRESA) identifCliente -->

	<div class="row">

		<?php echo $form->labelEx($model,'identifCliente'); ?>

		<?php echo $form->textField($model,'identifCliente'); ?>

		<?php echo $form->error($model,'identifCliente'); ?>

	</div>

        <!-- ------------------------------------------------------------ -->


	<div class="row">

		<?php echo $form->labelEx($model,'username'); ?>

		<?php echo $form->textField($model,'username'); ?>

		<?php echo $form->error($model,'username'); ?>

	</div>

        

	<div class="row">

		<?php echo $form->labelEx($model,'password'); ?>

		<?php echo $form->passwordField($model,'password'); ?>

		<?php echo $form->error($model,'password'); ?>

<!--		<p class="hint">

			Hint: You may login with <tt>demo/demo</tt> or <tt>admin/admin</tt>.

		</p>-->

	</div>


	<div class="row rememberMe">

		<?php echo $form->checkBox($model,'rememberMe'); ?>

		<?php echo $form->label($model,'rememberMe'); ?>

		<?php echo $form->error($model,'rememberMe'); ?>

	</div>


	<div class="row buttons">

		<?php echo CHtml::submitButton('Login'); ?>

	</div>


<?php $this->endWidget(); ?>

</div><!-- form -->



2º Modifico /protected/models/LoginForm.php:




<?php

/**

 * LoginForm class.

 * LoginForm is the data structure for keeping

 * user login form data. It is used by the 'login' action of 'SiteController'.

 */

class LoginForm extends CFormModel

{

	public $identifCliente; // AÑADO ATRIBUTO identifCliente (=EMPRESA)

	public $username;

	public $password;

	public $rememberMe;


	private $_identity;


	/**

	 * Declares the validation rules.

	 * The rules state that username and password are required,

	 * and password needs to be authenticated.

	 */

	public function rules()

	{

		return array(

			// username and password are required

//			array('username, password', 'required'),  

			array('identifCliente, username, password', 'required'),  //AÑADO identifCliente (=EMPRESA)

			// rememberMe needs to be a boolean

			array('rememberMe', 'boolean'),

			// password needs to be authenticated

			array('password', 'authenticate'),

		);

	}


	/**

	 * Declares attribute labels.

	 */

	public function attributeLabels()

	{

		return array(

			'rememberMe'=>'Remember me next time',

		);

	}


	/**

	 * Authenticates the password.

	 * This is the 'authenticate' validator as declared in rules().

	 */

	public function authenticate($attribute,$params)

	{

		if(!$this->hasErrors())

		{

//			$this->_identity=new UserIdentity($this->username,$this->password); 

			$this->_identity=new UserIdentity($this->identifCliente,$this->username,$this->password); //AÑADO identifCliente (=EMPRESA)

			if(!$this->_identity->authenticate())

				$this->addError('password','Incorrect username or password.');

		}

	}


	/**

	 * Logs in the user using the given username and password in the model.

	 * @return boolean whether login is successful

	 */

	public function login()

	{

		if($this->_identity===null)

		{

//			$this->_identity=new UserIdentity($this->username,$this->password);

			$this->_identity=new UserIdentity($this->identifCliente,$this->username,$this->password);   //AÑADO identifCliente (=EMPRESA)

			$this->_identity->authenticate();

		}

		if($this->_identity->errorCode===UserIdentity::ERROR_NONE)

		{

			$duration=$this->rememberMe ? 3600*24*30 : 0; // 30 days

			Yii::app()->user->login($this->_identity,$duration);

			return true;

		}

		else

			return false;

	}

}




3º Modifico /protected/components/UserIdentity.php:




<?php

/*

    AUTENTICACION CONTRA BASE DATOS:

    Para que nuestra aplicación funcione con los usuarios y contraseñas 

    de nuestra base de datos (AUTENTICACION) hay que emplear este código

    en sustitución del que Yii genera por defecto.

*/


class UserIdentity extends CUserIdentity

{

    private $_id;

    public function getId()

    {

        return $this->_id;

    }

    

    public function authenticate()

    {

        /*

            http://www.yiiframework.com/doc/guide/1.1/es/topics.auth

            $this->username   : Nombre de usuario que se ha introducido en el formulario del login.

            findByAttributes  : Encuentra un registro único activo que tiene los valores de los atributos especificados.

            findByAttributes($attributes,$condition,$params)

                http://www.yiiframework.com/doc/api/1.1/CActiveRecord#findByAttributes-detail

                Esto es equivalente a ejecutar la senctencia SQL:

                SELECT * FROM usuarios WHERE username = ?

            Usuarios::model() : Emplearemos los datos del modelo Usuarios para comprobar la autenticacion.

        */

        

        //modifico lo estandar pues en esta aplicacion quiero entrar por cif y nif. No por nombre usuario.

        

        $registro=Usuarios::model()->findByAttributes(array

                                                        (

                                                            //'nombre'=>$this->username,

                                                            'identificacion_usuario'=>$this->username,

                                                            'identificacion_cliente'=>$this->identifCliente // AÑADO identifCliente

                                                        )

                                                     );

        if($registro===null)

            $this->errorCode=self::ERROR_USERNAME_INVALID;

        else if($registro->contrasena!==md5($this->password))

            $this->errorCode=self::ERROR_PASSWORD_INVALID;

        else

        {

            $this->_id=$registro->id;

            /*

            	setState: Guarda información en la sesion (para futuras solicitudes)

                          Podemos guardar toda la información que necesitemos.

                          (Tener cuidado pues si el usuario activa 'recordar en mi equipo',

                          esos parámetros se almacenan en ququies en el ordenador)

            	setState('el nombre del estado','valor del estado llamado');

            */

//            $this->setState('nombre', $registro->nombre);

            $this->setState('identifCliente', $registro->identificacion_cliente);

            $this->setState('username', $registro->identificacion_usuario);

            $this->errorCode=self::ERROR_NONE;

        }

        return !$this->errorCode;

    }

}




Pero al ejecutar la aplicación me dice que ‘identifCliente’ no esta definido. No entiendo porqué, si ya declare $identifCliente en class LoginForm.




CException


Property "UserIdentity.identifCliente" is not defined.


/Applications/MAMP/htdocs/ejemplo/protected/components/UserIdentity.php(36)


24                 http://www.yiiframework.com/doc/api/1.1/CActiveRecord#findByAttributes-detail

25                 Esto es equivalente a ejecutar la senctencia SQL:

26                 SELECT * FROM usuarios WHERE username = ?

27             Usuarios::model() : Emplearemos los datos del modelo Usuarios para comprobar la autenticacion.

28         */

29         

30         //modifico lo estandar pues en esta aplicacion quiero entrar por cif y nif. No por nombre usuario.

31         

32         $registro=Usuarios::model()->findByAttributes(array

33                                                         (

34                                                             //'nombre'=>$this->username,

35                                                             'identificacion_usuario'=>$this->username,

36                                                             'identificacion_cliente'=>$this->identifCliente // AÑADO identifCliente

37                                                         )

38                                                      );

.....



Agradecería ayuda sobre cómo solucionar esto.

Muchas gracias de nuevo.

saludos.

Hola

Lo que he modificado esta en la respuesta a Christian.

Aparte tendrás que configurar main para el acceso a la base de datos.

Buenas!

El error es porque la clase CUserIdentity no tiene una propiedad identifCliente, a la cual querés acceder en la línea #36 de tu UserIdentity.

Podrías agregar esa propiedad a la clase para después hacer la autenticación.

También tendrías que sobreescribir el constructor para aceptar la nueva propiedad como parámetro.

Algo como




<?php

/*

    AUTENTICACION CONTRA BASE DATOS:

    Para que nuestra aplicación funcione con los usuarios y contraseñas 

    de nuestra base de datos (AUTENTICACION) hay que emplear este código

    en sustitución del que Yii genera por defecto.

*/


class UserIdentity extends CUserIdentity

{

    private $_id;

    public function getId()

    {

        return $this->_id;

    }


    private $_identifCliente; // <--- Acá agregás la propiedad

    

    // Sobreescribiendo el constructor

    public function __construct($identifCliente,$username,$password)

    {

        $this->$_identifCliente=$identifCliente;

        $this->username=$username;

        $this->password=$password;

    }


    public function authenticate()

    ... ...



y más adelante en el código:




$registro=Usuarios::model()->findByAttributes(array

    (

     //'nombre'=>$this->username,

    'identificacion_usuario'=>$this->username,

    'identificacion_cliente'=>$this->_identifCliente // AÑADO identifCliente    

    )

);



Pregunto ¿tenés el campo contrasena en la tabla users?

Muchas gracias Luciano

He probado lo que me has dicho y funcionó perfecto.

En la base de datos si que tengo un campo contrasena (ya se que no suena muy profesional…pero es que estoy comenzando.)

Gracias de nuevo por todo y a todos

Gracias.