A autenticação e autorização em uma aplicação web são os primeiros mecanismos de defesa contra acessos não autorizados. Quando implementamos autenticação, estamos garantindo que os usuários possam entrar no sistema de forma segura, fornecendo suas credenciais. A autorização, por outro lado, assegura que esses usuários só possam acessar as funcionalidades e dados que estão permitidos a eles.
Com o Django, um dos frameworks web mais populares em Python, temos uma série de ferramentas para criar um sistema confiavel de autenticação e autorização sem muita dor de cabeça. No entanto, para aplicações mais complexas, a necessidade de customizações e extensões do sistema padrão pode surgir.
Neste artigo, vamos abordar como implementar um sistema de autenticação do zero, customizar o modelo de usuário, controlar permissões e grupos, além de integrar o Django Allauth para facilitar logins com redes sociais. Tudo isso sem perder de vista as melhores práticas de segurança.
O sistema nativo do Django: Por onde começar?
O Django já vem com um sistema de autenticação pré-configurado e integrado ao seu framework. Isso significa que, assim que você criar um projeto Django, o sistema de autenticação básico já está disponível.
O que está disponível no pacote padrão?
- Modelo User: O modelo de usuário padrão é gerenciado por
django.contrib.auth
. Ele armazena informações como username, senha (de forma segura, utilizando hashing), email, primeiro nome, último nome, e permissões associadas ao usuário. - Sessões e Cookies: O Django usa cookies de sessão para manter os usuários logados após o login, de forma que você não precisa implementar isso manualmente.
- Autenticação básica: A função
authenticate()
elogin()
estão prontas para serem utilizadas, permitindo que você autentique um usuário e o conecte à sessão.
Essas funcionalidades cobrem a maior parte dos casos básicos, mas você provavelmente precisará configurar algumas coisas manualmente, como já mencionamos no início com o LOGIN_URL
, LOGOUT_URL
e LOGIN_REDIRECT_URL
.
Agora que você entende o básico, vamos avançar para configurações mais detalhadas.
Implementando um sistema de Login e Logout no Django
Detalhando a View de Login
Na seção anterior, mostramos uma view básica de login. No entanto, podemos detalhar um pouco mais para incluir melhores práticas, como validação de formulários e tratamento de erros:
from django.contrib.auth import authenticate, login
from django.shortcuts import render, redirect
from django import forms
from django.contrib.auth.forms import AuthenticationForm
def login_view(request):
if request.method == 'POST':
form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('home')
else:
return render(request, 'login.html', {'form': form, 'error': 'Usuário ou senha inválidos.'})
else:
return render(request, 'login.html', {'form': form, 'error': 'Dados de login inválidos.'})
else:
form = AuthenticationForm()
return render(request, 'login.html', {'form': form})
PythonAqui, usamos o formulário AuthenticationForm
, uma classe já fornecida pelo Django, que realiza as verificações de forma mais robusta e centralizada.
View de Logout
O logout, por outro lado, é bem simples e não precisa de muita personalização. Você pode usar a view genérica LogoutView
do Django, que já faz todo o trabalho para você:
from django.contrib.auth.views import LogoutView
urlpatterns = [
path('logout/', LogoutView.as_view(), name='logout'),
]
PythonEsse logout invalida a sessão atual do usuário e redireciona para a página que você configurou no LOGOUT_REDIRECT_URL
.
Criando as Templates
Para exibir os formulários de login e logout, você precisará criar templates. Um exemplo básico de template para login (login.html
) poderia ser:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
</form>
{% if error %}
<p style="color: red;">{{ error }}</p>
{% endif %}
PythonEsse template renderiza o formulário que criamos na view e, se houver algum erro (usuário ou senha inválidos), ele será exibido de forma amigável ao usuário.
Autorização no Django: Grupos e Permissões
Agora que configuramos a parte de autenticação, vamos focar na autorização. O Django também vem com um sistema poderoso de permissões baseado em usuários e grupos.
Como funcionam as permissões no Django?
O Django aplica permissões a três níveis: add
, change
e delete
. Para cada modelo registrado na sua aplicação, ele cria automaticamente essas três permissões. Além disso, você pode definir permissões customizadas nos seus modelos.
Vamos criar um exemplo onde apenas usuários com a permissão can_view_dashboard
podem acessar uma view de dashboard.
Definindo permissões customizadas
No modelo onde você deseja aplicar a permissão, basta definir as permissões personalizadas usando a classe Meta
:
from django.db import models
class Report(models.Model):
name = models.CharField(max_length=100)
date_created = models.DateTimeField(auto_now_add=True)
class Meta:
permissions = [
('can_view_dashboard', 'Pode ver o painel'),
]
PythonAgora, para aplicar essa permissão na view, usamos o decorator @permission_required
:
from django.contrib.auth.decorators import permission_required
@permission_required('yourapp.can_view_dashboard')
def dashboard_view(request):
return render(request, 'dashboard.html')
PythonSe o usuário não tiver a permissão can_view_dashboard
, ele será automaticamente redirecionado para a página de login ou uma página de erro.
Trabalhando com Grupos
Uma maneira mais eficiente de gerenciar permissões, especialmente em aplicações com muitos usuários, é usar Grupos. Você pode adicionar permissões a um grupo e, em seguida, atribuir usuários a esse grupo. Isso evita a necessidade de configurar permissões individualmente para cada usuário.
Aqui está como você pode criar grupos e associar permissões a eles no Django Admin:
- Acesse o Django Admin.
- No painel, clique em “Groups”.
- Crie um novo grupo e adicione as permissões desejadas a ele.
- Agora, ao editar um usuário, você pode simplesmente associá-lo a um grupo.
Esse sistema é muito útil para papéis de usuários como “Admin”, “Editor”, “Moderador”, entre outros.
Customizando o Sistema de Usuários
No início, mostramos como estender o modelo User
padrão para adicionar novos campos. Vamos aprofundar um pouco mais, explicando quando faz sentido usar AbstractUser
e quando você deveria considerar AbstractBaseUser
.

Usando AbstractBaseUser
para Controle Completo
Se você precisar de controle total sobre o modelo de usuários (talvez você não queira usar nomes de usuários, apenas emails, por exemplo), AbstractBaseUser
é a escolha ideal. Ele fornece o esqueleto do sistema de autenticação sem nenhum campo adicional, e você precisa definir os campos que deseja.
Aqui está um exemplo básico de como criar um modelo de usuário totalmente customizado:
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.db import models
class CustomUserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError('O email deve ser fornecido')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password=None, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
return self.create_user(email, password, **extra_fields)
class CustomUser(AbstractBaseUser):
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = CustomUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name']
PythonNeste exemplo, a autenticação é baseada no email, e não em usernames. Você também define o gerenciador de usuários customizado para criar usuários e superusuários corretamente.
Sistema de Autenticação com Django Allauth
Para aplicações modernas, oferecer aos usuários opções de login via redes sociais pode ser crucial. Isso facilita a entrada de novos usuários sem que eles precisem passar pelo processo de criação de contas manuais. Para facilitar isso, usamos o Django Allauth.
O Allauth é um pacote que oferece suporte a várias formas de autenticação, incluindo login via redes sociais, registro de novos usuários, verificação de email, recuperação de senha, entre outros. Além disso, ele já vem com templates prontos para todas essas funcionalidades, o que economiza um bom tempo de desenvolvimento.
Instalação e Configuração
Vamos começar instalando o pacote:
pip install django-allauth
PythonAgora, você precisa adicionar o Allauth ao seu arquivo settings.py
. Isso envolve adicionar alguns apps ao seu projeto, além de configurar os backends de autenticação:
INSTALLED_APPS = [
# Apps padrão do Django
'django.contrib.sites', # Necessário para o Django Allauth
# Apps do Django Allauth
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.google', # Exemplificando a integração com o Google
]
# Configuração para o Django Sites Framework (requisito do Allauth)
SITE_ID = 1
# Definindo o backend de autenticação para o Allauth
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
]
# URLs de redirecionamento
LOGIN_REDIRECT_URL = '/'
ACCOUNT_LOGOUT_REDIRECT_URL = '/'
# Configurações extras para o Allauth
ACCOUNT_EMAIL_VERIFICATION = 'mandatory' # Verificação de email obrigatória
ACCOUNT_EMAIL_REQUIRED = True
PythonAqui estamos adicionando os apps allauth
e allauth.socialaccount
ao nosso projeto. Também incluímos o provedor social do Google como exemplo. O Allauth oferece suporte a diversos provedores (Facebook, GitHub, Twitter, entre outros), e a configuração para cada um deles é bem similar.
Configurando as URLs
O próximo passo é adicionar as URLs do Allauth ao seu arquivo urls.py
:
from django.urls import path, include
urlpatterns = [
# Suas outras rotas
path('accounts/', include('allauth.urls')),
]
PythonO Allauth já traz um conjunto completo de URLs para login, logout, cadastro, recuperação de senha, verificação de email e login social. Tudo isso será incluído automaticamente ao adicionar essa linha.
Configurando o Login Social (Exemplo com Google)
Para permitir o login com Google, você precisa configurar as credenciais da sua aplicação na console do Google Developers. Depois de criar um novo projeto e ativar o Google OAuth, você receberá um Client ID e um Client Secret. Essas informações devem ser adicionadas ao seu projeto Django.
No admin do Django, vá até Social applications (Aplicações Sociais), adicione uma nova aplicação, selecione “Google” como provedor e adicione o Client ID e Secret. Você também deve configurar a URL de redirecionamento, que será algo como:
http://localhost:8000/accounts/google/login/callback/
PythonTestando o Login Social
Com as credenciais configuradas, o login via Google estará disponível na página de login (/accounts/login/
). O Allauth gera automaticamente os botões de login social baseados nos provedores que você configurou.
A partir deste ponto, os usuários poderão se registrar e fazer login utilizando suas contas Google. O Allauth cuidará de toda a parte de autenticação e criação de usuários, incluindo o armazenamento seguro de tokens de acesso e atualizações de perfil.
Personalizando o Django Allauth
Se você quiser personalizar o comportamento padrão do Allauth (por exemplo, mudar as mensagens de erro, os templates ou o fluxo de autenticação), isso também é bastante fácil. O Allauth oferece templates personalizáveis que você pode sobrescrever. Crie um diretório chamado templates/account
no seu projeto e adicione templates personalizados para views de login, cadastro e email.
Por exemplo, um template customizado para login (login.html
) pode ser algo assim:
{% extends "base.html" %}
{% block content %}
<h2>Faça login na sua conta</h2>
<form method="post" action="{% url 'account_login' %}">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
</form>
<p>Ou faça login com:</p>
<a href="{% provider_login_url 'google' %}">Login com Google</a>
{% endblock %}
PythonEsse template oferece uma experiência de login tradicional, com a opção de login social integrada.
Segurança: Melhorando a Proteção do Sistema de Autenticação
Um sistema de autenticação robusto precisa ser seguro. O Django já oferece uma série de boas práticas de segurança por padrão, mas algumas medidas adicionais são altamente recomendadas para proteger ainda mais sua aplicação.
Uso de HTTPS
Certifique-se de que sua aplicação esteja usando HTTPS em produção. Isso garante que os dados transmitidos entre o cliente e o servidor sejam criptografados, o que é crucial para impedir a interceptação de credenciais de login. No settings.py
, você pode habilitar o uso de HTTPS com as seguintes configurações:
# Redireciona todas as requisições HTTP para HTTPS
SECURE_SSL_REDIRECT = True
# Garante que o cookie de sessão só será enviado por HTTPS
SESSION_COOKIE_SECURE = True
# Garante que o cookie CSRF só será enviado por HTTPS
CSRF_COOKIE_SECURE = True
PythonBloqueio de Tentativas de Login Mal-Sucedidas
Para impedir ataques de força bruta, onde um invasor tenta várias combinações de nome de usuário e senha até acertar, você pode limitar o número de tentativas de login que um usuário pode fazer antes de ser temporariamente bloqueado.
Um pacote popular para isso é o django-axes:
pip install django-axes
PythonAdicione o django-axes
ao seu settings.py
:
INSTALLED_APPS = [
# Apps padrão
'axes',
]
MIDDLEWARE = [
'axes.middleware.AxesMiddleware',
# Outros middlewares
]
# Configuração do django-axes
AXES_FAILURE_LIMIT = 5 # Número de tentativas permitidas antes de bloquear
AXES_COOLOFF_TIME = timedelta(minutes=15) # Tempo de bloqueio após o limite ser atingido
PythonCom isso configurado, o django-axes rastreará as tentativas de login e bloqueará automaticamente endereços IP que ultrapassarem o limite de tentativas falhas.
Verificação de Email
Habilitar a verificação de email é uma maneira importante de garantir que os usuários forneçam endereços de email válidos. O Django Allauth já possui suporte para verificação de email integrada. No settings.py
, você pode forçar a verificação de email:
ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
ACCOUNT_EMAIL_REQUIRED = True
PythonIsso garantirá que o usuário só poderá acessar o sistema após confirmar seu endereço de email.
Testando o Sistema de Autenticação
Depois de implementar toda essa estrutura, é essencial testar o sistema de autenticação e autorização. O Django facilita os testes com suas ferramentas de TestCase
.
Um teste básico para verificar o login pode ser algo assim:
from django.test import TestCase
from django.contrib.auth import get_user_model
class LoginTest(TestCase):
def setUp(self):
self.user = get_user_model().objects.create_user(username='testuser', password='testpassword')
def test_login(self):
response = self.client.post('/login/', {'username': 'testuser', 'password': 'testpassword'})
self.assertEqual(response.status_code, 302) # Redirecionamento após o login
PythonEsse teste cria um usuário e verifica se ele consegue fazer login com sucesso. Testar todas as partes do sistema é crucial para garantir que ele funcione corretamente em produção.
Conclusão
A autenticação e autorização são peças fundamentais para qualquer aplicação web. O Django, com seu sistema nativo, já oferece uma estrutura robusta e segura, que pode ser facilmente estendida e adaptada para necessidades específicas.
Quando integramos ferramentas como o Django Allauth, adicionamos mais conveniência e flexibilidade, permitindo que os usuários façam login com contas sociais e criando um sistema de autenticação altamente customizável.
Além disso, medidas de segurança, como o uso de HTTPS, bloqueio de tentativas de login e verificação de email, são fundamentais para proteger os dados dos usuários e garantir que seu sistema não seja alvo fácil para ataques.
Espero que este passoo-a-passo tenha coberto de forma abrangente os principais aspectos da autenticação e autorização no Django. Agora, é só implementar e seguir as melhores práticas de segurança!