¡La versión 2.0 de Play ya está lista! Ayúdanos a traducir la documentación de la útlima versión y sigue nuestro progreso.

Manuales, tutoriales & referencias

Consulte

Contenidos

Elija la versión

Buscar

Busque con google

Libros

Agregando autenticación

Ahora que tenemos un área de administración necesitamos agregarle la autenticación. Por suerte, Play tiene un módulo para esto, cuyo nombre es Secure.

Habilitando el módulo Secure

Habilite el módulo Secure en el archivo yabe/conf/application.conf y reinicie la aplicación.

# Importar el módulo Secure
module.secure=${play.path}/modules/secure

Después de reiniciar, Play debería reportar que el módulo está cargado.

El módulo Secure viene con un conjunto de rutas ('routes') por defecto que usted puede habilitar fácilmente en el archivo yabe/conf/routes (o también podríamos declarar nuestras propias rutas):

# Importar rutas de Secure
*       /                                       module:secure

Protegiendo los controladores de administración (admin)

El módulo proporciona un controlador llamado controllers.Secure que declara todos los interceptores necesarios. Por supuesto, nosotros simplemente podría heredar de este controlador, pero debido a que Java tan sólo soporta herencia simple, este enfoque presentaría ciertas limitaicones.

Por lo tanto, en vez de heredar directamente del controlador Secure, podemos anotar los controladores de administración con la anotación @With para decirle a Play que invoque al interceptor correspondiente:

package controllers;
 
import play.*;
import play.mvc.*;
 
@With(Secure.class)
public class Posts extends CRUD {    
}

Repita el procedimiento para los controladores Comments, Users y Tags.

Ahora si intenta acceder a cualquier acción de administración, debería ver una página para inicio de sesión:

De hecho, por ahora puede probar con cualquier combinación de nombre de usuario y contraseña, y funcionará.

Personalizando el proceso de autenticación

La aplicación debe proporcionar una instancia de controllers.Secure.Security para personalizar el proceso de autenticación. Al crear nuestra versión particular de esta clase podremos especificar con exactitud la manera en que deberían autenticarse los usuarios.

Cree el archivo yabe/app/controllers/Security.java y redefina el método authenticate():

package controllers;
 
import models.*;
 
public class Security extends Secure.Security {
	
    static boolean authenticate(String username, String password) {
        return true;
    }
    
}

Como ya tenemos los objetos User como parte del modelo del blog, es fácil implementar una versión de este método que valide el usuario y password correctamente:

static boolean authenticate(String username, String password) {
    return User.connect(username, password) != null;
}

Ahora vaya a http://localhost:9000/logout para finalizar la sesión de usuario e intente iniciar una nueva con uno de los usuarios importados desde el archivo initial-data.yml, como por ejemplo: bob@gmail.com/secret.

Mejorando el área de administración

Hemos creado el área de administracion usando el módulo CRUD, pero todavía no está bien integrada con la interfaz de usuario blog. Por lo que empezaremos a trabajar en una nueva área de administración, la cual dará a cada autor acceso a sus propias publicaciones (posts). Todas las funciones CRUD de administración seguirán disponibles para los usuarios con perfil (profile) de super administrador.

Vamos a crear un nuevo controlador Admin para la parte de administración:

package controllers;
 
import play.*;
import play.mvc.*;
 
import java.util.*;
 
import models.*;
 
@With(Secure.class)
public class Admin extends Controller {
    
    @Before
    static void setConnectedUser() {
        if(Security.isConnected()) {
            User user = User.find("byEmail", Security.connected()).first();
            renderArgs.put("user", user.fullname);
        }
    }
 
    public static void index() {
        render();
    }
    
}

Y ajuste la definición de rutas (routes) en yabe/conf/routes:

# Administracion
GET     /admin/?                                Admin.index
*       /admin                                  module:crud

Recuerde que el orden en que definimos las entradas en el archivo routes es significativo; ya que la primera línea que concuerde con la petición HTTP será utilizada. Esto significa que las entradas que corresponden al controlador Admin deben venir antes de la segunda línea mostrada en el código de arriba, la cual corresponde a todas las otras peticiones de las páginas /admin del módulo CRUD. De lo contrario, la dirección /admin/, sería capturada por la línea module:crud e invocaría a la acción CRUD.index en vez de Admin.index.

Ahora cree un enlace con el texto ‘Log in to write something’ en la plantilla yabe/app/views/main.html que llame a este controlador:

…
<ul id="tools">
    <li>
        <a href="@{Admin.index()}">Log in to write something</a>
    </li>
</ul>
…

Lo último para lograr que todo funcione es crear la plantilla yabe/app/views/Admin/index.html. Vamos a comenzar con algo simple:

Welcome ${user}!

Ahora, vaya a la página de inicio (home) del blog, haga clic en el enlace ‘Log in to write something’ y debería ver la nueva área de administración:

¡Buen comienzo! Pero como tendremos varias páginas en esta área de administración, necesitamos una super-plantilla. Vamos a crearla en el archivo yabe/app/views/admin.html:

<!DOCTYPE html>
<html>
    <head>
        <title>Administration</title>		
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        #{get 'moreStyles' /}	
        <link rel="stylesheet" type="text/css" media="screen" 
                href="@{'/public/stylesheets/main.css'}" />
        <link rel="shortcut icon" type="image/png" 
                href="@{'/public/images/favicon.png'}" />
        <script src="@{'/public/javascripts/jquery-1.4.2.min.js'}"></script>
        <script src="@{'/public/javascripts/jquery.tools-1.2.5.toolbox.expose.min.js'}"></script>
    </head>
    <body id="admin">
        
        <div id="header">
            <div id="logo">
                yabe. <span>administration</span>
            </div>
            <ul id="tools">
                <li>
                    <a href="@{Secure.logout()}">Log out</a>
                </li>
            </ul>
        </div>
        
        <div id="main">
            #{doLayout /} 
        </div>
        
        <p id="footer">
            Yabe is a (not so) powerful blog engine built with the 
            <a href="http://www.playframework.org">Play framework</a>
            as a tutorial application.
        </p>
        
    </body>
</html>

Como pueden ver, es muy similar a la plantilla usada para la parte frontal del sistema de blog. En esta plantilla se ha reemplazado el enlace de Log in por el enlace Log out que invoca la accion logout del controlador Secure que proporciona el módulo secure.

Ahora vamos a utilizarla en la plantilla yabe/app/views/Admin/index.html:

#{extends 'admin.html' /}
 
Welcome ${user}!

¡Y actualice la página!

Si hace clic en el enlace Log out la aplicación lo enviará de nuevo al formulario de inicio de sesión:

Ese es el comportamiento por defecto del módulo secure para manejar los eventos de cierre de sesión (log out). Pero esto también puede ser fácilmente personalible redefiniendo el método onDisconnected() en la clase controllers.Security:

static void onDisconnected() {
    Application.index();
}

Puede hacer lo mismo para el evento onAuthenticated():

static void onAuthenticated() {
    Admin.index();
}

Agregando roles

En realidad, necesitamos dos areas de administración: una para los simples editores y otra para el super administrador. Como puede observar, el objeto User del modelo tiene un campo isAdmin que indica si el usuario tiene derechos de super administrador o no.

El módulo secure no sólo provee manejo de autenticación sino tambien manejo de autorización, a través de los llamados perfiles (profiles). Para crear un perfil de administrador (admin), solo necesita redefinir el método check() de la clase controllers.Security():

static boolean check(String profile) {
    if("admin".equals(profile)) {
        return User.find("byEmail", connected()).<User>first().isAdmin;
    }
    return false;
}

Ahora podemos mostrar un menú de administración si el usuario tiene el rol (role) de administrador (admin). Modifique el archivo views/admin.html para integrar un menú en la parte superior de la página:

…
<div id="main">
    
    <ul id="adminMenu">
        <li class="${request.controller == 'Admin' ? 'selected' : ''}">
            <a href="@{Admin.index()}">My posts</a>
        </li>
        #{secure.check 'admin'}
            <li class="${request.controller == 'Posts' ? 'selected' : ''}">
                <a href="@{Posts.list()}">Posts</a>
            </li>
            <li class="${request.controller == 'Tags' ? 'selected' : ''}">
                <a href="@{Tags.list()}">Tags</a>
            </li>
            <li class="${request.controller == 'Comments' ? 'selected' : ''}">
                <a href="@{Comments.list()}">Comments</a>
            </li>
            <li class="${request.controller == 'Users' ? 'selected' : ''}">
                <a href="@{Users.list()}">Users</a>
            </li>
        #{/secure.check}
    </ul>
    
    #{doLayout /} 
</div>
…

Note como usamos el tag #{secure.check /} para mostrar parte del menú solo a los usuarios con el rol admin.

Sin embargo ¡esto no es suficiente para resguardar la sección CRUD del área de administración! Si un usuario conoce la URL aún puede acceder a esa parte del sitio. Por lo que también tenemos que proteger los controladores; lo cual podemos hacer fácilmente usando la anotación @Check. Por ejemplo, para el controlador Posts haríamos lo siguiente:

package controllers;
 
import play.*;
import play.mvc.*;
 
@Check("admin")
@With(Secure.class)
public class Posts extends CRUD {    
}

Repita el procedimiento para los controladores Tags, Comments y Users. Ahora pruebe cerrando sesión e iniciando una nueva con un usuario estándar (tal como jeff@gmail.com/secret). No debería ver los enlaces de administración CRUD. Y si intenta acceder directamente al URL http://localhost:9000/admin/users obtendrá una respuesta HTTP 403 Forbidden.

Personalizando la apariencia de las páginas CRUD

Todo esto está muy bien, pero cuando vamos a la parte CRUD del área de administración perdemos el estilo (layout) de nuestra página inicial. Esto se debe a que el módulo CRUD proporciona su propio estilo. Pero por supuesto nosotros podemos redefinirlo. Use el siguiente comando Play:

play crud:ov --layout

Y verá una nueva plantilla /yabe/app/views/CRUD/layout.html. Vamos a reemplazar su contenido para integrarla elegantemente con nuestro estilo descrito en el archivo admin.html:

#{extends 'admin.html' /}
#{set 'moreStyles'}
    <link rel="stylesheet" type="text/css" media="screen" 
        href="@{'/public/stylesheets/crud.css'}" />
#{/set}
 
<div id="crud">
 
    #{if flash.success}
    	<div class="crudFlash flashSuccess">
    		${flash.success}
    	</div>
    #{/if}
    #{if flash.error || error}
    	<div class="crudFlash flashError">
    		${error ?: flash.error}
    	</div>
    #{/if}
 
    <div id="crudContent">
    	#{doLayout /}
    </div>
 
</div>

Como pueden ver, reutilizamos crud.css y lo incluimos en admin.html usando el mecanismo para manejar variables de plantillas get/set. Ahora si prueba la parte CRUD del área de administración, verá que está correctamente integrada con el estilo del área de administración:

Aplicando estilo a la página de inicio de sesión

El área de administración ya está casi completa desde el punto de vista gráfico. Lo último que queda por ajustar es la página de inicio de sesión. Como siempre, esto es fácilmente personalizable haciendo una redefinicion del archivo CSS que usa por defecto:

play secure:ov --css

Dejaremos el archivo CSS tal como está, pero importaremos nuestro main.css al principio. Sólo agregue esto en la primera línea del archivo yabe/public/stylesheets/secure.css:

@import url(main.css);
…

Y personalice los mensajes de la página de inicio de sesión, agregando estás líneas al archivo yabe/conf/messages:

secure.username=Your email:
secure.password=Your password:
secure.signin=Log in now

Continúa con: Creando un área para editores personalizada.