# 🔐 Day 7: Django Authentication – Beginner’s Web Dev Series

Welcome to **Day 7** of the Django for Beginners journey!  
Today, we dive deep into **user authentication** in Django — the core of most web applications involving users.

We'll learn:

* How login/logout works
    
* How to create a user registration system
    
* How to protect views
    
* And, importantly, how to create a **custom login system from scratch** to understand the flow
    

---

## 📍 What You’ll Learn

1. How Django's built-in auth system works
    
2. Handling login, logout, and user registration
    
3. Checking if a user is authenticated
    
4. Protecting views with decorators
    
5. Creating a **custom login system manually**
    

---

## 1\. Django’s Built-in Auth System

Django provides:

* `User` model
    
* Login/logout views
    
* Password hashing
    
* CSRF protection
    
* Secure session handling
    

---

## 2\. Login and Logout (Built-in)

### Add to [`urls.py`](http://urls.py)

```python
from django.contrib.auth import views as auth_views

urlpatterns = [
    path('login/', auth_views.LoginView.as_view(template_name='login.html'), name='login'),
    path('logout/', auth_views.LogoutView.as_view(next_page='login'), name='logout'),
]
```

### Create `login.html`

```html
<form method="POST">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">Login</button>
</form>
```

---

## 3\. User Registration with `UserCreationForm`

### View:

```python
from django.contrib.auth.forms import UserCreationForm

def register(request):
    form = UserCreationForm(request.POST or None)
    if form.is_valid():
        form.save()
        return redirect('login')
    return render(request, 'register.html', {'form': form})
```

### Template:

```html
<form method="POST">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">Register</button>
</form>
```

---

## 4\. Checking if a User is Logged In

### In Python:

```python
if request.user.is_authenticated:
    print("Welcome", request.user.username)
```

### In Templates:

```css
{% if user.is_authenticated %}
  Hi, {{ user.username }}
{% else %}
  Not logged in
{% endif %}
```

---

## 5\. Protecting Views

### Option 1: Manually

```python
def dashboard(request):
    if not request.user.is_authenticated:
        return redirect('login')
    return render(request, 'dashboard.html')
```

### Option 2: Use Decorator

```python
from django.contrib.auth.decorators import login_required

@login_required(login_url='login')
def dashboard(request):
    return render(request, 'dashboard.html')
```

---

## 6\. Custom Login – Understand How It Works Internally

Here’s how Django authentication works step by step using **manual logic**.

### Create a Custom Login Form

```python
# forms.py

from django import forms

class CustomLoginForm(forms.Form):
    username = forms.CharField()
    password = forms.CharField(widget=forms.PasswordInput)
```

---

### View: Custom Login Logic

```python
# views.py

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

def custom_login(request):
    form = CustomLoginForm(request.POST or None)
    if request.method == 'POST' and form.is_valid():
        username = form.cleaned_data['username']
        password = form.cleaned_data['password']

        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)
            return redirect('dashboard')
        else:
            messages.error(request, "Invalid credentials")

    return render(request, 'custom_login.html', {'form': form})
```

---

### Template: `custom_login.html`

```html
<h2>Custom Login</h2>
{% if messages %}
<ul class="messages">
    {% for message in messages %}
    <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
    {% endfor %}
</ul>
{% endif %}

<form method="POST">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">Login</button>
</form>
```

---

### Logout View (Manual)

```python
from django.contrib.auth import logout

def custom_logout(request):
    logout(request)
    return redirect('custom_login')
```

---

## URLs

```python
urlpatterns = [
    path('login/', custom_login, name='custom_login'),
    path('logout/', custom_logout, name='custom_logout'),
]
```

---

## Recap: How Login Actually Works

| Action | What Happens |
| --- | --- |
| `authenticate()` | Verifies username/password |
| `login()` | Stores user ID in the session |
| `request.user` | Becomes the authenticated user |
| `logout()` | Clears session |

---

## ✅ Task for Day 7

* Create your own `register`, `login`, and `logout` views and templates.
    
* Use `authenticate()` and `login()` in a custom view.
    
* Protect one page (like `/dashboard/`) with `@login_required`.
    
* Bonus: Show login error on invalid input.
    

---

## 🚀 Coming Up in Day 8…

We’ll explore:

* Setup git and github
    
* Setup Environment Variables
    
* Prepare for production environment
