[PYTHON] How to authenticate with Django Part 2

Part 1 Try making user authentication with Djnago. Part 1

Create an authentication backend

First, (I wrote it several times) A review of "authentication" in security!

It looks like this when I write it in the figure

Introduction to Security 1. What is Authentication?

** Authentication ** is "to confirm that the person who accessed is the person who accessed it". It may be rephrased as "** approval " or " identity verification **" in Japanese.

For example, in face-to-face authentication performed by security guards, you may be able to pass by face, but How should a computer, which is a machine, verify the identity of a human being?

Common methods are names and secrets In short, it ’s an ID and password method.

認証.jpg

In addition, "** 2-step authentication **" that adds the person's belongings (smartphone, etc.) to password authentication There are ** biometrics ** using fingerprints and veins, ** face recognition ** using face recognition using deep learning, etc.

Security Overview 2. What is Authorization?

Then, if you ask the guards through the gate in the real world, What will humans do next?

Yes ** Get an admission card **. The admission card determines where you can enter.

This is exactly the same for computers, The computer issues a thing called "** Authentication Token **" to the user

認可.jpg

How your computer system authorizes depends on the framework you use.

I've heard that there is a way to put a specific token in the HTTP header at the time of request, Basically, it compares the cookie with the session information of the server. The session may be in memory or in the DB.

In a broad sense There is also a process that says "** This page is allowed access by general users, but the administrator button is not shown **" This is the process included in the authorization.

Keep in mind that if the user and server have the same authentication token, it's a mechanism to allow access.

What is required for approval

By the way, the important thing in this mechanism is to make sure that the "** admission card **" given by the guard is not strange. Even though we named it an admission card, the reality is that it is just a character string. What if this admission card is a very simple string "2021/01/02"? Anyone can copy and paste and break in illegally.

The admission card requires a ** mechanism to prevent counterfeiting **.

Hacking techniques are constantly evolving, Roughly speaking, there are several ways to forge an admission card. ** "Steal from others" ** ** "Prepare a lie page and have them enter their password" ** ** "Let the machine's calculation speed say something and create a character string until it becomes the correct admission card" ** etc ...

Of these, stealing from other people This is a concrete computer hacking method ** Session hijacking **, called spoofing attack.

↓ An example of session hijacking. I stole the session ID to access the token authenticated by Spring Security and accessed the password protected page on another PC.

What Spring Security can and cannot do https://qiita.com/opengl-8080/items/6dc37f8b77abb5ae1642

In other words, keep in mind that "** It can be easily forged depending on the authentication token **".

Authentication and encryption

So what is an "authentication token that is absolutely unpredictable and almost secure even if stolen"? Yes, here comes the story of "** encryption **".

If you set the authentication token to "** Wakewakanne character string ** that can only be created at the time of issuance", it will be difficult to forge.

In other words, in the world of cryptography and mathematics, this Wakewakanne character string is called ** hash . It is created as " The Wakewakanne string created for authentication does not happen (or maliciously) be like any other in the world. **".

The fact that this "Wakewakanne character string" overlaps with other character strings is called "** collision **".

Implement something that meets this in Django

Yes, this is the basic knowledge of security (゜ ρ ゜)

So what kind of security features does Django offer?

Authentication in Django

Django basically sets the credentials in the session after authentication, Authorize on each view.

And Django sessions are cookie-based sessions, You will store the authentication token in a cookie on the client side

In other words, I think the procedure until approval is done is like this

** 1. Authenticate and save the authentication token in the session (cookie) ** ** 2. Each view determines the token in the session and returns a normal page if it can be authorized, and an abnormal page if it cannot be authorized **

I think it will be like that.

Django is called the ** BaseBackend ** class, We provide a class to customize the authentication process.

With this, Let's create a process that "if the user name and password are the same, the authentication token will be returned"!

First, define the authentication token. Depending on the use, it may be useful to determine the validity period and roles for access control.

This time it's a "simple token that just holds a hash" class!

There is a mysterious field called ** OneToOneField ** OneToOneField This is a field that creates foreign keys with other models. Like the ER diagram, you can create an association with another Entity. Others include OneToMany.

T_UserToken.py


import hashlib

from django.core.validators import FileExtensionValidator
from django.db import models
from datetime import datetime

from config import settings
from memFrame.models import M_User

'''
Authentication token model
'''
from django.contrib.auth.models import PermissionsMixin, UserManager
from django.contrib.auth.base_user import AbstractBaseUser

#User class
class T_UserToken(models.Model):
    #Hash creation
    def create_token(self, user:M_User):
        self = self.__init__()

        #Generate a hash
        self.AuthenticateToken =  hashlib.scrypt(datetime.now() + user.password)
        #Register in DB
        self.save()
        #Returns an object
        return self

    #Field definition
    id = models.BigAutoField(primary_key=True,unique=True)
    #Configure user model and foreign keys
    UserId = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='MUserId',
        )
    AuthenticateToken = models.CharField(max_length=400)
    def str (self):
        return '<User:id' + str(self.MUserId) + ', ' + ')>'

The great thing about the OneToOne field is that you can specify what happens when a related class is deleted. This time, ** on_delete = models.CASCADE **, and when the related class is deleted, this entity is also deleted.

Reference Django official documentation https://docs.djangoproject.com/en/3.1/topics/db/examples/one_to_one/ reference When I looked up the foreign key (on_delete = models.CASCADE), StackOverflow's answer was nice. https://mkai.hateblo.jp/entry/2018/08/11/101245

MemFrameBackAuthenticateEnd.py



from django.contrib.auth.backends import BaseBackend
from django.contrib.auth.hashers import check_password

from config import settings
from memFrame.models import M_User, T_UserToken

"""
Authentication class implemented independently
Authenticate with user name
I will return the token
"""
class MemFrameBackAuthenticateEnd(BaseBackend):
    def get_user(self, user_id):
        try:
            return M_User.objects.get(pk=user_id)
        except M_User.DoesNotExist:
            return None
        # Check the username/password and return a user.
        ...
    #Authenticate users by username or email address
    def authenticate(self, request, username, password):
        #Get user by user name
        user: M_User = M_User.objects.get(username=username)
        #Authentication
        valid = check_password(password, user.password)
        if valid :
            return T_UserToken.create_token(user)
        return None

    #Create an authentication token
    def createAuthToken(self, user:M_User):
        return T_UserToken.create_token(user)

Except for making tokens It simply gets the user and compares the passwords.

Incorporate this into your login view!

Next Authentication in Django Part 2

Recommended Posts

How to authenticate with Django Part 2
How to authenticate with Django Part 3
How to get started with Django
How to do arithmetic with Django template
Authenticate Google with Django
How to develop a cart app with Django
How to measure execution time with Python Part 2
How to update with SQLAlchemy?
How to cast with Theano
How to Alter with SQLAlchemy?
How to separate strings with','
How to RDP with Fedora31
How to Delete with SQLAlchemy?
How to upload with Heroku, Flask, Python, Git (Part 3)
How to make a shooting game with toio (Part 1)
How to upload with Heroku, Flask, Python, Git (Part 2)
Test Driven Development with Django Part 3
Steps to develop Django with VSCode
Test Driven Development with Django Part 4
Python: How to use async with
[Django] How to test Form [TDD]
Test Driven Development with Django Part 6
How to handle static files when deploying to production with Django
How to check ORM behavior in one file with django
How to use virtualenv with PowerShell
How to deal with imbalanced data
How to install python-pip with ubuntu20.04LTS
Common html to rent with Django
Test Driven Development with Django Part 2
How to deal with imbalanced data
[Django] How to give input values in advance with ModelForm
How to resolve CSRF Protection when using AngularJS with Django
How to get started with Scrapy
How to get started with Python
How to deal with DistributionNotFound errors
How to use FTP with Python
How to calculate date with python
How to write Django1.9 environment-independent wsgi.py
How to install mysql-connector with pip3
Test Driven Development with Django Part 1
How to install Anaconda with pyenv
Test Driven Development with Django Part 5
How to deal with "You have multiple authentication backends configured ..." (Django)
Here's a brief summary of how to get started with Django
How to utilize Python with Jw_cad (Part 1 What is external transformation)
How to use Python with Jw_cad (Part 2 Command explanation and operation)
[Tips] How to do template extends when creating HTML with django
Step notes to get started with django
How to title multiple figures with matplotlib
How to get parent id with sqlalchemy
How to add a package with PyCharm
How to check the version of Django
How to delete expired sessions in Django
How to use OpenVPN with Ubuntu 18.04.3 LTS
How to use Cmder with PyCharm (Windows)
How to use Tweepy ~ Part 1 ~ [Getting Tweet]
How to prevent package updates with apt
How to work with BigQuery in Python
How to use Ass / Alembic with HtoA
How to deal with enum compatibility errors
How to use Japanese with NLTK plot