LoginSignup
0
0

個人開発記録 2024/05/06(djangoでログイン機能を実装)

Last updated at Posted at 2024-05-06

目的

  • とにかくやりきることが一番の目的
  • 毎日発信することで、発信する習慣作り
  • 個人開発をやりきることで、実績作り

開発するもの

X(旧Twitter)のパクリ

構成

  • バックエンド
    • python
    • django REST framework
  • DB
    • postgreSQL
  • フロントエンド
    • React

本編

今回はログイン画面を作成していきたいと思います。

バックエンド

以下を参考にログインのバックエンド処理を組んでいきます。

モデルの修正

まずはmodelを修正。
変更点としてはcreate_auth_tokenメソッドを追加。
@receiver(post_save, sender=settings.AUTH_USER_MODEL)をつけることで、User保存後にTokenを生成するようにした。

likeX/user/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser, PermissionsMixin
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token

from likeX import settings


@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    """
    ユーザーが保存された後にトークンを作成する
    """
    if created and instance is not None:
        Token.objects.create(user=instance)


class User(AbstractUser, PermissionsMixin):
    bio = models.CharField(max_length=280, blank=True)
    location = models.CharField(max_length=100, blank=True)
    birth_date = models.DateField(null=True, blank=True)

ログインURLを追加

views.obtain_auth_tokenと紐づけたいURLを追加する。
views.obtain_auth_tokenDjango REST Frameworkが用意しているログイン用のview。
これを使うことによって、Tokenの登録など良しなにやってくれる。

likeX/user/urls.py
from django.urls import re_path, path
from rest_framework.authtoken import views

from .views import UserRegister

urlpatterns = [
    re_path(r'^register/$', UserRegister.as_view()),
    path('login/', views.obtain_auth_token),
]

フロントエンド

LoginFormを作成

/src/auth/components/LoginForm.jsを作成。
マテリアルUIからテンプレートをパクってくる。

routesを作成

src/auth/routes/Login.jsx
import { LoginForm } from "../components/LoginForm";

export const Login = () => {

    return (
        <>
            <LoginForm />
        </>
    );
};

AuthRoutesにLoginを追加

src/auth/routes/index.jsx
import { Route, Routes } from 'react-router-dom';
import { Register } from './Register';
import { Login } from './Login';

export const AuthRoutes = () => {
  return (
    <Routes>
      <Route path="register" element={<Register />} />
      <Route path="login" element={<Login />} />
    </Routes>
  );
};

ログイン画面を表示

表示は完了。

image.png

APIを作成

src/auth/api/login.js
import axios from 'axios';
import { API_URL } from '../../../config';

export const login = (data) => {
    const jsonData = JSON.stringify(data);
    const config = {
        headers: {
            'Content-Type': 'application/json'
        }
    };
    const url = `${API_URL}/api/user/login/`;
    return axios.post(url, jsonData, config)
};

LoginFormのhandleSubmitを以下の通り修正。
usernameemailからとっているのは、おいおい修正。。

/src/auth/components/LoginForm.js
  const handleSubmit = (event) => {
    event.preventDefault();
    const data = new FormData(event.currentTarget);

    const loginData = {
      username: data.get('email'),
      password: data.get('password'),
    };

    // API 関数を使用してデータを送信
    login(loginData)
      .then((response) => {
        console.log('Registration successful:', response);
        // ここに成功時の処理を書く、例えばログインページへリダイレクト等
      })
      .catch((error) => {
        console.error('Registration failed:', error);
        // ここにエラー処理を書く、例えばエラーメッセージの表示等
      });
  };

動作確認

会員登録

image.png

こんな感じでuserとtokenが作成される。

image.png

image.png

ログイン

先ほど作成された会員でログインする。
ログインする前に、トークンを削除しておく。

image.png

先ほどとは違う、Tokenが作成されていることを確認。

image.png

感想

簡単にログイン機能が作成できるのはさすがdjangoって思った。
だが、spring bootとかもそうだけど、カスタマイズがどれだけ簡単にできるかが、フレームワークとしての質が問われると思う。
実際の業務では、フレームワーク作成者の想定より複雑だったりするので。。
明日は、ログイン機能のカスタマイズ練習として、会員登録、ログインの必要項目をメールアドレスにしたい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0