まずはユーザー登録。これがなければ何も話が進まない。
ひとまず下記の第3回までを見てさくっと動作確認とユーザーテーブル作成まで行う。
material-uiでさくっと作成。Twitterのトップ画面を見ると今回必要そうなコンテンツはこれだけ。
アカウント作成でsignupページヘ。
こちらも同様にぱぱっと作成。
このページはユーザー登録とログインのサーバーへの通信が必要なのだが、
そのままだとCSRFでエラーになるのでensure_csrf_cookieを設定している。
また、後述するconfigライブラリを作成している。
ちなみにログインを押すとモーダルが出てくる。
全体の共通機能として下記のようなファイルを作成した。
app/lib/config.js
const config = {
defaultHeaders: {
"X-CSRFToken": getCookie('csrftoken'),
"Accept": "application/json",
},
url: (url) => {
if (url.charAt(0) === '/') {
url = url.substr(1);
}
return '/dumitter/' + url;
},
}
module.exports = config;
現在さくらサーバーのそのままのURL(SSL)なので、
今後独自ドメインを使う場合全箇所の修正は大変になるためurl補正メソッドを作成。
(最初から独自ドメインなら絶対パスで良いのだが)
また、ajaxの際にCSRFのトークンを送信するため、共通のデフォルトヘッダを定義している。
(getCookieは検索すれば出てくる)
postするとjsonを返却するアクション。
resultがtrueなら成功でログイン済みなのでトップページへリダイレクト。
falseならjsonに各フィールド名のエラーメッセージが入っているのでmaterial-uiのTextFieldのerrorTextにセット。
バリデーションの処理は全部python側でやっている。
js側でもいいかと思ったのだが、パスワードの細かいバリデーションがdjango側に入っているのでそちらに統一した。
(設定ファイルで細かいパスワードのバリデーション方法を指定することができる)
本当はもっとちゃんとした書き方がありそうだが、この処理はここだけだしいいかと思いバリデーションもベタ書き。
from django.http.response import JsonResponse
from django.contrib.auth import authenticate, login as authLogin
from django.contrib.auth.models import User
from django.core.validators import validate_email
from django.contrib.auth.password_validation import validate_password
from django.db import IntegrityError
from django.core.exceptions import ValidationError
import re
def create(request):
errors = {}
if re.match(r'^[\da-zA-Z_]+$', request.POST['name']) is None:
errors['name'] = '半角英数字で入力して下さい。'
try:
validate_email(request.POST['email'])
except ValidationError as e:
errors['email'] = e.messages
try:
validate_password(request.POST['password'])
except ValidationError as e:
errors['password'] = e.messages
if len(errors) == 0:
try:
user = User.objects.create_user(
username=request.POST['name'],
email=request.POST['email'],
)
except IntegrityError as e:
if 'email' in str(e):
errors['email'] = 'そのメールアドレスは既に使用されています。'
elif 'name' in str(e):
errors['name'] = 'そのユーザー名は既に使用されています。'
if len(errors) != 0:
errors['result'] = False
return JsonResponse(errors)
user.set_password(request.POST['password'])
user.save()
return login(request)
def login(request):
authed = authenticate(
username=request.POST['name'],
password=request.POST['password'],
)
result = {'result': True}
if authed is not None:
authLogin(request, authed)
else:
result['result'] = False
return JsonResponse(result)
新規登録後は自動的にログインするが、通常のログインのプログラムと全く同じだったので関数を流用している。
ログイン後はトップページにリダイレクトするが、
ここではログインの場合別のテンプレートを表示するようにしている。
def index(request):
if request.user.is_authenticated():
template = 'main.html'
else:
template = 'index.html'
return render(request, template)
多分邪道かも知れないが下記のようなことを行っている。
const element = document.getElementById('auth-regist');
if (element != undefined) {
ReactDOM.render(<AuthRegist />, element);
}
認証側はこれ以上ページを作るつもりはないので適当。
認証後はルーティングを使いたい。
これで認証が完成したので次は投稿を作っていく予定。
第1回 | Twitterを作る 第1回 概要 |
第2回 | Twitterを作る 第2回 認証 |
第3回 | Twitterを作る 第3回 投稿 |
第4回 | Twitterを作る 第4回 コンポーネント構成考察 |
第5回 | Twitterを作る 第5回 フォロー |
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント