Passo-a-Passo web2py, 6º Passo

No último passo conseguimos realizar pesquisas dentro do nosso sistema e exibir os resultados na tela, ou seja, entendemos todo o sistema de views! Agora já temos uma noção geral sobre toda a organização do web2py compreendendo os Models, os Controllers e as Views.

Isso quer dizer que, com o conhecimento que temos até agora, já somos capazes de desenvolver uma aplicação completa no web2py. Por isso, vamos começar a entender detalhes mais específicos para aprimorar nosso controle de estoque para a locadora.

Segue o índice para que você acompanhe também os outros passos:

Autenticação

Um dos detalhes mais importantes que temos nas aplicações que vemos na web é a forma como realizamos o controle de usuários. Precisamos projetar uma forma de armazenar os usuários, proporcionar funções específicas para eles e criar diferentes níveis de permissão. Para entender como isso funciona, podemos organizar qualquer sistema da web de forma semelhante a:

Funções (páginas) do Usuário

  • Cadastro
  • Login/Logout
  • Perfil
  • Recuperar Senha
  • Etc.

Tipos de usuário (Permissões)

  • Administrador
  • Moderador
  • Usuário padrão
  • Visitante
  • Etc.

Os nomes das funções e das permissões variam dependendo do sistema que você está utilizando, mas em geral encontramos esse tipo de estrutura em qualquer sistema que possua autenticação.

O que deixamos visível aqui é que o usuário da plataforma possui sempre funções específicas para ele, ou seja, existem páginas que existem apenas porque existem usuários e o único propósito delas é servir o usuário de alguma forma.

Além disso, podemos ter vários tipos de usuários diferentes. Por exemplo, um administrador da plataforma tem permissão para realizar qualquer ação dentro da plataforma; um moderador tem permissão para gerenciar o conteúdo de outros usuários; um usuário padrão possui permissão apenas de interagir com seu próprio conteúdo e ler o dos outros; um visitante, que não existe no cadastro de usuários ou não está logado, só tem permissão para ler o conteúdo disponível.

Entendido isso, temos uma ideia do que vamos precisar: uma forma de armazenar o usuário, páginas específicas para nossos usuários e permissões diferentes dentro da plataforma. E, para ficar tudo melhor, vamos ver que o web2py já traz tudo isso para nós!

Tabelas de Usuário

Vimos no 2º passo desta sequência que o web2py cria, sozinho, as tabelas de usuário e todas aquelas relacionadas a autenticação. Para relembrar, ele faz o seguinte no arquivo db.py dos models:

from gluon.tools import Auth

auth = Auth(db)
auth.define_tables(username=False, signature=False)

A partir da classe Auth, ele se conecta ao banco de dados e, usando o método define_tables(), cria as tabelas de autenticação, que são as seguintes:

  • auth_user
  • auth_group
  • auth_membership
  • auth_permission
  • auth_event
  • auth_cas

OBS: Neste passo-a-passo, apenas as três primeiras irão nos interessar e você poderá se aprofundar nas funções das restantes em momentos posteriores.

A primeira tabela, auth_user, é responsável por armazenar nossos usuários e todas as informações referentes a eles, como nome, sobrenome, e-mail, senha (criptografada), etc.

A segunda, auth_group, cria grupos para o usuário. Estes grupos são os tipos de usuários que nossa plataforma terá. O web2py, por padrão, cria um novo grupo para cada novo usuário, sem ter permissões específicas definidas. Para separar os usuários em grupos específicos, somos nós que teremos que fazê-lo (e vamos ver como!).

A terceira tabela, auth_membership, associa as duas primeiras. Ou seja, é nela que vamos falar qual usuário pertence a qual tipo/grupo para o web2py e ele vai conseguir checar se o usuário tem permissão para fazer aquilo que está pedindo.

Páginas de Usuário

Ok, temos tabelas para armazenar os nossos usuários e lidar com permissões, mas então teremos que fazer todo o resto? Não! O web2py também traz nossas páginas de usuário prontas, e você pode vê-las no controller default.py. Neste arquivo, existirá uma função chamada user:

def user():
    """
    exposes:
    http://..../%5Bapp%5D/default/user/login
    http://..../%5Bapp%5D/default/user/logout
    http://..../%5Bapp%5D/default/user/register
    http://..../%5Bapp%5D/default/user/profile
    http://..../%5Bapp%5D/default/user/retrieve_password
    http://..../%5Bapp%5D/default/user/change_password
    http://..../[app]/default/user/manage_users (requires membership in
    use @auth.requires_login()
    @auth.requires_membership('group name')
    @auth.requires_permission('read','table name',record_id)
    to decorate functions that need access control
    """
    return dict(form=auth())

Todas as páginas de usuário estão dentro de uma só, que é esta função user. Para alternar entre elas, vamos alterar o argumento da URL, como o próprio comentário da função mostra. As páginas são:

  • Login
  • Logout
  • Register (cadastro)
  • Profile (editar perfil)
  • Retrieve Password (recuperar senha)
  • Change Password (trocar senha)

Todas essas páginas estão integradas com as tabelas que foram criadas pelo Auth do web2py e funcionam sem que precisemos mudar nem uma vírgula. Elas também são geradas pelo módulo Auth e cada uma delas é, basicamente, um formulário (como aquele SQLFORM que vimos antes) que é gerado de forma automática.

Permissões

Até agora, se seguirmos desta forma, veremos que qualquer usuário cadastrado terá acesso a qualquer página, mas isso não é o que queremos. Podemos deixar todos os usuários verem as páginas que exibem os filmes, mas não queremos que todos eles cadastrem locações, apenas os funcionários da locadora. E como faremos isso?

O primeiro passo é criar um grupo de usuários que terá essas funções específicas dentro da nossa locadora: o grupo de funcionários. Para fazer isso, podemos usar o próprio AppAdmin, como já vimos antes, e adicionar um novo registro na tabela auth_group.

Adicionando novo grupo "funcionario"

Adicionando novo grupo “funcionario”

O registro de grupo precisa receber apenas um título e uma descrição, principalmente para facilitar nossa vida quando formos associar os usuários a um grupo.

Agora, para colocarmos cada usuário que é funcionário no grupo de funcionários precisamos acessar a tabela auth_membership. Abrindo com o AppAdmin, veremos que esta tabela já possui registros caso tenhamos usuários cadastrados no sistema (caso não tenha, faça o teste cadastrando um usuário pela função /user/register que vimos).

Como mencionei antes, o web2py cria um novo grupo para cada novo usuário cadastrado. Por isso, precisamos editar os usuários que são funcionários para que eles pertençam ao grupo certo. Edite os registros do auth_membership para colocar seus usuários que são funcionários no grupo funcionario.

Edição da membership de um usuário

Edição da membership de um usuário

Separamos nossos usuários que são funcionários em um grupo específico, mas isto apenas não basta para o programa saber quais páginas este grupo tem permissão de acessar e quais não. O web2py consegue identificar que os usuários possuem diferentes grupos, mas ele não consegue adivinhar quais funções estão disponíveis para estes grupos e quais não! Por isso, precisamos indicar essas páginas. Para fazer isso, vamos usar decorators.

Decorators são como mensagens que vêm antes do início da declaração de uma função ou classe e servem para inserir algum código ou validação naquela função.

Neste caso, temos dois decorators principais:

  • @auth.requires_login()
  • @auth.requires_membership(‘nome_do_grupo’)

O primeiro decorator faz com que, para acessar determinada página, o usuário precisa obrigatoriamente estar logado. O segundo indica que, além de estar logado, ele precisa ter uma permissão específica, ou seja, pertencer a um grupo.

E como vamos usar estes decorators? Basta colocá-los antes da função da página que deve possuir tais restrições. Por exemplo, não queremos que nenhum usuário que não seja do grupo de funcionários acesse a página de cadastrar novos filmes, então podemos fazer:

@auth.requires_membership('funcionario')
def novo_filme():
    form = SQLFORM(Filmes)
    if form.process().accepted:
        session.flash = 'Novo vídeo cadastrado: %s' % form.vars.titulo
        redirect(URL('novo_filme'))
    elif form.errors:
        response.flash = 'Erros no formulário!'
    else:
        if not response.flash:
            response.flash = 'Preencha o formulário!'
    return dict(form=form)

Assim, o acesso a essa página ficará restrito. Agora, é seu dever aplicar qualquer um destes decorators nas outras páginas onde julgar necessário.

E o que acontecerá se um usuário sem permissão tentar acessar essa página? Temos duas opções:

  1. Se o usuário não estiver logado, ele será redirecionado para a página de login;
  2. Se o usuário estiver logado, será exibida uma mensagem alertando que o usuário não possui permissão para acessar a página.

Conclusão

Este passo não foi tão prático como os outros pois foi voltado para entender o conceito de autenticação que o web2py traz consigo. O sistema de autenticação que vimos até agora é padrão do web2py e, como pudemos perceber, vem pronto para ser usado e funciona de forma automática. Aqui entendemos tudo que é necessário para utilizá-lo sem complicações.

Porém, ele não é a única forma de se trabalhar com autenticação de usuários no framework. Você pode criar seu próprio sistema de autenticação ou dar uma olhada na seção de Controle de Acessos do livro do web2py e ver outras formas de fazer as mesmas coisas.

Perceba também que várias etapas do que fizemos foram manuais utilizando o AppAdmin, mas existem formas de fazê-las de maneira mais automatizada. Caso você tenha interesse, tome isso como uma tarefa para aumentar seu aprendizado!

Para acompanhar o que foi feito até agora, você pode recorrer ao repositório do GitHub onde está o código atualizado deste passo: https://github.com/juliarizza/locadora.

Espero vocês no próximo passo!

Anúncios

11 comentários sobre “Passo-a-Passo web2py, 6º Passo

  1. José Cardoso disse:

    Oi Júlia bem didático este material, porém parei em um erro no 6. passo e sou bastante noob, se puder dar um dica ficarei muito grato.

    Registration needs verification e a partir desta mensagem não consigo fazer nada (inclusão, alteração ou exclusão nos apps).

    Curtir

  2. DeadHeat disse:

    Estou desenvolvendo uma aplicação baseada nesta locadora, eu queria que os usuarios pudessem visualizar uma lista com os filmes locados por eles, e estou com dificuldades, pois os usuarios comuns cadastrados visualizam essa lista como um todo e não individualmente.

    Curtir

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

w

Conectando a %s