1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

5. Koa2でWebページを作成しよう 〜アカウント登録〜

Posted at

記事一覧

概要

今回は、アカウント登録、ログイン検証の実装を行います。
当記事ではログインは検証に留め、ログイン状態の保持は後の記事で進めていく予定です。
また、前回の続きとして進めて行くので、上手くいかない場合は以前の記事をご覧ください。

アカウントの登録やログインに必要なデータベースはMariaDB(MySQL)を使用します。

インストール

こちらのページからXAMPPをダウンロードし、インストールしてください。
https://www.apachefriends.org/jp/download.html

インストールが完了したら、MySQL DatabaseとApache Web Serverを起動してください。
ブラウザから以下のURLにアクセスすることで、MariaDBに接続・操作できます。
http://localhost/phpmyadmin/index.php

エラーが発生した場合

preg_match_all(): Allocation of JIT memory failed, PCRE JIT will be disabled. This is likely caused by security restrictions. Either grant PHP permission to allocate executable memory, or set pcre.jit=0

というエラーが表示された場合は、以下の手順を試してください。

XAMPPをインストールしたディレクトリから、/xamppfiles/etc/php.iniを開く。
[Pcre]の文字列で検索して、その次の行に以下の記述を追加。
pcre.jit=0

データベースの作成

今回使用するデータベースを作成します
以下の記述をphpMyAdminのSQLタブのテキストボックスに追加して実行してください。

CREATE DATABASE koa2_test;
USE koa2_test;
CREATE TABLE koa2_test.user
(
    user_id   INT AUTO_INCREMENT PRIMARY KEY,
    user_name VARCHAR(20)  NOT NULL,
    password  VARCHAR(255) NOT NULL
);

画面左のリストからkoa2_testデータベースをクリックすると、作成したテーブルが確認できます。

Koaでデータベースに接続する処理を記載します。
接続するにあたって、こちらのパッケージを利用します。
https://github.com/sidorares/node-mysql2

以下のコマンドをコンソールで実行してください。
npm install mysql2

DB接続にはコネクションプールを作成し、これをすべてのデータベースへのクエリで利用します。
/app/db.js を作成し、以下の記述を追加してください。

db.js
const mysql = require('mysql2/promise');
const config = require('../config.json');

const connection = mysql.createPool(config.db);

module.exports = connection;

DB接続を行う外部ファイルでは、当ファイルをrequireで読み込むことでコネクションプールを利用します。

また、設定情報を保存するためのファイルを作成します。
/config.jsonを作成し、以下の記述を追加してください。

config.json
{
  "db": {
    "host": "localhost",
    "port": 3306,
    "user": "root",
    "password": "",
    "database": "koa2_test"
  }
}

設定ファイルを別に用意することで、設定情報を一元管理できたり、Gitにパスワード等の情報が保存されてしまう事を防ぐことができるので、このようにすると良いようです。

アカウント登録

/view/signup.ejsを作成し、以下の記述を追加してください。

signup.ejs
<h1>アカウント登録</h1>
<form action="signup" method="post">
   USER NAME <input type="text" name="name"><br>
   PASSWORD <input type="password" name="password"><br>
   <input type="submit" value="登録"><br>
</form>

/router/signup.jsを作成し、以下の記述を追加してください。

signup.js
const Router = require('koa-router');
const router = new Router();
const connection = require('../app/db');

router.get('/signup', async (ctx) => {
    await ctx.render('signup');
});

router.post('/signup', async (ctx) => {
    // POSTパラメータを取得
    let userName = ctx.request.body['name'];
    let password = ctx.request.body['password'];

    // DBにアカウント情報を登録
    // SQL文中の ? はプレースホルダーというもので、ここに後から値を割り当て(バインド)します。
    // ここでは、insert文のuser_nameとpasswordに当たる箇所を ? としており、
    // query()関数の第二引数として配列の形で、バインド値を渡しています。
    let signupSQL = 'INSERT INTO user (user_name, password) VALUES (?, ?)';
    await connection.query(signupSQL, [userName, password]);

    await ctx.render('signup');
});

module.exports = router;

/index.jsに以下の記述を追加してください。

index.js
const signupRouter = require('./router/signup');
app.use(signupRouter.routes());
app.use(signupRouter.allowedMethods());

動作を確認

ブラウザで http://localhost:5000/signup にアクセスすると、アカウント登録ページが表示されます。
http://localhost/phpmyadmin/ で情報がDBに登録されていることが確認できます。

パスワードのハッシュ化

現在の状態ではパスワードが平文で登録されてしまっているので、ハッシュ化して登録するように変更します。
パスワードのハッシュ化にはこちらのパッケージを利用します。
https://github.com/kelektiv/node.bcrypt.js

以下のコマンドをコンソールで実行してください。
npm install bcrypt

/router/signup.jsを以下のように修正してください。

signup.js
const Router = require('koa-router');
const router = new Router();
const connection = require('../app/db');
const bcrypt = require('bcrypt');

router.get('/signup', async (ctx) => {
    await ctx.render('signup');
});

router.post('/signup', async (ctx) => {
    // POSTパラメータを取得
    let userName = ctx.request.body['name'];
    let password = ctx.request.body['password'];

    //パスワードをハッシュ化
    const salt = bcrypt.genSaltSync();
    const hashPassword = bcrypt.hashSync(password, salt);

    // DBにアカウント情報を登録
    let signupSQL = 'INSERT INTO user VALUES (0, ?, ?)';
    await connection.query(signupSQL, [userName, hashPassword]);

    await ctx.render('signup');
});

module.exports = router;

この状態で再びアカウント登録を実行すると、以下のような文字列がパスワードとして保存されます。
「$2b$10$pO2kkkS0FWpKMgIoCg5QbuQilL7E3nbWF6im47pvSx8…」

以上で新規登録は完了です。

ログイン

/view/login.ejsを作成し、以下の記述を追加してください。

login.ejs
<h1>ログイン</h1>
<form action="login" method="post">
    USER NAME <input type="text" name="name" placeholder="userと入力"><br>
    PASSWORD <input type="password" name="password" placeholder="userと入力"><br>
    <input type="submit" value="ログイン"><br>
</form>

<a href="signup">アカウント登録</a>

<!-- この部分でログイン結果を表示するようにjs側で処理を書いていきます。 -->
<% if(typeof loginResult !== "undefined"){ %>
    <br>
    <%= loginResult %>
<% } %>

/router/login.jsを作成し、以下の記述を追加してください。

login.js
const Router = require('koa-router');
const router = new Router();
const connection = require('../app/db');
const bcrypt = require('bcrypt')

router.get('/login', async (ctx) => {
    await ctx.render('login');
});

router.post('/login', async (ctx) => {
    // POSTパラメータを取得
    let userName = ctx.request.body['name'];
    let password = ctx.request.body['password'];

    // DBからuserNameが一致するデータを検索
    let loginSQL = 'SELECT user_id, password FROM user WHERE user_name = ?';
    let [queryResult] = await connection.query(loginSQL, [userName]);

    // 入力されたパスワードとDBに保存されているハッシュ化されたパスワードを比較
    let loginResult = 'ログイン失敗';
    for (let row of queryResult) {
        if (bcrypt.compareSync(password, row['password'])) {
            loginResult = 'ログイン成功';
        }
    }

    await ctx.render('login', {loginResult: loginResult});
});

module.exports = router;

作成したrouterを読み込む処理をindex.jsに追加します。
/index.jsに以下のコードを追加してください。

index.js
const loginRouter = require('./router/login');
app.use(loginRouter.routes());
app.use(loginRouter.allowedMethods());

動作を確認

ブラウザでhttp://localhost:5000/login にアクセスすると、ログイン画面が表示されます。
!# 画像を挿入

まとめ

以上で新規登録とログインの検証が完了です。
次回は入力値のバリデーションを書いていく予定です。

1
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?