Documentação dos Sistemas de Autenticação do Django
Views de Autenticação (Login, Logout, Troca de senha, Reset de senha, etc)
Crie um novo app
Vamos separar do nosso módulo principal o gerenciamento de usuários para não ficar muita coisa em um módulo só. Para isso, crie um app chamado “usuarios”:
python manage.py startapp usuarios
Crie um arquivo de urls
Dentro do módulo novo, crie um arquivo “urls.py” com o seguinte código (o básico para criar e usar as urls):
from django.urls import path
from django.contrib.auth import views as auth_views
urlpatterns = [
# Aqui vão suas urls
]
Crie o diretório dos templates
Dentro do app “usuarios”, crie também uma pasta “templates” com uma pasta “usuarios” dentro dela.
Utilizando as Views existentes para Login
Existe uma View pronta já para funcionar como tela de login, basta criar uma url e apontar para ela, indicando qual o template será usado para fazer o login. É possível já usar um template que existe ou criar um novo só para login.
Primeiro crie a URL:
path('login/', auth_views.LoginView.as_view(
template_name='usuarios/login.html',
extra_context={'titulo': 'Autenticação'}
), name='login'),
E agora crie o template login.html dentro do módulo “usuarios” com o seguinte conteúdo (que pode variar de acordo com o seu e no geral é igual algum form.html que você já tem):
{% extends 'adocao/base.html' %} {% load static %} {% load crispy_forms_tags %} {% block header %} {% endblock %} {% block container %} <div class="container py-5"> <div class="row mt-5"> <div class="col-lg"> <h3>{{ titulo }}</h3> </div> </div> <div class="row"> <div class="col-lg-5"> <form method="post"> <!-- Todo formulário tem que ter essa validação --> {% csrf_token %} <!-- Gera o formulário --> {{ form|crispy }} <button type="submit" class="btn btn-primary"> Entrar </button> </form> </div> </div> </div> {% endblock %}
Ative o módulo no settings.py
Agora é necessário ativar o novo módulo no settings.py para que ele funcione normalmente. Para isso, dentro de “INSTALLED_APPS” adicione (antes de fechar o vetor [ …. ]):
'usuarios.apps.UsuariosConfig',
Importe as URLS para o projeto padrão
No arquivo “urls.py” que está junto com settings.py, importe o arquivo de urls que foi criado lá no módulo “usuarios”:
path('', include('usuarios.urls')),
Pronto, o login já pode ser feito! Acesse: http://127.0.0.1:8000/login/
Por enquanto fizemos apenas a autenticação. Agora será necessário informar as páginas que só podem ser acessadas se o usuário fizer login.
Redirecionar o usuário depois do login
Por padrão, o usuário vai ser redirecionado para http://127.0.0.1:8000/accounts/profile/ depois de fazer login, mas não temos esse endereço. Podemos alterar a URL que o usuário será redirecionado após o login (LOGIN_REDIRECT_URL) e a URL que o usuário vai ver se tentar acessar alguma página que não tem login (LOGIN_URL). Configure também pra onde o usuário vai depois de fazer logout (LOGOUT_REDIRECT_URL). Adicione no settings.py essas duas constantes e o nome da URL:
# Nome da URL em que o usuário será redirecionado
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth
LOGIN_REDIRECT_URL = 'index'
LOGIN_URL = 'login'
LOGOUT_REDIRECT_URL = 'login'
Mais informações podem ser consultadas aqui: https://docs.djangoproject.com/en/2.1/ref/settings/#auth
Crie a URL de logout
Dentro do “urls.py” que está no módulo “usuarios”, crie a URL de logout que utiliza a classe “LogoutView”:
path('sair/', auth_views.LogoutView.as_view(), name="logout"),
Crie um link para login no seu menu
Crie um link para acessar essa página:
<a class="nav-link" href="{% url 'login' %}">Entrar</a>
Crie um link para logout no seu menu
Crie um link para acessar essa página:
<a class="nav-link" href="{% url 'logout' %}">Sair</a>
Definindo as páginas que precisam de login para serem acessadas
Lá nos seus arquivos “views.py”, independente do módulo, importe a classe que vai fazer as páginas requisitarem a autenticação para serem exibidas:
from django.contrib.auth.mixins import LoginRequiredMixin
Criando as heranças
Agora, nas suas classes/métodos dentro do views.py basta criar uma herença para LoginRequiredMixin e adicionar o atributo login_url = reverse_lazy(‘login’).
Exemplo:
class CidadeUpdateView(LoginRequiredMixin, UpdateView):
login_url = reverse_lazy('login')
...
Atenção: O LoginRequiredMixin precisa ser importado antes de outras coisas e o método reverse_lazy tem que estar importado (from django.urls import reverse_lazy).
Criando uma tela para o usuário alterar sua senha
Também existe uma View que faz todo esse trabalho para nós (PasswordChangeView). Ela é semelhante à url de login e precisamos passar mais um parâmetro pra ela: “success_url”, que nada mais é do que para onde o usuário vai ser redirecionado após alterar a senha.
Para isso, vá no “urls.py” do módulo “usuarios” e importe o “reverse_lazy” no início do arquivo:
from django.urls import reverse_lazy
Agora crie a url conforme o exemplo abaixo:
path('alterar-minha-senha/', auth_views.PasswordChangeView.as_view(
template_name='usuarios/login.html',
extra_context={'titulo': 'Alterar senha atual'},
success_url=reverse_lazy('index')
), name="alterar-senha"),
Pronto, basta acessar http://127.0.0.1:8000/alterar-minha-senha/ que você vai ver o formulário para alteração de senha. A View utiliza o mesmo formulário de Login, por isso usamos o “extra_context” para enviar o título da página.
Criar link para usuário
Agora basta criar mais um link no seu menu para facilitar a troca de senha:
<a class="nav-link" href="{% url alterar-senha%}">Alterar senha</a>
Controle de acesso ao conteúdo diretamente nos templates
Nos templates também é importante verificar se o usuário fez o login para poder mostrar algumas coisas ou não. Isso é, basicamente, simples e envolve usar um if/else para verificar a autenticação.
Primeiro vamos no nosso menu para esconder alguns links. Vá no seu arquivo base do template (ex. base.html) e faça algo parecido com seu menu:
{% if request.user.is_authenticated %}
<!-- Links/Conteúdo exibidos apenas para usuários logados -->
{% endif %}
Mostrando dados do usuário
Lá nos templates é possível mostrar algumas informações do usuário por meio da instrução “request.user.atributo”. Exemplos:
Mostrar o primeiro nome: {{ request.user.first_name }}
Outros atributos são: last_name, email, usernamet
Exemplo de menu personalizado
<!-- Início do menu à direita --> <ul class="navbar-nav ml-auto"> {% if request.user.is_authenticated %} <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> {{ request.user.username }} </a> <div class="dropdown-menu" aria-labelledby="navbarDropdown"> <a class="dropdown-item" href="{% url 'alterar-senha' %}"> <i class="fa fa-key" aria-hidden="true"></i> Alterar senha</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="{% url 'logout' %}"> <i class="fa fa-sign-out" aria-hidden="true"></i> Sair</a> </div> </li> {% else %} <li class="nav-item"> <a class="nav-link" href="{% url 'login' %}"> <i class="fa fa-sign-in" aria-hidden="true"></i> Entrar </a> </li> {% endif %} </ul> <!-- Fim do menu -->
Controle de acesso por grupo de usuário
Django Braces
Este framework permite fazer o controle de acesso à determinadas URL de acordo com o grupo em que os usuários pertencem.
Documentação do plugin/framework:
Controle de acesso por grupo
Instalar o plugin (aqui no IFPR já está instalado)
pip install django-braces
Para ver os grupos que você tem ou para criar mais, acesse:
Você pode adicionar um grupo pelo próprio Django Admin. Vamos criar dois grupos:
- Administrador
- Usuário
Quando criamos um usuário pelo comando (python manage.py createsuperuser), esse usuário passa a ter acesso total ao nosso projeto. É possível remover/adicionar o status de superusuário ao editar algum usuário pelo Django Admin.
Definindo que uma URL/View nossa precisa ter um usuário que pertence a um determinado grupo
Vá no seu arquivo “adocao/views.py” e importe o módulo para controle de acesso por grupo:
from braces.views import GroupRequiredMixin
Agora, basta fazer uma herança nas suas views para GroupRequiredMixin e criar o atributo group_required na sua classe. É importante notar que a primeira herança deve ser do GroupRequiredMixin. Por exemplo:
No nosso projeto, vamos fazer com que os cadastros de Cidade, Estado, Tipo e Raca sejam somente visualizados pelo administrador (inserir, alterar, excluir e listar).
class EstadoCreate(GroupRequiredMixin, LoginRequiredMixin, CreateView):
group_required = u"Administrador"
...
Ajustar o template de login para redirecionar usuários autenticados
Só vamos mostrar o form se o usuário não estiver autenticado.
{% if request.user.is_authenticated %}
<h4 class="mt-4 text-danger">Você não pode fazer isso!</h4>
Redirecionando para a página inicial em 5 segundos...
<meta http-equiv="Refresh" content="5; url={% url 'index' %}" />
{% else %}
<form method="post">
<!-- Todo formulário tem que ter essa validação -->
{% csrf_token %}
<!-- Gera o formulário -->
{{ form|crispy }}
<button type="submit" class="btn {{ classe }}">
{{ botao }}
</button>
</form>
{% endif %}
Ainda não testei e nem testarei agora; mas já salvei aqui as instruções. Entretanto, antes que eu me esqueça, acho que vale já deixar o comentário: excelente explicação. Tudo muito claro e detalhado na medida.
Muito obrigado pelo conteúdo de qualidade.