Login do Django

Resumo : neste tutorial, você aprenderá como criar um formulário de login do Django que permite aos usuários fazer login usando um nome de usuário e senha.

Este tutorial começa onde o tutorial Django Delete Form  parou.

Criar uma nova aplicação

Primeiro, crie um novo aplicativo chamado usersexecutando o startappcomando:

django-admin startapp users

O diretório do projeto ficará assim:

├── blog
├── db.sqlite3
├── manage.py
├── mysite
├── static
├── templates
└── usersLinguagem de código:  texto simples  ( texto simples )

Segundo, registre o usersaplicativo nos aplicativos instalados do settings.pyprojeto:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # local
    'blog.apps.BlogConfig',
    'users.apps.UsersConfig'
]
Linguagem de código:  Python  ( python )

Terceiro, crie um novo urls.pyarquivo dentro do usersaplicativo com o seguinte código:

from django.urls import path
from . import views

urlpatterns = []Linguagem de código:  Python  ( python )

Por fim, inclua o urls.pyda usersaplicação no urls.pydo projeto usando a include()função:

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('blog.urls')),
    path('',include('users.urls'))
]
Linguagem de código:  Python  ( python )

Crie um formulário de login

Primeiro, crie uma URL de login no urls.pyaplicativo users:

from django.urls import path
from . import views

urlpatterns = [
    path('login/', views.sign_in, name='login'),
]Linguagem de código:  Python  ( python )

Segundo, crie um forms.pyarquivo na usersaplicação e defina o LoginFormque herda da Formclasse:

from django import forms


class LoginForm(forms.Form):
    username = forms.CharField(max_length=65)
    password = forms.CharField(max_length=65, widget=forms.PasswordInput)
Linguagem de código:  Python  ( python )

O LoginFormpossui dois campos nome de usuário e senha.

Terceiro, crie a sign_in()função no views.pyarquivo da usersaplicação para renderizar o login.htmltemplate:

from django.shortcuts import render
from .forms import LoginForm


def sign_in(request):
    if request.method == 'GET':
        form = LoginForm()
        return render(request, 'users/login.html', {'form': form})
Linguagem de código:  Python  ( python )

Quarto, crie o templates/usersdiretório dentro da usersaplicação:

mkdir templates
cd templates
mkdir usersLinguagem de código:  texto simples  ( texto simples )

Quinto, crie o login.htmlmodelo dentro do templates/usersdiretório que estende o base.htmlmodelo:

{% extends 'base.html' %}

{% block content %}
<form method="POST" novalidate>
	{% csrf_token %}
	<h2>Login</h2>
	{{form.as_p}}
	<input type="submit" value="Login" />
</form>

{% endblock content%}Linguagem de código:  HTML, XML  ( xml )

Sexto, abra o URL de login e você verá o formulário de login:

http://127.0.0.1:8000/loginLinguagem de código:  texto simples  ( texto simples )

Se você inserir um nome de usuário/senha e clicar no botão Login, receberá um erro porque ainda não adicionamos o código que trata a solicitação HTTP POST.

Sétimo, modifique a sign_in()função para lidar com o processo de login:

from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth import login, authenticate
from .forms import LoginForm


def sign_in(request):

    if request.method == 'GET':
        form = LoginForm()
        return render(request,'users/login.html', {'form': form})
    
    elif request.method == 'POST':
        form = LoginForm(request.POST)
        
        if form.is_valid():
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']
            user = authenticate(request,username=username,password=password)
            if user:
                login(request, user)
                messages.success(request,f'Hi {username.title()}, welcome back!')
                return redirect('posts')
        
        # form is not valid or user is not authenticated
        messages.error(request,f'Invalid username or password')
        return render(request,'users/login.html',{'form': form})
Linguagem de código:  Python  ( python )

Como funciona.

Primeiro, importe a função authenticatee logindo django.contrib.authmódulo:

from django.contrib.auth import login, authenticateLinguagem de código:  Python  ( python )

A authenticate()função verifica um nome de usuário e senha. Se o nome de usuário e a senha forem válidos, ele retornará uma instância de Userclasse ou Nonenão.

A login()função faz login de um usuário. Tecnicamente, ela cria um ID de sessão no servidor e o envia de volta ao navegador na forma de um cookie.

Na solicitação subsequente, o navegador envia o ID da sessão de volta ao servidor web, o Django combina o valor do cookie com o ID da sessão e cria o Userobjeto.

Segundo, verifique o nome de usuário e a senha usando a authenticate()função se o formulário for válido:

user = authenticate(request, username=username, password=password)Linguagem de código:  Python  ( python )

Terceiro, faça login do usuário, crie uma mensagem flash e redirecione o usuário para a postsURL se o nome de usuário e a senha forem válidos:

if user:
   login(request, user)
   messages.success(request,f'Hi {user.username.title()}, welcome back!')
   return redirect('posts')Linguagem de código:  Python  ( python )

Caso contrário, crie uma mensagem de erro flash e redirecione o usuário de volta à página de login:

messages.error(request,f'Invalid username or password')
return render(request,'users/login.html')Linguagem de código:  Python  ( python )

Se você inserir um nome de usuário sem senha e clicar no botão Login, receberá a seguinte mensagem de erro:

No entanto, se você inserir o nome de usuário/senha corretos, você será redirecionado para a página da lista de postagens com uma mensagem de boas-vindas:

Adicionar um formulário de logout

Primeiro, defina uma rota para desconectar um usuário:

from django.urls import path
from . import views

urlpatterns = [
    path('login/', views.sign_in, name='login'),
    path('logout/', views.sign_out, name='logout'),
]Linguagem de código:  JavaScript  ( javascript )

Segundo, defina a sign_out()função no views.pyarquivo que trata da rota de logout:

from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth import login, authenticate, logout
from .forms import LoginForm

def sign_in(request):

    if request.method == 'GET':
        form = LoginForm()
        return render(request,'users/login.html', {'form': form})
    
    elif request.method == 'POST':
        form = LoginForm(request.POST)
        
        if form.is_valid():
            username = form.cleaned_data['username']
            password=form.cleaned_data['password']
            user = authenticate(request,username=username,password=password)
            if user:
                login(request, user)
                messages.success(request,f'Hi {username.title()}, welcome back!')
                return redirect('posts')
        
        # either form not valid or user is not authenticated
        messages.error(request,f'Invalid username or password')
        return render(request,'users/login.html',{'form': form})
    
    
        
def sign_out(request):
    logout(request)
    messages.success(request,f'You have been logged out.')
    return redirect('login')        
Linguagem de código:  Python  ( python )

Se você fizer login e acessar a página de login, ainda verá o formulário de login. Portanto, é melhor redirecionar o usuário logado para a lista de postagens se o usuário acessar a página de login.

Terceiro, modifique a sign_in()função no views.pyaplicativo users:

def sign_in(request):

    if request.method == 'GET':
        if request.user.is_authenticated:
            return redirect('posts')
        
        form = LoginForm()
        return render(request,'users/login.html', {'form': form})
    
    elif request.method == 'POST':
        form = LoginForm(request.POST)
        
        if form.is_valid():
            username = form.cleaned_data['username']
            password=form.cleaned_data['password']
            user = authenticate(request,username=username,password=password)
            if user:
                login(request, user)
                messages.success(request,f'Hi {username.title()}, welcome back!')
                return redirect('posts')
        
        # either form not valid or user is not authenticated
        messages.error(request,f'Invalid username or password')
        return render(request,'users/login.html',{'form': form})
Linguagem de código:  PHP  ( php )

O request.user.is_authenticatedretorno Truese um usuário estiver logado ou Falsenão.

Quarto, modifique o base.htmlmodelo para incluir o link de logout se o usuário estiver autenticado e o link de login caso contrário:

{%load static %}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="{% static 'css/style.css' %}" />
    <script src="{% static 'js/app.js' %}" defer></script>
    <title>My Site</title>
  </head>
  <body>
  	<header>
  		{%if request.user.is_authenticated %}
  			<span>Hi {{ request.user.username | title }}</span>
  			<a href="{% url 'logout' %}">Logout</a>
  		{%else%}
  			<a href="{% url 'login' %}">Login</a>
  		{%endif%}
  	</header>
  	<main>
	  	{% if messages %}
			<div class="messages">
			{% for message in messages %}
				<div class="alert {% if message.tags %}alert-{{ message.tags }}"{% endif %}>
					{{ message }}
				</div>
			{% endfor %}
			</div>
		{% endif %}
		    
	    {%block content%} 
	    {%endblock content%}
  	</main>
	
  </body>
</html>Linguagem de código:  HTML, XML  ( xml )

Se você acessar o site, verá o link de login:

Ao clicar no link de login, a página de login será aberta:

Se você inserir o nome de usuário e a senha válidos e fazer login, verá uma mensagem de boas-vindas, bem como o link de logout:

Se você clicar no link de logout, ele será redirecionado para a página de login:

Ocultando os links de edição e exclusão na lista de postagens

Se um usuário estiver logado, o arquivo request.user.is_authenticatedé True. Portanto, você pode usar este objeto para mostrar e ocultar elementos da página, esteja o usuário logado ou não.

Por exemplo, o seguinte oculta os links de edição e exclusão no blog/home.htmlmodelo se o usuário estiver autenticado:

{% extends 'base.html' %}
	
{% block content %}
<h1>My Posts</h1>
	{% for post in posts %}
		<h2>{{ post.title }}</h2>
		<small>Published on {{ post.published_at | date:"M d, Y" }} by {{ post.author | title}}</small>
		<p>{{ post.content }}</p>
		
		{% if request.user.is_authenticated %}
		<p>
			<a href="{% url 'post-edit' post.id %}">Edit</a> 
			<a href="{% url 'post-delete' post.id%}">Delete</a>
		</p>
		{% endif %}
		
	{% endfor %}
{% endblock content %}
Linguagem de código:  HTML, XML  ( xml )

Protegendo as páginas protegidas

Normalmente, você deve permitir que usuários autenticados acessem as páginas de criação, atualização e exclusão de postagens. Para fazer isso você pode usar login_requiredo decorador do Django.

Se uma função de visualização tiver o login_requireddecorador e um usuário não autenticado tentar executá-la, o Django redirecionará o usuário para a página de login.

Protegeremos as funções de criação, atualização e exclusão de postagem usando o login_requireddecorador.

Primeiro, defina o URL de login settings.pyno URL de login:

LOGIN_URL = 'login'Linguagem de código:  JavaScript  ( javascript )

Se você não fizer isso, o Django irá redirecionar para a URL de login padrão que accounts/login/não é users/logina que definimos neste projeto.

Segundo, modifique o views.pyaplicativo blogadicionando o @login_requireddecorador às funções create_post, edit_poste :delete_post

from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .models import Post
from .forms import PostForm


@login_required
def delete_post(request, id):
    post = get_object_or_404(Post, pk=id)
    context = {'post': post}

    if request.method == 'GET':
        return render(request, 'blog/post_confirm_delete.html', context)
    elif request.method == 'POST':
        post.delete()
        messages.success(request,  'The post has been deleted successfully.')
        return redirect('posts')


@login_required
def edit_post(request, id):
    post = get_object_or_404(Post, id=id)

    if request.method == 'GET':
        context = {'form': PostForm(instance=post), 'id': id}
        return render(request, 'blog/post_form.html', context)

    elif request.method == 'POST':
        form = PostForm(request.POST, instance=post)
        if form.is_valid():
            form.save()
            messages.success(
                request, 'The post has been updated successfully.')
            return redirect('posts')
        else:
            messages.error(request, 'Please correct the following errors:')
            return render(request, 'blog/post_form.html', {'form': form})


@login_required
def create_post(request):
    if request.method == 'GET':
        context = {'form': PostForm()}
        return render(request, 'blog/post_form.html', context)
    elif request.method == 'POST':
        form = PostForm(request.POST)
        if form.is_valid():
            form.save()
            messages.success(
                request, 'The post has been created successfully.')
            return redirect('posts')
        else:
            messages.error(request, 'Please correct the following errors:')
            return render(request, 'blog/post_form.html', {'form': form})


def home(request):
    posts = Post.objects.all()
    context = {'posts': posts}
    return render(request, 'blog/home.html', context)


def about(request):
    return render(request, 'blog/about.html')

Linguagem de código:  JavaScript  ( javascript )

Se você abrir o URL de criação, atualização ou exclusão, por exemplo:

http://127.0.0.1/post/createLinguagem de código:  JavaScript  ( javascript )

Ele será redirecionado para a página de login.

Baixe o código fonte do Projeto Django

Resumo

  • Use authenticate()a função para verificar um usuário por nome de usuário e senha.
  • Use login()a função para fazer login de um usuário.
  • Use logout()a função para desconectar um usuário.
  • Use request.user.is_authenticatedpara verificar se o usuário atual está autenticado.
  • Decorador de usuário @login_requiredpara proteger páginas de usuários não autenticados.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *