Alura > Cursos de Programação > Cursos de Python > Conteúdos de Python > Primeiras aulas do curso Django: autenticação com OAuth2.0

Django: autenticação com OAuth2.0

Servidor - Apresentação

Olá! Meu nome é Guilherme Lima e serei seu instrutor neste curso sobre Django e OAuth. Estamos felizes que você deseja aprofundar seus conhecimentos em Django, com foco em um assunto muito importante: a autenticação!

Audiodescrição: Guilherme se descreve como um homem branco, de barba e cabelo curtos e castanho-escuros, e olhos castanho-escuros. Ele usa óculos de armação retangular preta, veste uma camisa laranja, e está sentado em frente a uma parede clara iluminada em azul-claro, com uma luminária à direita do instrutor trazendo um ponto de iluminação amarela, e um quadro de moldura dourada atrás dela.

O que vamos aprender?

Neste curso, vamos criar do zero uma aplicação na qual temos um botão para autenticar pessoas usuárias com recursos protegidos do GitHub. Para isso, vamos usar a biblioteca django-allauth.

Vamos observar essa aplicação em funcionamento? Ao clicar no botão do GitHub à direita da tela, somos redirecionados para o serviço cadastrado, já usando o protocolo do OAuth e do GitHub.

Nessa tela, podemos inserir o nome de usuário e a senha. Caso aprovado, somos redirecionados para uma área para membros autenticados da aplicação. Da mesma forma que fizemos a autenticação, também podemos clicar no botão "Logout" e voltar para a página principal.

Aprenderemos como funciona todo esse fluxo de autenticação, como o OAuth funciona em segundo plano, como o servidor do Django conversa com o GitHub, e caso sejam concedidas as permissões necessárias, ou seja, se autorizarmos a aplicação, como pegamos os dados e o que fazemos com eles.

Vamos abordar tudo isso neste curso!

Conclusão

Esse conteúdo é muito usado. Provavelmente, você já utilizou OAuth sem saber, pois quando entramos em uma aplicação com a opção "Faça login com o Google", "Faça login com o GitHub", ou "Faça login com o Facebook", por exemplo, em segundo plano, usamos esse protocolo muito interessante.

Tudo pronto para implementá-lo neste curso?

Servidor - Subindo o servidor

Vamos iniciar nossos estudos?

Subindo o servidor

Sabemos que, ao utilizar o framework do Django, podemos criar uma aplicação web como fizemos no Alura Space, que possui diversas páginas, autenticação, e a área de administração do Django.

No entanto, também somos capazes de desenvolver API REST com o Django REST Framework. Portanto, temos o framework do Django mais o REST para desenvolver APIs.

O que faremos neste curso?

Neste curso, vamos focar em desenvolver uma aplicação do zero, na qual queremos que pessoas se cadastrem e realizem um momento de autenticação, para receberem notícias de tecnologia.

Já que nosso contexto é um cenário de tecnologia, podemos usar como ferramenta o GitHub. Sabe quando acessamos uma aplicação e ela pergunta se queremos fazer o login com o GitHub?

Ao clicar, aparece a tela do GitHub em outro sistema e fazemos a nossa autenticação por esse caminho. É isso que vamos fazer, mas com foco no desenvolvimento do Django, não na criação de uma API REST.

Isso é tão interessante que, aqui na Alura, dividimos em dois momentos:

Sugestão de sequenciamento de estudos em Python para back-end. O ponto de partida é no canto superior direito, com 'Formação: A partir do zero: iniciante em programação'. Segue para baixo, com 'Formação: Aprenda a programar em Python com Orientação a Objetos'. À esquerda, um caminho leva a 'Formação: Django: crie aplicações em Python' acima e 'Formação: Começando com Flask: framework web de Python' abaixo. A 'Formação: Django: crie aplicações em Python' está ligada à 'Formação: Django REST APIs: crie aplicações REST em Python' no canto esquerdo. Os blocos estão interligados por linhas, indicando o fluxo de aprendizado. Há um destaque em verde escrito 'COMECE AQUI' no primeiro bloco.

Primeiro, criamos aplicações com Python, nas quais incorporamos código Python no HTML, temos rotas e URLs cadastradas, focadas em uma aplicação web em que temos estilos, documentos HTML, e assim por diante. Já em uma formação com API, não temos tanto essa parte visual.

No entanto, neste curso, usaremos bastante a parte visual e criaremos do zero. Você será capaz de estilizar com cores e imagens de sua preferência, para deixar o projeto com a sua cara.

Criando a pasta do projeto

Dito isso, vamos começar do zero. O primeiro passo será clicar com o botão direito sobre a área de trabalho e selecionar a opção "New Folder" ("Nova Pasta") para criar a pasta do projeto, que chamaremos de "tech".

Feito isso, podemos abrir o Visual Studio Code e arrastar para a interface a pasta que acabamos de criar. A partir desse momento, conseguimos começar a desenvolver nosso ambiente no Python.

Desenvolvendo o ambiente no Python

Primeiramente, vamos isolar todas as dependências do nosso projeto em um ambiente virtual do Python. Para isso, no terminal, vamos executar o seguinte comando:

python3 -m venv ./venv

Com isso, será criada a pasta "venv" no projeto, onde ficarão todas as dependências.

Ativando o projeto

Em seguida, precisamos ativar o projeto. Para isso, executamos o seguinte:

source venv/bin/activate.fish

Linux ou macos

source nome_da_virtualenv/bin/activate

Windows

nome_da_virtualenv/Scripts/activate

Uma vez ativado o ambiente, será exibido o nome (venv) na lateral esquerda do terminal.

Instalando o Django

O próximo passo será instalar o Django para criarmos a aplicação. Para isso, utilizamos o comando pip, que é o gerenciador de pacote do Django, seguido de install django.

pip install django

Após executar, ele traz tudo o que for necessário para usarmos o Django em uma aplicação.

Isolando as dependências

Sempre que instalamos um módulo, um pacote, uma biblioteca, ou um framework com o comando pip, uma boa prática importante é isolar todas as dependências em um arquivo chamado requirements.txt. O comando para isso é pip freeze, seguido do sinal > e do nome do arquivo requirements.txt.

pip freeze > requirements.txt

Ao executar, todas as dependências que o projeto precisa serão listadas no arquivo requirements.txt criado, com as suas respectivas versões.

requirements.txt:

asgiref==3.8.1
Django==5.0.6
sqlparse==0.5.0

Inicializando o projeto

Agora que temos a venv ativada, o Django instalado, e o arquivo requirements.txt criado, vamos iniciar o nosso projeto. Utilizaremos o comando django-admin startproject e, na sequência, nomearemos como setup a pasta na qual serão mantidos todos os projetos.

Finalizaremos o comando com um ponto (.) para não criar uma subpasta e sabermos onde fica o código que mantém todas as configurações do projeto.

django-admin startproject setup .

Ao final, será criada a pasta "setup", como podemos conferir no explorador à esquerda.

Criando uma nova aplicação

Agora que temos o projeto configurado, criaremos um app para manter tudo o que for relacionado a essa aplicação de novidades e notícias do mundo tech.

Sendo assim, pediremos ao python que use o manage.py para iniciar um novo app com o comando startapp. Chamaremos essa aplicação de tech. Com isso, podemos executar a linha de comando.

python manage.py startapp tech

Ao teclar "Enter", ele cria uma nova aplicação. Sempre que fazemos isso, é importante acessarmos o arquivo settings.py, da pasta "setup", e indicar que a aplicação utilizada com o Django também terá uma aplicação chamada tech. Faremos isso entre aspas simples na linha 40.

settings.py:

# código omitido

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'tech',
]

# código omitido

Subindo o servidor

Com a aplicação configurada, podemos visualizá-la para conferir se o que fizemos funciona. Para isso, vamos subir o servidor com o seguinte comando:

python manage.py runserver

Ao executar, recebemos a mensagem de que há migrações pendentes, e elas são a estrutura base do Django para ele funcionar. Com a tecla "Ctrl" pressionada, vamos clicar no endereço retornado:

Starting development server at http://127.0.0.1:8000/

Feito isso, será aberta uma aba no navegador contendo a mensagem de que a instalação foi um sucesso ("The install worked successfully! Congratulations!").

Alterando o idioma e a localização da aplicação

Após esse primeiro contato, vamos definir como língua oficial (LANGUAGE_CODE) da aplicação o português do Brasil, ou seja, pt-br. Faremos isso na linha 107 do arquivo settings.py.

settings.py:

# código omitido

LANGUAGE_CODE = 'pt-br'

# código omitido

Além disso, vamos usar o TIME_ZONE do local onde a pessoa instrutora está, que é America/Sao_Paulo, sem nenhum acento ou caractere especial na linha 109.

# código omitido

TIME_ZONE = 'America/Sao_Paulo'

# código omitido

Apenas com esses ajustes, já teremos o horário de São Paulo na aplicação. Ao atualizar a página no navegador, as informações também serão exibidas em português, e no terminal, será exibido o horário atual em que o instrutor Guilherme utiliza a aplicação.

Criando a pasta "templates"

Outra configuração possível é a seguinte: como criaremos uma aplicação web na qual as pessoas irão clicar e realizar uma autenticação, usando um protocolo com o GitHub que vamos abordar mais adiante, e colocar o sistema para conversar com o sistema externo, seria interessante se pudéssemos organizar e manter todos os arquivos HTML em um único lugar.

Dessa forma, facilitamos a manutenção da aplicação.

Dito isso, vamos criar uma pasta chamada "templates". Todo projeto Django com uma pasta com esse nome, diz para quem irá trabalhar nele que se tratam dos documentos HTML, ou talvez até de alguns assets que podemos usar.

Definindo o diretório base

Após criar essa pasta, vamos retornar ao arquivo settings.py. Na linha 58, utilizamos DIRS para indicar o diretório base de onde iremos manter os templates, mas ele está vazio por enquanto.

# código omitido

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],

# código omitido

Para conseguirmos colocar o caminho, precisamos primeiro realizar um import. Faremos isso na linha 14 do mesmo arquivo com import os.

# código omitido

from pathlib import Path
import os

# código omitido

O os é capaz de navegar entre as pastas que temos no projeto. Feito isso, vamos indicar entre os colchetes ([]) da linha 58 que, através do os, queremos passar o diretório em que estamos, mas também queremos que ele encontre a pasta "templates".

Para isso, chamamos os seguido de path (caminho), e depois juntamos o path com o método join(). Entre parênteses, passaremos o diretório onde estamos, ou seja BASE_DIR, seguido do nome da pasta, onde colocaremos "templates", pasta que criamos anteriormente.

# código omitido

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],

# código omitido

Criando o arquivo index.html

Dessa forma, podemos criar, por exemplo, um documento HTML.Para fazer isso, vamos criar um novo arquivo na pasta "templates" chamado index.html.

Começaremos com um código HTML base usando o atalho !.

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
</html>

Na linha 6, adicionaremos o título Tech, por exemplo. Também podemos colocar uma tag h1 na linha 9, entre as tags body, apenas para incluir um título a mais, como "Autenticação com OAuth 2.0".

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tech</title>
</head>
<body>
    <h1>Autenticação com OAuth 2.0</h1>
</body>
</html>

Criando a função index()

Para finalizar, vamos visualizar a página de autenticação que acabamos de criar. Na pasta "tech" do projeto, acessaremos o arquivo views.py para criar uma função chamada index().

Na linha 3, adicionaremos def index(), e entre parênteses vamos passar o request, que é sempre necessário quando vamos renderizar uma nova página. Na linha 4, diremos para retornar (return) a renderização, isto é, o render() da página index.html.

Importante! O primeiro parâmetro de render() sempre será o request. Em qualquer página que pedirmos para visualizar, o primeiro recurso será o request.

views.py:

from django.shortcuts import render

def index(request):
    return render(request, 'index.html')

Criando o arquivo urls.py

Uma vez criada a função, precisamos fazer com que, sempre que acessarmos a raiz da aplicação, seja exibida a página index.html que acabamos de criar.

Para isso, vamos criar um novo arquivo na pasta "tech" chamado urls.py. Neste arquivo, iremos manter todas as URLs relacionadas à aplicação Tech.

Começaremos importando o path do django.urls na linha 1. Além disso, do tech.views que acabamos de criar, queremos importar o index.

urls.py (tech):

from django.urls import path
from tech.views import index

Após essas importações, teremos uma sequência de padrões de URL, então criaremos o urlpatterns. Entre colchetes, passaremos o path(). Sempre que tivermos uma requisição na raiz do projeto, a index irá atender e o name que daremos para a rota será index.

from django.urls import path
from tech.views import index

urlpatterns = [
    path('', index, name='index')
]

Configurando a URL

A última coisa que vamos fazer será no arquivo urls.py da pasta "setup". O próprio código informa como podemos utilizar: vamos importar através das views; das classes baseadas em views; ou vamos incluir através de uma configuração de URL?

urls.py (setup):

"""
URL configuration for setup project.

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/5.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""

# código omitido

Seguiremos com a configuração da URL. Para isso, usaremos a função include(). Começaremos importando include na linha 18 do arquivo. Abaixo, na linha 22, vamos adicionar path() recebendo entre parênteses '', include('tech.urls').

# código omitido

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('tech.urls'))
]

Após salvar a aplicação, vamos voltar para o terminal e executar o servidor mais uma vez.

python manage.py runserver

Aparentemente, não temos nenhuma mensagem de erro. Ao atualizar a página no navegador, temos o título "Autenticação com OAuth 2.0", conforme adicionado no código.

Conclusão

Nosso documento HTML seria muito melhor se tivesse uma imagem, o link com um estilo bonito, se estivesse visualmente mais atrativo para as pessoas receberem as notícias do mundo tech e se autenticarem com o GitHub.

Esse será nosso desafio na sequência!

Servidor - Editando o documento

Ao acessar a aplicação, há um título "Autenticação com OAuth 2.0" no canto superior esquerdo. Poderíamos adicionar um link simples abaixo para realizar a autenticação com OAuth, mas isso não seria muito eficiente, pois quem utiliza o Django e renderiza páginas, precisa ter um bom conhecimento de HTML e uma noção de CSS. Queremos mostrar como seria o início desse projeto!

Editando o documento

Começaremos criando um documento HTML na aplicação para tornar o desenvolvimento mais nítido.

Lembre-se: isso faz parte do trabalho de quem utiliza Django. Não se trata apenas de Python e do lado do servidor. É importante saber como renderizar páginas e também estilizar as aplicações. Praticamente, estamos nos tornando pessoas desenvolvedoras "full stack em Python".

Criando um header

O objetivo é criar um HTML semântico. No arquivo index.html, dentro do body da linha 10, adicionaremos um header, onde manteremos algumas informações sobre nossa aplicação.

Inicialmente, colocaremos apenas uma imagem. Portanto, a tag header irá conter uma tag img, na linha 11. Em img, teremos o atributo src para informar o caminho da imagem.

Caso a imagem não apareça na tela, queremos que o atributo alt, isto é, que o texto alternativo da imagem seja algo como "Uma pessoa feliz no computador".

Além disso, esse elemento terá uma classe CSS (class), definida como logo. Caso você queira obter o mesmo resultado que nós, basta utilizar as mesmas classes aplicadas pelo instrutor neste vídeo.

index.html:

<!-- código omitido -->

<header>
    <img src="" alt="Uma pessoa feliz no computador" class="logo">
</header>

<!-- código omitido -->

Assim, a única coisa que teremos em header será uma imagem que ficará posicionada à esquerda, com as informações da página e o botão para realizar a autenticação com o GitHub à direita.

Criando um main

Criaremos também o bloco main, referente ao conteúdo principal da página. A tag h1 que adicionamos anteriormente pode ser movida para o escopo de main, na linha 15.

<!-- código omitido -->

<main>
    <h1>Autenticação com OAuth 2.0</h1>
</main>

<!-- código omitido -->

Na sequência, vamos criar algumas classes CSS e a estrutura base para utilizar no projeto.

Lembre-se: nosso projeto é uma aplicação que irá conectar pessoas do mundo da tecnologia para se autenticarem com o GitHub.

Criando classes CSS

Primeiramente, criaremos as classes CSS para aparecer a imagem do GitHub, o texto abaixo do ícone do GitHub para que a pessoa clique e realize a autenticação, e assim por diante.

Na linha 16, vamos criar uma div e aplicar uma class chamada social-media. Nessa classe social-media, teremos uma única div no momento, mas podemos ter várias depois, conforme o projeto evoluir.

<!-- código omitido -->

<main>
    <h1>Autenticação com OAuth 2.0</h1>
    <div class="social-media">
        
    </div>
</main>

<!-- código omitido -->

A partir da linha 17, criaremos mais uma div, mas usaremos o atalho .social-media-details. Dentro dessa div de classe social-media-details criada através do atalho, queremos uma tag âncora (a).

Nessa tag, queremos duas coisas: primeiro, uma imagem (img), que colocaremos na linha 19. Imagine que, dentro dessa imagem, queremos colocar o Ícone para realizar a autenticação com GitHub.

Nesse caso, podemos escrever o seguinte texto alternativo (alt): "Ícone para realizar a autenticação com GitHub". Abaixo, na linha 20, criaremos um parágrafo (p) escrito "GitHub".

<!-- código omitido -->

<main>
    <h1>Autenticação com OAuth 2.0</h1>
    <div class="social-media">
        <div class="social-media-details">
            <a href="">
                <img src="" alt="Ícone para realizar a autenticação com GitHub">
                <p>GitHub</p>
            </a>
        </div>
    </div>
</main>

<!-- código omitido -->

Resultado do código de index.html até o momento:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tech</title>
</head>
<body>

    <header>
        <img src="" alt="Uma pessoa feliz no computador" class="logo">
    </header>

    <main>
        <h1>Autenticação com OAuth 2.0</h1>
        <div class="social-media">
            <div class="social-media-details">
                <a href="">
                    <img src="" alt="Ícone para realizar a autenticação com GitHub">
                    <p>GitHub</p>
                </a>
            </div>
        </div>
    </main>

</body>
</html>

Executando o servidor

Feito isso, vamos executar o servidor novamente:

python manage.py runserver

Ao atualizar a página, teremos uma estrutura melhor da aplicação, com os textos alternativos (alt) exibidos em tela. Isso é muito importante, principalmente por questões de acessibilidade.

Ainda temos o título h1 que criamos anteriormente, mas agora podemos visualizar o texto alternativo "Ícone para realizar a autenticação com GitHub" seguido do nome "GitHub" abaixo.

Conclusão

Na sequência, vamos melhorar muito a parte visual do projeto, adicionando imagens para termos uma referência delas em tela.

Nosso objetivo é tornar o visual mais agradável!

Sobre o curso Django: autenticação com OAuth2.0

O curso Django: autenticação com OAuth2.0 possui 91 minutos de vídeos, em um total de 40 atividades. Gostou? Conheça nossos outros cursos de Python em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Python acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas