diadia

興味があることをやってみる。自分のメモを残しておきます。

email認証する方法

一つはUserモデルを自分で作成する方法。
もう一つは認証バックエンドにemailで認証するバックエンドを実装して、settings.pyでそれを使う宣言する方法。

後者を最近試してできたので時間があれば詳しく書きたい。

要点だけまとめておく。

1.備え付けのdjango.contrib.auth.authenticate関数を使う
2.認証方法としてメールアドレス認証のバックエンドを作る
3.そのバックエンドを使う旨をsettings.pyで宣言する

リポジトリ

https://github.com/chiaki1990/authentication_backends_sample

1.備え付けのdjango.contrib.auth.authenticate関数を使って認証する

from django.shortcuts import render
from django.views.generic import View
from django.contrib.auth import authenticate, login 
# Create your views here.

class SignInView(View):

    def get(self, request):
        return render(request, 'observe_login/signin.html')

    def post(self, request):
        email = request.POST["email"]
        password = request.POST["password"]
        user_obj = authenticate(request=request, email=email, password=password)
        print("認証されればUserオブジェクト、失敗ならNoneの表示 : ",user_obj)
        if user_obj:
            login(request, user_obj)
        return render(request, 'observe_login/signin.html')

2.認証方法としてメールアドレス認証のバックエンドを作る

from django.conf import settings
from django.contrib.auth.backends import BaseBackend
from django.contrib.auth.hashers import check_password
from django.contrib.auth.models import User

# Emailで認証する方法を選択肢を増やす

class EmailAuthBackend(BaseBackend):

    def authenticate(self, request, email, password):
        print("EmailAuthBackendが呼び出されている")
        print(request, email, password)
        if email and password:
            try:
                user = User.objects.get(email=email)
            except User.DoesNotExist:
                return None
            else:
                if user.check_password(password) and self.user_can_authenticate(user):
                    print("認証成功!!!")
                    return user
        return None

    def user_can_authenticate(self, user):
        """
        Reject users with is_active=False. Custom user models that don't have
        that attribute are allowed.
        """
        is_active = getattr(user, 'is_active', None)
        return is_active or is_active is None


    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

3.そのバックエンドを使う旨をsettings.pyで宣言する

settings.pyにて

# https://docs.djangoproject.com/ja/3.1/ref/settings/#auth
# https://docs.djangoproject.com/ja/3.1/topics/auth/customizing/#specifying-authentication-backends

AUTHENTICATION_BACKENDS = [
    #'django.contrib.auth.backends.ModelBackend',
    'observe_login.utils.EmailAuthBackend'
    ]