[SP-pm] Validar session no Catalyst

Eden Cardim edencardim at gmail.com
Tue Jul 12 09:09:23 PDT 2011


>>>>> "Nelson" == Nelson Ferraz <nferraz em gmail.com> writes:

    Nelson> Sem querer iniciar uma flamewar, mas este é apenas mais um exemplo
    Nelson> onde o Catalyst complica demais algo que deveria ser simples.

Apesar do título da mensagem original ser sobre sessões, a dúvida do
Lucas era sobre outra coisa, então o exemplo não procede.

A princípio, não entendi o código de exemplo porque sessões e usuários
são conceitos ortogonais, mas ok, pra fazer exatamente a mesma coisa no
catalyst (mesmo sem fazer sentido):

    Nelson> Veja como isso pode ser feito no Mojolicious:

,----[ # 1: verificar uma variável de sessão ]
| get '/' => sub {
|     my $self = shift;
|     my $username = $self->session('username');
|     self->redirect_to('/login') if !$username;
|     $self->render( text => "Hello, $username" );
| };
`----

sub root :Path('/') {
    my($self, $c) = @_;
    my $username = $c->session->{username};
    $c->res->redirect('/login') if !$username;
    $c->res->body("Hello $username");
}

Não muda muita coisa, e se fosse só pelo golf, o Catalyst ainda levava.

,----[ 2: definir uma variável de sessão ]
| get '/login' => sub {
|     my $self = shift;
| 
|     my $username = $self->param('username');
|     my $password = $self->param('password');
| 
|     if ($username eq 'foo' and $password eq 'bar') {
|         $self->session( username => $username );
|         $self->redirect_to('/');
|     }
| 
|     $self->render( text => "Please use:
| http://localhost:3000/login?username=xxx;password=yyy" );
| };
`----

sub login :Path {
    my($self, $c) = @_;

    my($username, $password) = @{$self->params}
      {qw(username password)};

    if($username eq 'foo' and $password eq 'bar') {
      $c->session->{username} = $username;
      $c->res->redirect('/');
    }

    $c->res->body("Please use: http://localhost:3000/login?username=xxx;password=yyy");
}

    Nelson> # 3: remover uma variável de sessão

,----[ 3: remover uma variável de sessão ]
| get '/logout' => sub {
|     my $self = shift;
| 
|     my $username = $self->session('username');
|     $self->session( username => undef ); # poderia ter usado "expire"
| 
|     $self->render( text => "Bye bye, $username" );
| };
`----

sub logout :Path {
    my($self, $c) = @_;
    my $username = delete $c->session->{username};
    $c->res->body("Bye, bye, $username");
}

Claro que eu nunca recomendaria que se usasse autenticação dessa forma,
a abordagem padrão do catalyst para autenticação é bem mais simples que
isso:

sub login :Path {
    my($self, $c) = @_;
    $c->authenticate()
      and $c->res->redirect('/'), return;
    $c->res->body('wrong username or password');
}

sub login :Path {
    my($self, $c) = @_;
    $c->logout();
}

O sistema de autenticação do Catalyst é extremamente flexível, robusto e
completo, e tudo funciona colando os pedaços que você precisa, assim a
aplicação não enche de bloat. Por exemplo, outro dia precisei
implementar uma funcionalidade de sudo (um usuário com privilégios
suficientes, precisaria ser capaz de trocar sua sessão pruma sessão de
outro usuário qualquer). Um desenvolvedor do projeto, que aprendeu a
programar perl há 4 meses implementou (completo, com testes, etc.), em 2
horas de trabalho. 30 minutos pra implementar a funcionalidade, 90 pra
implementar os testes unitários e de integração. No final das contas, o
core do código funcional ficou assim:

$c->authenticate({ email => $email,  pasword => 'DUMMY' }, 'sudo')
  if $c->user->check_user_roles('admin');

Inclusive, eu experimentei novamente o mojolicious outro dia porque o
thiago precisa de autenticação prum projeto dele, mas o plugin que
implementava basic http auth tava bugado por incompatibilidade com uma
versão que saiu a mais de 10 releases atrás. O thiago submeteu um patch
e tal mas isso me faz questionar quantas pessoas realmente estão usando
o mojolicious em produção, porque basic http auth é uma funcionalidade
trivial e muito exigida em apps do mundo real, se tivesse alguém usando
em produção, já teriam esbarrado com o problema e atualizado o plugin na
versão seguinte.

    Nelson> PS: Até onde eu sei, o Eden estava trabalhando em um projeto que
    Nelson> traria esse tipo de simplicidade para o Catalyst. Em que pé está esse
    Nelson> projeto, Eden?

Na verdade, não é um projeto pra trazer simplicidade, a simplicidade já
está no core. Só é uma extensão que inclui uma forma alternativa de
declarar regras de dispatch:

https://github.com/edenc/Catalyst-Lite/blob/master/lib/Catalyst/Lite.pm

Estou investindo meu tempo livre aos poucos pra incluir mais sintaxe, o
problema é que esse projeto não tá com uma prioridade muito alta na
minha fila porque a única utilidade pra ele é brincar de golf.

-- 
   Eden Cardim       Need help with your Catalyst or DBIx::Class project?
  Code Monkey                    http://www.shadowcat.co.uk/catalyst/
 Shadowcat Systems Ltd.  Want a managed development or deployment platform?
http://blog.edencardim.com/            http://www.shadowcat.co.uk/servers/
http://twitter.com/#!/edenc


More information about the SaoPaulo-pm mailing list