DreamerDreamのブログ

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

Djangoの使い方⑥cssを含むstaticディレクトリのコピー

以前の記事のようにApacheDjangoのページを表示しようとするとレイアウトが崩れることがあります。 

dreamerdream.hateblo.jp

 

原因はデフォルトのスタイルシート、staticディレクトリが読み込めないということです。

 

本来、このような型で表示されるべきところが

f:id:DreamerDream:20180921135643p:plain

 

このようにレイアウトの崩れたページになります。

f:id:DreamerDream:20180921135653p:plain

 

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

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

 

そのままではapache用に/usr/以下のデフォルトのディレクトリの権限を変更しないといけないので、必要なファイルを含むディレクトリ(今回は求められているstatic/adminのスタイルシート)をプロジェクトのディレクトリに全コピーします。

f:id:DreamerDream:20181001165913p:plain

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

つまり、

/usr/local/lib/python3.5/dist-packages/django/contrib/admin/static/admin/

以下のものを全て

/home/django/draemon/draemon/static/admin/

として使います。

 

コピー先にApache2のサイト.confでAliasを設定し、権限を与えます。

/etc/apache2 $ sudo nano sites-available/draemon.conf

下記を追加

Alias /static/admin/ /home/django/draemon/draemon/static/admin/
<Directory /home/django/draemon/draemon/static>
Require all granted
</Directory>

これで/static/admin/にアクセスしてきたものがプロジェクト内にコピーしたファイルにアクセス出来ることになります。

コピーなのでスタイルシートも好きに弄って大丈夫です。

 

ディレクトリの場所はややこしいですが、[プロジェクトディレクトリ]/[プロジェクト名ディレクトリ]/staticです。

解らなければApacheのエラーログを見れば良いです。

client denied by server configuration: /home/django/draemon/draemon/static, 

と出ていますのでここのstaticディレクトリが読めていないんだなーということが解ります。

 

 

 

次回 

dreamerdream.hateblo.jp

 

 

<参考サイト>

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

VPSの使い方 ⑤SWAP領域を拡大する

 前回記事

dreamerdream.hateblo.jp

 

 

僕はVPSの格安プランに申し込んだのでメモリ領域は512MBしかありません。

個人のWebサイトだけであれば充分ですが、それならレンタルサーバーの方が安いのでわざわざVPSにはしていません。もちろん他にもアプリを動かします。もし、何かしらでアクセスが集中するとサーバーが落ちてしまいます。そのための予防手段です。

 

システムで使用されているメモリーを調べるために再起動

sudo reboot

freeで確認すると

free
          total     used      free     shared     buff/cache     available
Mem: 499452 83992 281768 4596 133692 386772
Swap: 2097148 0 2097148

最初から約300MB弱しか余裕が無いのが解ります。

 

ここでhttpdを立ち上げてDjangoの初期ページにアクセスしてみました。

sudo systemctl start httpd

再度確認


free
          total     used     free     shared     buff/cache available
Mem: 499452 165212 178624 4684 155616 304212
Swap: 2097148 0 2097148

そうすると200MB弱しか余裕が無くなります。Apachedjangoを起動させたので当然です。

 

モリーは環境にもよりますが、Webページ1件のアクセスで約20MB〜30MB消費されるとされています。(今回はデフォルトページの表示だけで大したことはありませんが)

ベリーキュート Blog » Blog Archive » Webサイトのアクセス数増加と必要メモリ

そうなると同時に10件や20件のアクセスがあるとあっという間にメモリー不足に陥ります。

モリー不足に陥ったサーバーはSwap領域というストレージ上にメモリー領域を確保しにいきます。

 

上の表のSwapと表されているところがメモリー領域として確保されているストレージ領域です。メモリーが足りている場合は当然使用量は0です。

Swap領域は本来高速なRAMメモリーへのアクセスが必要な処理をストレージで補うのでRAMメモリーより低速です。

ですが、Conohaのストレージは全てHDDよりは高速なSSDです。

これを活かさない手はありません。

モリー不測の事態でも、遅くなっても仕事はしてくれます!

 

ということでSwap領域を拡大します。

Linux の SWAP 領域を増やす : まだプログラマーですが何か?

今、約2GBのswapが確保されているのでさらに+2GBの余裕を持たせることにします。

まずはddコマンドで2GBのファイルを作ります。

sudo dd if=/dev/zero of=/var/swapfile bs=1M count=2048
2048+0 records in
2048+0 records out
2147483648 bytes (2.1 GB) copied, 4.59156 s, 468 MB/s

swapファイルとします。

sudo mkswap /var/swapfile
Setting up swapspace version 1, size = 2097148 KiB
no label, UUID=b865b7eb-584e-444e-age3-dc4fefei

swapとして登録します。

sudo swapon /var/swapfile
swapon: /var/swapfile: insecure permissions 0644, 0600 suggested.

 

fstabに作ったswap領域を追記します。

sudo nano /etc/fstab

 

/var/spool/swap/swapfile none swap defaults 0 0
/var/swapfile swap swap defaults 0 0 <=追記

これで再起動後もこのファイルがswapとして扱われます。

確認します。

free
total used free shared buff/cache available
Mem: 499452 270908 5876 4676 222668 198116
Swap: 4194296 0 4194296

 

これでSwapが4Gとして認識されています。

f:id:DreamerDream:20180928131757p:plain

 

 

Swapを解除するには

sudo swapoff /var/swapfile

として、追記したfstabファイルからも削除します。

 

実際にこんなに必用か?と問われると・・同時に100件アクセス?一生必用無いかもしれません。しかし、もしストレージいっぱいまで使ってしまってから確保するとなると難しいので予め確保しておきます。

実際に500MBを絶えず軽く超えてくるようなアクセスがある場合はサーバーの追加でWebページの移転作業となるでしょう。その際にも4GBもの余裕があると慌てずに済むでしょう。

ちなみにこの方法だとサーバーを再起動しなくてもswap確保できるのだそうです。

 

※過去記事では、RaspberryPiの場合はSwapを使うとSDカードの寿命に影響を及ぼす可能性があるのでSwapを無効にしていました。

dreamerdream.hateblo.jp

Conohaで使われているSSDフラッシュメモリですが、VPSの場合はミラー化してあったりと物理的に寿命がくるようなシステムは全て管理され定期的に交換されていますので、ユーザーはストレージ寿命を全く気にすることなくストレージを使う事が出来ます。このあたりも自宅サーバーよりVPSをオススメする重要な要素です。

 

全5回に渡ってVPS導入からセキュリティー対策等の使い方を備忘録として記しました。

またどなたかの約に立てば幸いです。

 

 

 

#memo:

ここまでの設定をイメージ保存

f:id:DreamerDream:20180928141108p:plain

SELinuxデフォ無効

VPSの使い方 ④必用なアプリをインストールする

 前回記事

dreamerdream.hateblo.jp

 

 

VPS必用なアプリは当然ながら目的によって異なりますが、僕はApacheDjangoでのwebサービスの構築を目指していますのでウェブサービスの為に必用なアプリをインストールします。

中盤のDNSの設定はssh接続だけでも必用かもしれません。

f:id:DreamerDream:20180928131621p:plain

 

 

Apacheインストール

Apache httpd 2.4 を CentOS 7 に yum でインストールする手順 | WEB ARCH LABO

RaspbianではApache2というパッケージでしたが、CenntOSではhttpdというパッケージなのですね。Apacheではなくhttpdと呼んだほうがいいのかな?

sudo yum info httpd

sudo yum -y install httpd

.

.

.

Complete!

 

で完了です。はやっ!

 

とりあえず起動

sudo systemctl start httpd.service

 

アクセスすると、おや?見れませんね。

f:id:DreamerDream:20180926163011p:plain

ファイアーウォールが関係していることがあるそうなので、ファイアーウォールを切ります。

sudo systemctl stop firewalld

再びアクセスすると、おおっ!初めて見るApacheだ!

f:id:DreamerDream:20180926163119p:plain

原因が判明したのでファイアーウォールを再起動させます。

sudo systemctl start firewalld

 

以下のコマンドでhttpの80番ポートの開放とファイアーウォールの再起動をするとちゃんと機能するようになります。

sudo firewall-cmd --add-service=http --zone=public --permanent

sudo firewall-cmd --reload

 

 

 

起動時にhttpdも起動させるにはサービスに設定する必用がありますがまだテストなので登録はしません。

systemctl enable httpd.service

テスト用として任意のポートを開く方法もググったので残します。

【すぐわかる】CentOSのポート開放のやり方

例えばポート8000番を開く場合

sudo firewall-cmd --zone=public --add-port=8000/tcp

恒久的に開く場合

sudo firewall-cmd --zone=public --add-port=8000/tcp --permanent

設定したらリロードして完了

sudo firewall-cmd --reload

確認コマンド

sudo firewall-cmd --list-all

 

Webサーバーとして公開すると大量パケットを送りつけるDDOS攻撃というサイバー攻撃を受けることがあります。PVSではこのような攻撃を受けると、コチラに非が無くとも停止処分を食らうこともありますのでそのような対策ツールの導入も予め検討しておきましょう

dreamerdream.hateblo.jp

 

 

DNSの設定

IPアドレス直打ちでもアクセス出来るっちゃ出来るんだけど、何か気持ち悪いので仮のドメインが欲しいところ。

本気のドメインムームードメインで後ほど取得するとして、今回は過去に無料で取得して使っていない(ムームーに置き換えた)ドメインを転用すようにしました。(VPSは固定IPなのでcronで設定する必要性は無いけど長期間更新しないと消されるので1日置きぐらいで更新)

取得と設定はRaspberrypiと同じ方法で↓

dreamerdream.hateblo.jp

これでドメイン名でHPもSSHもアクセスできます。 

 

と思ったけど、ここでハマった。

 wget http://(マスターID):(パスワード)@www.mydns.jp/login.html

と打ったけど・・・

丸一日、待てども暮らせどもIPアドレスが更新出来ないという事態に陥ってしまった。

しかたがないのでもう一度新しいドメインを取得させてもらって同じように打ったんけど更新されない???

何かおかしい!と思って取得したHTMLファイルを見直すと(---は伏せ字)

<DT>MASTERID :</DT><DD>mydns------</DD>
<DT>REMOTE ADDRESS:</DT><DD>24--:----:---:---:---:---:---:---</DD>
<DT>ACCESS DAYTIME:</DT><DD>2018/09/--8 --:--:-- UTC</DD>
<DT>SERVER ADDRESS:</DT><DD>26--:18-:---:---:---:---</DD>

ちょ?これIPv6のアドレスじゃないの?って調べたら、同じようにハマってた人がいた!!ナマカマカマ

MyDNS.jp と IPv6 : GONGON の無線日誌

「www.mydns.jp」ではなく、「ipv4.mydns.jp」で接続しないとダメだったらしい。。。待ってた一日を返してくれ

てことで、V4アドレスの更新は

 wget http://(マスターID):(パスワード)@ipv4.mydns.jp/login.html

で更新できます。お間違えないよーに。

このドメイン更新のhttp-basicアクセスなのでセキュリティー的にはNGなんだろうけど、とりあえずwebページを作成してムームーで新しく取得するまでは仮のドメインとして使います。

追記) ムームーでドメイン取得しました。

dreamerdream.hateblo.jp

 

 

 

Python3インストール

CentOSは標準でpython2.7、python3はインストールが必用だそうです。こんなレベルからもRaspbianとは違うのか。

CentOS 7 + python3 + Djangoの本番環境を動かしてみる

python3とpip3のインストール

sudo yum install -y https://centos7.iuscommunity.org/ius-release.rpm

sudo yum install -y python36u python36u-libs python36u-devel python36u-pip

 

 

Djangoとpipのインストール

sudo pip3.6 install django

pipのアップグレードが促されたのでそれもインストール

sudo pip3.6 install --upgrade pip

 

wsgiのインストール

sudo yum install -y python36u-mod_wsgi

 

設定ファイル

/etc/httpd/conf.modules.d/10-wsgi-python3.6.conf

が作成されるので必用に応じて編集すればhttpdと連携出来るそうですが、もう少しCentOSに慣れたいのでそれはまた後日にします。

 

 

ざっくりとアプリをインストールしてみて、参考サイトの通りにDjangohttpdApache)も試してみました。

CentOS 7 + python3 + Djangoの本番環境を動かしてみる

RaspberryPiと比較した感想は

一言「はやっ!!!」です。

モリーが最低限の512MBプランなのでそんなに変わらんやろー。と思っていたのですが、サスガは大手の回線だけあってアプリのダウンロードものすごく早いしhttpdの起動もレスポンス早いし超キモチイー!!(古)です!

VPS導入してから殆ど待ち時間なくアプリのインストールまで完了しました。

 

 

 

dreamerdream.hateblo.jp

 

 

[memo]

1つのサーバで複数ドメインを運用したい! | Webサイト構築簡単メモ

VPSの使い方 ③不要なサービスとポートを閉じる

 前回記事

dreamerdream.hateblo.jp

 

 

ポートを閉じるにはまずは現段階の何もインストールしていない状態でどのポートが開いているか?を調べる為にポートスキャンソフト、NMAPをインストールします。

yum -y install nmap

nmapコマンドで覚えておきたい使い方11個 | 俺的備忘録 〜なんかいろいろ〜

とりあえずポートの開放状態の確認

nmap 127.0.0.1

 

Starting Nmap 6.40 ( http://nmap.org ) at 2018-09-26 15:12 JST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00060s latency).
Not shown: 997 closed ports
PORT STATE SERVICE
25/tcp open smtp
111/tcp open rpcbind
50/tcp open ____

Nmap done: 1 IP address (1 host up) scanned in 0.10 seconds

 

おや?sshで設定したポート以外に25と111が開いています。

111番はリフレクション攻撃の対象ポートだそうです。

リフレクション攻撃の増加でDDoS攻撃が大規模化 | さくらのナレッジ

ファイアーウォールから閉じるのでしょうか?

sudo firewall-cmd --permanent --remove-port=111/tcp
Warning: NOT_ENABLED: 111:tcp
success

止まりません!なんで??

9.6. NFS の起動と停止 - Red Hat Customer Portal

sudo service rpcbind status

でステータスが見れるとフムフム。

じゃあ

sudo service rpcbind stop

で停止できるんじゃないか?と推測

nmap localhost


PORT STATE SERVICE
25/tcp open smtp
50/tcp open ____

止まったようです。が、再起動で復活!なんやねん?これ?

とりあえずサービスで動いてるっぽいから

sudo systemctl stop rpcbind
Warning: Stopping rpcbind.service, but it can still be activated by:
rpcbind.socket

サービス自動起動を停めます。

sudo systemctl disable rpcbind
Removed symlink /etc/systemd/system/multi-user.target.wants/rpcbind.service.

止まった。

 

次、25番はメールの受信ポートらしい。使わないのでもちろん閉じる!

25番ポートを開くという情報は多い物の閉じるという情報は少ないので苦労しました。

メールサーバー構築(Postfix+Dovecot) - CentOSで自宅サーバー構築

こちらの記事もメールサーバーの構築記事だけど、もしかして?と思って確認したら

sudo systemctl status postfix.service

postfix.service - Postfix Mail Transport Agent
Loaded: loaded (/usr/lib/systemd/system/postfix.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2018-09-26 15:53:17 JST; 15min ago

 

はいはい、しっかりメールサーバが動いてましたとも。

sudo systemctl stop postfix.service

で停止して自動起動も停止。

sudo systemctl disable postfix.service

これでsshポート以外閉じることが出来ました。

 

f:id:DreamerDream:20180928131358p:plain

 

 

dreamerdream.hateblo.jp

 

 

VPSの使い方 ②初期設定

前回、Cohohaに申し込みましたので、今回はVPSの初期設定編です。 

dreamerdream.hateblo.jp

 

初期設定は基本的にはRaspberryPiと同様ですが、firewallの設定が必用なこと、 ブラウザ上のターミナル操作(実質実機上の操作と同じ)とクライアントPCからのターミナル操作の使い分けが必用です。

dreamerdream.hateblo.jp

 

まずはブラウザ上のターミナルからユーザー追加とssh設定をします。

 

ユーザーの追加

useradd [name]

ユーザーのパスワード設定

passwd [name]

 

sshポートの変更

デフォルト22番からsshポート番号を変更します。

nano /etc/ssh/sshd_config

f:id:DreamerDream:20180926142110p:plain

 

ファイアーウォールsshポート変更

CentOS7からファイアーウォールがiptablesからfirewalldに変更になったようで、よく見るiptablesの設定でははく、firewall-cmdを使った変更が必要なようです。

<参考>

CentOS7でSSHのポート番号を変更する

一覧表示

firewall-cmd --list-all

f:id:DreamerDream:20181002140751p:plain

この一覧からsshを削除します。

firewall-cmd --permanent --remove-service=ssh

ssh.xmlの設定をコピーして使います。

cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/ssh-50.xml

内容を編集します。

nano /etc/firewalld/services/ssh-50.xml

ポートの指定22から任意のポート番号に変更します。

<port protocol="tcp" port="50"/>

ファイアーウォールに追加します。

firewall-cmd --permanent --add-service=ssh-50

再起動します。

firewall-cmd --reload

最終確認でssh-50(任意のファイル)が認識されていたらOK!

firewall-cmd --list-all

 

visudo

でユーザーへ権限追加します。

Raspbianはvisudoでnanoが選べましたがCentOSはデフォルトでvimエディタ

「a」キーで編集して、「esc」キーで編集終了

「:w」入力で上書き保存「:q」で終了。「:q!」で保存しないで終了。

デフォルトで

root ALL=(ALL) ALL

とrootには全ての権限が与えられています。

[ユーザー] ALL=(ALL) ALL

とすることで任意のユーザーにsudo権限が与えられますがrootと違うのはsudoコマンドでパスの入力が必要です。

 

一度再起動して

reboot

 

f:id:DreamerDream:20180928131540p:plain

///////////////

ここで一旦クライアントPCのターミナルから登録ユーザーでVPSIPアドレスと任意のポートからログインしてみてsudo操作に問題が無いことを確認します。

///////////////

 

rootでのsshログイン禁止処置をします。


新しいユーザーでログインしてから

sudo nano /etc/ssh/sshd_config

sshd_congifの項目のPermitRootLogin yesを

PermitRootLogin no

と設定します。

 

もう一度再起動

sudo reboot

 

 

※このようなポートの変更、rootログイン禁止という基本処置をしていてもSSHへの攻撃は容赦なく行なわれます。

↓こういったツールの導入も検討しましょう。

dreamerdream.hateblo.jp

 

 

システムをアップデートします。

アップデートがあるか確認します。

sudo yum check-update

あればアップデート、初回起動ではまあ必ずありますよね。

sudo yum update

以降カーネルを外してアップデートする手順

yumでシステムアップデートする(カーネルは除く)|Linux Tips

 

普通にアップデートしていればカーネルのアップデートも対象になります。

しかし、場合によってはカーネルを何でもかんでもアップデートしてしまうとシステムに不具合を来す場合もあるのでカーネルはアップデートの対象外とすることが望ましいようです。

通常、カーネルを除外するコマンドは

sudo yum -y update --exclude=kernel*

ですが、面倒なので

sudo nano /etc/yum.conf

を編集して

exclude=kernel* ←追加

これで普通にアップデートしてもカーネルは除外されます。

 

こうするとアップデートにkernelが含まれていれば「kernelがアップデートできないよー!」とOSに文句を言われます。

そしたらVPSを一回バックアップイメージに残しておき、上記コマンドをコメントアウトしてからアップデートをします。

そうすると万が一、カーネルのアップデートによるトラブルが発生してもバックアップイメージからアップデート前のVPSを復元することができます。

 

////もっと便利に///

yum-cron」というツールで自動アップデートする方法もあるそうです。

セキュリティーのみ自動アップデートしようかな?そのためには少し弄らないといけないらいいので後ですることにして、こちらに参考ページをメモ。

CentOS7 での yum –security update 事情 « LANCARD.LAB|ランカードコムのスタッフブログ

////////////


カーネルバージョン確認コマンド

uname -r
3.10.0-862.2.3.el7.x86_64

 
CentOSバージョン確認コマンド

cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)

 

ここまでで初期設定は完了。

一度バックアップイメージを作ります。

VPSをシャットダウンします。

sudo poweroff 

 

イメージ保存で保存します。

f:id:DreamerDream:20180926145552p:plain

このように保存されるといつでもこの初期設定後の状態に戻せます。

f:id:DreamerDream:20180926145643p:plain

 

 次は、「不要なサービスはセキュリティー強化の為に停止しましょう。」というお話です。

dreamerdream.hateblo.jp

 

 

VPSの使い方 ①申し込み

以前からラズパイサーバーに構築したアプリをVPSで稼動させたいなー、と思いながらもなかなか思い腰が上がらなかったのですが、今回とうとうCohohaに申し込んでしまいました。

↓詳細ページ(今回申し込んだプラン)

【512MBプラン】なんと月額630円/1時間1円【ConoHa VPS】

今回、サーバーの導入から設定までを備忘録として残すことにします。

 

自宅サーバーよりVPSを選ぶべき理由は以前書いた記事を参考にどうぞ。 

dreamerdream.hateblo.jp

 

 

ーConohaにした理由ー

料金が安いこと。

コンソールが解りやい。

スケールアップが出来る(1GB以上のプランの場合)

バックアップイメージ作成50GBまで無料。

  

ストレージはSSDで爆速、個人のサーバーであれば一番安いプランでも充分そうです。

ということで630円/月の一番お手軽なプランを選択しました。

※誕生日月にはお誕生日クーポンを頂きました!最安プランなのにスゴイ!(この月は実質130円のサーバー代♪)

f:id:DreamerDream:20190625125205p:plain

 

スケールアップは出来ないけど、いざとなればスケールアウト(イメージをそのまま新しいサーバーに移す)することにします。

f:id:DreamerDream:20180926141819p:plain

 

OSは予め選択肢として用意されているイメージから選ぶも良し、自前で用意するも良し。

今回はサーバー用途なので安定を求めてCentOSを選択しました。RaspberryPiで使っていたRaspbianはDebianベースなのでディレクトリ構造等の使い勝手が違うようです。

Debianは最新のシステムで構築できることが魅力的なのですが、アップデートでのトラブルはよくあるそうです。(ラズパイサーバーでも遭遇したことがあります。)

CentOSは若干古いシステム(2年ほど遅いそうです)になるそうですが、安定性がバツグンだそうでサーバーとしてはよく使われています。

f:id:DreamerDream:20180926141827p:plain

ちなみに、ConohaはLinuxだけでなくWindowsServerシステムも提供していますがやはりスペックが求められるシステムだけあって最低でも2000円弱〜になるようです。

WindowsServerは使った事がありませんが、Linuxのようなコンソール操作でなく、やはりよく見慣れたWindows画面をベースにしたサーバーを組めるのが魅力なのでしょう。

サーバーOSとは?UNIX系とWindows系の違いをわかりやすく解説します | カゴヤのサーバー研究室

f:id:DreamerDream:20180926141834p:plain

サーバーOSを選択したらrootパスワードを入力します。セキュリティー上色々と制約があり、

  • アルファベッドの大文字と小文字を両方使うこと
  • 数字を使うこと
  • 記号を使うこと

が求められます。

f:id:DreamerDream:20180926141844p:plain

ネームタグは複数サーバーを運用する際に管理用に名前を付けるものなので何でも良いです。

f:id:DreamerDream:20180926141851p:plain

登録したら既にサーバーは起動していますので「コンソール」を選んでみましょう。

f:id:DreamerDream:20180926141900p:plain

通常のLinuxと同じCUI画面です。

f:id:DreamerDream:20181003085004p:plain

rootでログインして中身を見てみると、なにも余計なものが入っていない綺麗な状態のOSです。

 

 

さて、これからセキュリティーやアプリのインストールなどの作業が始まります。

f:id:DreamerDream:20180928131202p:plain

 

 

dreamerdream.hateblo.jp

 

 

 <追記>2020年、料金とSSD容量が改定されました。

dreamerdream.hateblo.jp

 

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