Part 1 Try making user authentication with Djnago. Part 1
First, (I wrote it several times) A review of "authentication" in security!
It looks like this when I write it in the figure
** 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.
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.
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
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.
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 **".
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 **".
Yes, this is the basic knowledge of security (゜ ρ ゜)
So what kind of security features does Django offer?
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