Hola de nuevo. Vamos a mostraros una forma de llevar un control de accesos y credenciales de usuarios bastante simple, sin tener que utilizar el plugin sfGuardPlugin que nos puede traer mas de un quebradero de cabeza.
Bien, lo primero de todo es crear un form que nos servirá de login:
/lib/form/LoginForm.class.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
class LoginForm extends BaseForm
{
public function configure()
{
$this->setWidgets(array(
'user' => new sfWidgetFormInputText(),
'password' => new sfWidgetFormInputPassword(),
));
$this->setValidators(array(
'user' => new sfValidatorEmail(array('required' => true), array('required' => 'Escribe tu usuario')),
'password' => new sfValidatorString(array('required' => true), array('required' => 'Escribe tu password')),
));
$this->widgetSchema->setLabels(array(
'user' => 'Usuario:',
'password' => 'Contraseña:',
));
}
} |
Para continuar tengo que explicar un poco como va el tema de las credenciales y la autenticación en symfony. Entre los archivos settings.yml y security.yml de la carpeta config de la aplicación se puede hacer practicamente todo. Lo primero es dicirle a la aplicación que necesita seguridad para lo que entramos al security.yml y modificamos:
/apps/app/config/security.yml
default:
is_secure: true
Con esto nuestra aplicación es segura, con lo que exigira la autenticación del usuario antes de pasar por cualquier acción, menos por la del login. Esto también se puede hacer para cualquier acción en cualquier módulo, por ejemplo, para solo tener una acción o un módulo protegido:
Creamos el archivo:
/apps/app/modules/prueba/config/security.yml
y escribimos:
default:
is_secure: true
esto para hacer que todo el módulo sea seguro o bien:
index:
is_secure: true
para que solo la acción index sea segura.
Vale para el tema credenciales la misma mecánica, vamos al config.yml de donde queramos controlar las credenciales y escribimos:
/apps/app/modules/prueba/config/security.yml
default:
is_secute: true
credentials: admin
Con esto solo pueden acceder a la aplicación app los usuarios que estén autenticados y tengan credenciales de admin.
default:
is_secure: true
credentials: [alianza, horda]
Con esto solo pueden acceder los usuarios que sean de la alianza y de la horda. Es decir que tengan las dos credenciales.
default:
is_secure: true
credentials: [[alianza, horda]]
Con esto solo pueden acceder los usuarios que sean de la alianza o de la horda. Es decir que tengan cualquiera de las dos credenciales.
Vale a continuación le atacamos al archivo settings.yml de la aplicación:
/apps/app/config/settings.yml
y añadimos:
all:
.actions:
login_module: login
login_action: index
Esto es para decirle a la aplicación que módulo y que acción van a controlar el login, por lo que tendremos acceso siempre, estemos autenticados o no.
Pues todo listo para crear el modulo y la acción de login:
/apps/app/modules/login/actions/action.class.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
class loginActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
if($request->getParameter('login')){
//Hacemos la consulta para ver si existe cliente con ese usuario y esa contraseña.
$query = Doctrine_Query::create()
->select('user, idcliente, nombre, apellidos')
->from('Cliente')
->where('user = ?',$request->getParameter('user'))
->andwhere('pass = ?',md5($request->getParameter('password')))
->execute();
//Comprobamos que existe el usuario, si no creamos un mensaje flash y redireccionamos al index
if(count($query) == 0){
$this->getUser()->setFlash('error', 'Usuario o contraseña inválidos');
$this->redirect('login/index');
}else{
//Autenticamos al usuario
$this->getUser()->setAuthenticated(true);
//Creamos variables de sesión con sus datos personales, para lo que nos pueda valer.
$this->getUser()->setAttribute('id', $query[0]['idcliente'], 'cliente');
//En este caso 'nombre' es el nombre de la variable, seguido por el valor y por último el namespace.
$this->getUser()->setAttribute('nombre', $query[0]['nombre'], 'cliente');
//Si queremos acceder a estas variables no tenemos mas que poner: $this->getUser()->getAttribute('nombre', null, 'cliente');
$this->getUser()->setAttribute('apellidos', $query[0]['apellidos'], 'cliente');
//Le damos las credenciales correspondientes, en este caso de cliente.
$this->getUser()->addCredential('cliente');
$this->redirect('moduloquequieras/index');
}
}
/*Aquí nos aseguramos de que no vuelva a entrar al login una vez logeado y tenga credencial de cliente, no es necesario pero a mi me gusta así. Quedaos con el isAuthenticated() y el hasCredential('credencial'). Para comprobar que se tienen mas de una credencial:
$this->getUser()->hasCredential(array("admin", "cliente")); Para comprobar que tiene las dos, admin y cliente.
$this->getUser()->hasCredential(array("admin", "cliente"), false); Para comprobar que tiene cualquiera de las dos.
*/
if($this->getUser()->isAuthenticated() && $this->getUser()->hasCredential('cliente'))
$this->redirect('moduloquetedelagana/index');
//Instanciamos el formulario que hemos creado en el primer paso.
$this->form = new LoginForm();
}
//Esta es la acción que se ejecuta cuando queremos hacer logout(deslogearse).
public function executeLogout(sfWebRequest $request){
//Borramos todas las variables de sesion creadas bajo el namespace de cliente.
$this->getUser()->getAttributeHolder()->removeNamespace('cliente');
//Quitamos la autenticación del usuario.
$this->getUser()->setAuthenticated(false);
//Eliminamos la credencial. Para borralas todas de golpe: $this->getUser->clearCredentials();
$this->getUser()->removeCredential('cliente');
$this->redirect('login/index');
}
} |
La seguridad de este login es ridícula, lo he hecho básico para explicarlo mas rápido, no lo toméis como referencia.
Ahora la vista:
/apps/app/modules/login/templates/indexSuccess.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
<?php use_stylesheets_for_form($form) ?>
<?php use_javascripts_for_form($form) ?>
<div class="login">
<h1>Acceso a clientes</h1>
<form action="<?php echo url_for('login/index')?>" method="post">
<table>
<tbody>
//Mostramos el mensaje flash, en caso de que haya.
<?php if ($sf_user->hasFlash('error')): ?>
<div class="flash_error"><?php echo $sf_user->getFlash('error') ?></div>
<?php endif; ?>
//Printamos el formulario.
<?php echo $form; ?>
<tr>
<th></th>
<td>
<input type="submit" value="Acceder" name="login">
</td>
</tr>
</tbody>
</table>
</form>
</div> |
Pues creo que no se me olvida nada. Bueno solo os queda poner por ahi un botón para hacer logout que se active según el usuario este autenticado o no, en el caso de que este en el layout. Espero que os sirva de ayuda.