Wallace ReisPublicado em 01/03/2010
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.
Para realizar a autenticação, precisa-se de um conjunto de plugins sendo eles:
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
.
Credential
Store
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
/;
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.
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
(...)
(...)
Existem apenas três partes que se referem a implementação básica de autenticação.
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
}
}
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
}
}
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
}
Wallace Reis <wallace@reis.org.br>