hikaru’s diary

Django Engineer

【Django】認証機能を作る

今回は認証機能を作ります。前回、テスト開始時にコピーされたデータベースが作られると思っていて手こずったのでちゃんとドキュメントを読みながら作ります。
仕様として、(入力が楽になるように)誰がログインしているか?のみ今は使いたいのでカスタムユーザーとかは作らないと思います。
Django でのユーザー認証 | Django ドキュメント | Django

ユーザを作成する

https://docs.djangoproject.com/ja/4.0/topics/auth/default/#:~:text=%E3%81%A3%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82-,%E3%83%A6%E3%83%BC%E3%82%B6%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B,-%C2%B6

python manage.py shell」でシェルを立ち上げてユーザーを作成

>>> user = User.objects.create_user('hikaru','mail@gmail.com','pass')
>>> user.last_name = 'aiu'
>>> user.save()
ユーザーを作成。メールは適当でもいいらしい。
>>> from django.contrib.auth import authenticate
>>> user = authenticate(username='hikaru',password='pass')
>>> if user is not None:
... 	print('yes')
... else:
... 	print('no')
... 
yes

作成していることを確認

ユーザーをログインさせるには

https://docs.djangoproject.com/ja/4.0/topics/auth/default/#:~:text=for%20anonymous%20users.%0A%20%20%20%20...-,%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%92%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E3%81%95%E3%81%9B%E3%82%8B%E3%81%AB%E3%81%AF,-%C2%B6

権限とかは今回必要ではないのと難しそうなのでとりあえずスルー。
ログインページ作るのも面倒なのでメインページ的なところに作成。

main.html

<p>ログインします。</p>
    <form method="POST">
        {% csrf_token %}
        <p>{{ form.as_p }}</p>
        <button type="submit" name="btn1">ログイン</button>
        <button type="submit" name="btn2">ログアウト</button>
    </form>
    <p> {{ check }}</p>

views.py

from django.contrib.auth import authenticate, login, logout


class main(TemplateView):
    template_name = 'main.html'

    def main(self, **kwargs):
        app_name = 'diary'

        params = {'form': None}
        if self.method == 'POST':
            form = main_form(self.POST)
            if 'btn1' in self.POST:
                username = self.POST['username']
                password = self.POST['password']
                user = authenticate(self, username=username, password=password)
                if user is not None:
                    login(self, user)
                    # Redirect to a success page.
                    params['check'] = "ユーザー名:" + username + "でログインしました!"
                else:
                    # Return an 'invalid login' error message.
                    params['check'] = "ユーザー名またはパスワードが間違っています。"
            elif 'btn2' in self.POST:
                username = self.POST['username']
                password = self.POST['password']
                logout(self)
                params['check'] = "ログアウトしました!"
            params['form'] = form
        else:
            params['form'] = main_form()

        return render(self, 'main.html', params)

forms.py

class main_form(forms.Form):
    username = forms.CharField(label='ユーザー名', max_length=100)
    password = forms.CharField(label='パスワード', max_length=100)

urls.py

urlpatterns{
path('main/', views.main.main, name='main'), # 追加
}


f:id:hikaru2323:20220212213634p:plain

f:id:hikaru2323:20220212213703p:plain

ログインできました。ここからログイン情報の記憶とcokkieの保存を作っていきたいです。



ブラウザを閉じたらログアウトになるって思ってたんですけど、そうじゃないらしいです。
djangoのセッション保持期間について調べてみた - Qiita

Django でログインセッションの有効期限を設定するのが意外と大変だった - Qiita

ログイン状態の表示

views.py

        if self.user.is_authenticated:
            params['user'] = "ようこそ" + str(self.user) + "さん!"
        else:
            params['user'] = "ログインしていません。"

        return render(self, 'main.html', params)


viewsの末尾に追加。こういうやつ先頭に付けがち。
他のページに行ってもログイン保持したのを確認したので終了です。お疲れさまでした。


追記3/9
shellでユーザーを登録するときに以下をインポートしてください
from django.contrib.auth.models import User