DreamerDreamのブログ

夢想家の夢です。〜揚げたてのモヤっとしたものをラフレシアと共に〜

Djangoの使い方⑤ユーザー認証を追加する(会員ページ、ユーザー専用ページ)

前回はApacheのドキュメントルート以外でDjangoを動かしました。

dreamerdream.hateblo.jp

 

今回はDjangoのサーバー機能を使ってユーザー認証機能のテストをします。 

ユーザー認証は会員専用ページとかユーザー専用のページを作るには必須事項です。

Djangoは認証のややこしい手間を省いてそういったページを作るにはうってつけのツールです。

f:id:DreamerDream:20180925152439p:plain

 

 

ユーザー認証のサンプルはこちらのサイトを参考にさせていただきました。

qiita.com

 

Djangoでは標準でユーザー認証機能が付いています。

[アドレス]/admin

にアクセスするとデフォルトで既にユーザー管理サイトが存在しています。

f:id:DreamerDream:20180921092410p:plain

ちなみに、前回の方法でapache2からアクセスするとスタイルシートが読み込まれていない場合はこのようになります↓

f:id:DreamerDream:20180921091025p:plain

プロジェクトのmanage.pyのあるディレクトリから

$ python3 manage.py runserver 0:8000

としてDjangoのサーバーで起動しましょう。

 

 

しかしこのままではユーザー登録をしていないので何を入力してもログインできません。

まずは「管理者」を登録する必要があります。

 

manage.pyのあるディレクトリから以下を実行します。

@raspberrypi:/home/django/draemon $ sudo python3 manage.py createsuperuser
ユーザー名 (leave blank to use 'root'): draemon
メールアドレス: dradra@draemon.jp
Password: 
Password (again): 
このパスワードは短すぎます。最低 8 文字以上必要です。
このパスワードは一般的すぎます。
このパスワードは数字しか使われていません。
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

パスワード(1234)は短すぎるとか数字だけとか怒られてしまいましたがテスト用なのでy(yes)としてadmin登録しました。

登録してからログインするとログイン後のページが表示されるはずです。

f:id:DreamerDream:20180921132655p:plain

このようなエラーが出たら

f:id:DreamerDream:20180921135253p:plain

データベースのアクセス権限エラーのようです。

[ データベース ] と [ 親ディレクトリ ]をその他ユーザーで扱えるようにしましょう。

ちなみに、Raspbianで使っているapache2のユーザー名はデフォルト「www-data」でした。CentOSの場合は「Apache」です。

 

 

Djangoからデフォルトで提供されているユーザー認証機能は

  • ログイン
  • ログアウト
  • パスワード管理(再設定)

の3つだけのようです。

それぞれに対応したURLパターンも決められているようです。

accounts/login/ [name='login']

accounts/logout/ [name='logout']

accounts/password_change/ [name='password_change']

accounts/password_change/done/ [name='password_change_done']

accounts/password_reset/ [name='password_reset']

accounts/password_reset/done/ [name='password_reset_done']

accounts/reset/<uidb64>/<token>/ [name='password_reset_confirm']

accounts/reset/done/ [name='password_reset_complete']

 

ところで、一番最初に欲しい「ユーザーの新規登録機能」は提供されていないようです。これは「登録っつったて名前やIDやメールアドレスや住所や各種管理番号や用途によっていろいろあるから自由に作ってね」ということでしょう。サンプルとして動かすには少し面倒そうです。

 

 

何はともあれ、機能を実装するにはまずはログイン・ログアウトの設定をします。

/home/django/draemon $ sudo nano draemon/urls.py

で、pathにaccounts/を追加します。

urlpatterns = [
path('admin/', admin.site.urls),
path('hello/', include('hello.urls')),
path('accounts/', include('django.contrib.auth.urls')),
]

これでログイン/ログアウト関連のビューが今から作るaccountsアプリとして有効化されます。

 

/home/django/draemon $ sudo nano draemon/settings.py

settings.pyにログイン後のリダイレクトアドレスを設定します。

LOGIN_REDIRECT_URL = '/hello'

設定しない場合はデフォルトで/profileページに飛びます。これはオプション機能のようです。

 helloアプリケーションは以前に作ったコレです。

dreamerdream.hateblo.jp

 

 

ユーザー認証用にaccountsというアプリケーションを作ります。

/home/django/draemon $ sudo python3 manage.py startapp accounts

アプリケーションをプロジェクトに登録します。 

/home/django/draemon $ sudo nano draemon/settings.py

 

INSTALLED_APPS = [
'hello',
'accounts.apps.AccountsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]

 アプリケーションのurls.pyを作ります。

/home/django/draemon $ sudo nano accounts/urls.py

 

#!/usr/bin/python3
#coding:utf-8
from django.conf.urls import url
from django.urls import path
from . import views

app_name='accounts'

urlpatterns = [
path('signup/', views.SignUpView.as_view(),name="signup"),
]

 

アプリケーションのurls.pyに連携させるようにプロジェクトのurls.pyも編集します。

/home/django/draemon $ sudo nano draemon/urls.py

 

urlpatterns = [
path('admin/', admin.site.urls),
path('hello/', include('hello.urls')),

path('accounts/', include('accounts.urls')),
path('accounts/', include('django.contrib.auth.urls')),
]  

 

accountsアプリケーションのviews.pyを編集します。

/home/django/draemon $ sudo nano accounts/views.py

 

from django.shortcuts import render
from django.contrib.auth.forms import UserCreationForm
from django.urls import reverse_lazy
from django.views import generic

class SignUpView(generic.CreateView):
  form_class = UserCreationForm
  success_url = reverse_lazy('login')
  template_name = 'accounts/signup.html'

 

 テンプレートをaccountsアプリケーションの中に作ります。

/home/django/draemon $ sudo nano accounts/templates/accounts/signup.html

 

{% extends 'base.html' %}

{% block content %}
<h1>Sign up</h1>
<section class="common-form">
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="submit">Sign up</button>
</form>
</section>
{% endblock %}

 

これで一度サーバーを起動させて/signupしようとしたらエラーが出ました。

どうやらデフォルトのhtmlが読めないらしいです。

よくわかりませんが、ベースのtemplateが読み込めないエラーが出たのでdjangoのプロジェクト直下にtemplatesディレクトリを作成し、必要なテンプレートをDjangoからコピーしました。

 

まずはデフォルトのテンプレートが格納されているディレクトリを調べます

$ python3 -c "import django; print(django.__path__)"
['/usr/local/lib/python3.5/dist-packages/django']

ここにtemplateディレクトリがあるので全てコピー

sudo cp -r /usr/local/lib/python3.5/dist-packages/django/template /home/django/draemon

すると読み込んでくれました。(強引な方法なのかもしれない)

f:id:DreamerDream:20180925145614p:plain

これでサインアップページが出来ました。

 

Djangoでログインできた登録ユーザーしか見られないページを作るのは簡単です。

views関数の前に@login_requiredを付け加えるだけ。

from django.contrib.auth.decorators import login_required

@login_required
def hello_world(request):

 

これでログインしていない状態でアプリケーションアドレスへアクセスすると自動でログイン画面に飛ばされます。

f:id:DreamerDream:20180925141656p:plain

ログインした状態でアプリケーションへアクセスすると通常の画面が表示されます。

会員専用ページですね。

f:id:DreamerDream:20180925141758p:plain

これらの機能を自前で作ろうとするとクッキーやらhiddenやらのお勉強が結構な手間なので非常に有り難い機能です。 (bottleには無い)

 

じゃあ、ユーザー専用ページは?

試しに、id、ユーザー名、パスワードを出力させてみました。

from django.http.response import HttpResponse

import datetime

from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User

@login_required
def hello_world(request):
  userid = str(request.user.id)
  username = request.user.username
  password = request.user.password
  return HttpResponse("<h1>Hello World!</h1>" + userid + ':' +username+':'+password)

 

 

パスワードにはsha256というビットコインでも使われている強力なhash値が使われており、生のデータは保存されていないので安心できそうです。

f:id:DreamerDream:20180925143814p:plain

 

これでユーザー情報を元にログインユーザーの専用ページを表示させるというシステムが組めますね。

 

 <追記>毎回ログイン時に表示される「Django管理サイト」の名前を変更する方法↓

dreamerdream.hateblo.jp

 

 

 

 <参考ページ>

会員登録機能

Djangoで、会員登録機能を自作する - naritoブログ 

Django2 でユーザー認証(ログイン認証)を実装するチュートリアル

 

 データベースエラー

Djangoの管理画面作成 | 屋根裏の部屋

 

ユーザー情報

Djangoでログインユーザの情報をビューに渡す

django.contrib.auth | Django documentation | Django

 

 

dreamerdream.hateblo.jp

 

kampa.me