記事一覧
概要
今回は、アカウント登録、ログイン検証の実装を行います。
当記事ではログインは検証に留め、ログイン状態の保持は後の記事で進めていく予定です。
また、前回の続きとして進めて行くので、上手くいかない場合は以前の記事をご覧ください。
アカウントの登録やログインに必要なデータベースは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
を作成し、以下の記述を追加してください。
const mysql = require('mysql2/promise');
const config = require('../config.json');
const connection = mysql.createPool(config.db);
module.exports = connection;
DB接続を行う外部ファイルでは、当ファイルをrequireで読み込むことでコネクションプールを利用します。
また、設定情報を保存するためのファイルを作成します。
/config.json
を作成し、以下の記述を追加してください。
{
"db": {
"host": "localhost",
"port": 3306,
"user": "root",
"password": "",
"database": "koa2_test"
}
}
設定ファイルを別に用意することで、設定情報を一元管理できたり、Gitにパスワード等の情報が保存されてしまう事を防ぐことができるので、このようにすると良いようです。
アカウント登録
/view/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
を作成し、以下の記述を追加してください。
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
に以下の記述を追加してください。
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
を以下のように修正してください。
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
を作成し、以下の記述を追加してください。
<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
を作成し、以下の記述を追加してください。
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
に以下のコードを追加してください。
const loginRouter = require('./router/login');
app.use(loginRouter.routes());
app.use(loginRouter.allowedMethods());
動作を確認
ブラウザでhttp://localhost:5000/login にアクセスすると、ログイン画面が表示されます。
!# 画像を挿入
まとめ
以上で新規登録とログインの検証が完了です。
次回は入力値のバリデーションを書いていく予定です。