Autenticação em aplicações usando Catalyst

Wallace Reis
Publicado em 01/03/2010

Autenticação em aplicações usando Catalyst

O objetivo da autenticação é estabelecer ou confirmar a identidade de um usuário, o qual pode ser uma pessoa ou grupo de pessoas que usem as mesmas credenciais, provendo desta forma, suporte as demais partes do sistema como controle de acesso (autorização) e customização da interface com o usuário. Neste artigo, veremos como realizar autenticação básica em aplicações que usam o web framework Catalyst com o plugin padrão, porém não se é obrigado a usar este plugin, o Catalyst é flexível suficiente para realizar a autenticação e autorização da forma que se quer implementar.

Requisitos

Para realizar a autenticação, precisa-se de um conjunto de plugins sendo eles:

* Catalyst::Plugin::Authentication

Este plugin provê a estrutura básica para aplicações com Catalyst realizarem autenticação e autorização, contendo também alguns plugins de Credential e Store.

* Um plugin de Credential
* Um plugin de Store
* Plugins para controle de sessão

A fim de permitir que teus usuários permaneçam conectados à sua aplicação através das páginas, é preciso guardar este estado de alguma forma tanto do lado do servidor quanto no cliente. Pode-se usar o recomendado pelo Catalyst para tal fim, Catalyst::Plugin::Session, juntamente com um plugin de State e outro de Store.

Antes de prosseguir, lembre-se de carregar os plugins requeridos na classe da aplicação.

    use Catalyst qw/
        Authentication
        Session
        Session::Store::Foo
        Session::State::Bar
    /;

Catalyst::Plugin::Authentication

A autenticação no Catalyst está projetada para ser bem flexível aos vários tipos de processos que se podem realizar, basicamente dividida em módulos de armazenamento (Store) e de verificação (Credential). O Credential é responsável por verificar a identidade do usuário, geralmente comparando a informação provida por este com a informação encontrada no Store. Estes módulos são carregados em conjunto por meio de realms, permitindo assim à aplicação ter múltiplos métodos de autenticação de usuários. Toda aplicação que realize autenticação deve ter ao menos um realm que é o default, mas pode-se ter quantos forem necessários.

Configuração

Os itens da configuração vão depender dos módulos de Credential e Store que se tenha decidio usar. A seguir, temos um exemplo de configuração (no formato do Config::General) que utiliza dois métodos de autenticação com o padrão para o realm de password. Consulte a documentação para detalhes sobre a configuração de cada tipo de Credential e Store, bem como a do Catalyst::Plugin::Authentication.

    
        default_realm password
        
            
                class Password
                password_field passwd
                password_type crypted
            
            
                class DBIx::Class
                user_class DB::LocalAccount
            
        
        
            
                class Signature
                signature_field sign
                session_field session_data
            
            
                class DBIx::Class
                user_class DB::LocalAccount
            
        
    

Até a versão 0.10008 do plugin de autenticação, você precisaria colocar toda os realms dentro da chave realms.

    
        default_realm password
        
            

            (...)

            
            

            (...)

            
        
    

Implementação

Existem apenas três partes que se referem a implementação básica de autenticação.

* Login
* Verificar que um usuário está "logado"
* Logout

Login

Esta parte envolve - geralmente a partir de um formulário - obter as credenciais do usuário e verificar que este é valido. Pode-se usar um processador de formulários como o HTML::FormHandler, mas não é requisito. Para fazer login do usuário, usa-se o método authenticate a partir de uma action num controller.

    sub login : Action {
        my ( $self, $c ) = @_;
        my $params = $c->req->body_params;
        if ( $params->{'username'} && $params->{'password'} ) {
            if ( $c->authenticate({ map { $_ => $params->{$_} } qw/username password/ }) ) {
                # usuário válido e autenticado
                # redirecione para algum caminho da sua aplicação
            } else {
                # mostrar a página com o formulário de autenticação e uma mensagem de erro
            }
        } else {
            # mostrar a página com o formulário de autenticação
        }
    }

Verificar que um usuário está "logado"

Em determinados caminhos da aplicação, é necessário que se tenha um usuário "logado", como por exemplo uma página de preferências ou se a aplicação utiliza dados deste para gerar e mostrar informações numa página. Deste modo, faz-se necessário retornar para o passo de login caso a verificação falhe. Para tal fim, pode-se usar alguns métodos como

* user_exists

Retorna verdeiro se um usuário está "logado". Se esta for a única informação necessária, não interessando qual usuário especificamente é, a depender do mecanismo de armazenamento, este método pode ser muito mais eficiente. A diferença entre este método e o user é que este retornará verdadeiro, mesmo se o usuário "logado" não foi ainda recuperado a partir do armazenamento.

* user_in_realm

Semelhante ao user_exists, exceto que apenas retorna verdadeiro se o usuário está "logado" -e- foi recuperado a partir do realm fornecido.

* user

Retorna o atual usuário "logado", ou undef se não há algum.

Como por exemplo

    sub requires_user : Action {
        my ( $self, $c ) = @_;
        if ( $c->user_exists ) {
            # usuário "logado"
        } else {
            # retorna ao passo de login
        }
    }

Logout

E por último a mais simples, resume-se a apenas chamar o método logout e redirecionar o usuário para o caminho de login ou algum outro.

    sub logout : Action {
        my ( $self, $c ) = @_;
        $c->logout;
        # redirecione
    }

Veja também

AUTOR

Wallace Reis <wallace@reis.org.br>

blog comments powered by Disqus