21.
MySQLの利用
非同期処理
Promiseで非同期処理
mysql2でDB処理をするとき、mysql2/promise モジュールを利用して非同期処理をします。
const mysql = require('mysql2/promise');
SQLクエリの実行処理は非同期処理 async/await で実装します。
async () => {
await SQL処理
}
ユーザ登録
Userモデル
Userクラスを作成しし、db、mysql2/promise モジュールを読み込みます。
const db = require('../lib/db');
const mysql = require('mysql2/promise');
class User {
}
module.exports = User
- Userクラスはモジュール化します
ユーザ登録メソッド追加
ユーザ登録メソッド add() を追加し、非同期処理とします。
models/User.js
add = async (post) => {
}
MySQL接続
MySQLに接続し、SQL INSERTのテンプレートを用意します。
models/User.js
add = async (post) => {
const con = await mysql.createConnection(db.info);
var sql = `INSERT INTO users SET ?;`;
post.password = bcrypt.hashSync(post.password, 10);
}
レコード挿入
「users」テーブルにレコード挿入するクエリを実行します。
models/User.js
add = async (post) => {
const con = await mysql.createConnection(db.info);
var sql = `INSERT INTO users SET ?;`;
var result;
try {
post.password = bcrypt.hashSync(post.password, 10);
result = await con.query(sql, post);
} catch (error) {
} finally {
await con.end();
}
return result;
}
- SQL実行エラーを「try-catch」で対応が必要です。
ユーザ登録フォーム
「RegistController.js」を作成し、Userモデルを読み込みます。
controllers/RegistController.js
const User = require('../models/User');
ユーザ登録入力画面
ユーザ登録入力画面のコントローラー、ビューを作成します。
controllers/RegistController.js
const User = require('../models/User');
exports.index = (req, res) => {
var data = {}
data.title = 'Regist'
res.render('regist/index', data)
}
views/regist/index.ejs
<div class="col-6 m-auto">
<form action="/regist/add" method="post">
<div>
<label class="mt-3 mb-3">名前</label>
<input type="text" name="name" class="form-control">
</div>
<div>
<label class="mt-3 mb-3">Email</label>
<input type="text" name="email" class="form-control">
</div>
<div>
<label class="mt-3 mb-3">パスワード</label>
<input type="password" name="password" class="form-control">
</div>
<div class="text-center p-3">
<button class="btn btn-primary">登録</button>
</div>
<div class="text-center p-3">
<a href="/" class="btn btn-outline-primary">ホーム</a>
</div>
</form>
</div>
ユーザ登録処理
ユーザ登録メソッド追加
ユーザ登録メソッド add() を非同期処理で追加します。
controllers/RegistController.js
...
exports.index = (req, res) => {
var data = {}
data.title = 'Regist'
res.render('regist/index', data)
}
//ユーザ登録メソッド
exports.add = async (req, res) => {
}
ユーザ登録処理
Userモデルを利用して、ユーザ登録処理を実行します。
controllers/RegistController.js
...
exports.add = async (req, res) => {
//ユーザ登録処理
const user = new User();
await user.add(req.body);
if (user.id) {
req.session.authUser = user;
res.redirect('/login');
} else {
res.redirect('/regist');
}
}
リダイレクト
ユーザ登録ができたらログイン画面に、失敗したらユーザ登録画面にリダイレクトします。
controllers/RegistController.js
...
exports.add = async (req, res) => {
const user = new User();
var isSuccess = await user.add(req.body);
if (isSuccess) {
res.redirect('/login');
} else {
res.redirect('/regist');
}
}
ルーティング
ユーザ登録のルーティングを追加します。
routes.js
const RegistController = require('./controllers/RegistController')
router.get('/regist', RegistController.index)
router.post('/regist/add', RegistController.add)
ユーザ登録確認
ユーザ登録画面にアクセスし、ユーザ登録できるか確認してみましょう。

演習
問題1
MySQLを利用してユーザ認証するように、ログインページを修正してみましょう。
ヒント
Userモデルに以下のような auth() メソッドを追加して認証します。 パスワードのハッシュ検証は、bcrypt.compareSync() を利用します。
models/User.js
const db = require('../lib/db');
const mysql = require('mysql2/promise');
const bcrypt = require('bcrypt');
class User {
auth = async (email, password) => {
const sql = 'SELECT * FROM users WHERE ?;';
var post = { email: email };
const con = await mysql.createConnection(db.info)
var user;
try {
const [rows, fields] = await con.query(sql, post);
user = rows[0];
} catch (error) {
} finally {
await con.end();
}
if (user.id && bcrypt.compareSync(password, user.password)) {
return user;
}
return;
}
add = async (post) => {
var sql = `INSERT INTO users SET ?;`;
const con = await mysql.createConnection(db.info)
var result;
try {
post.password = bcrypt.hashSync(post.password, 10);
result = await con.query(sql, post);
} catch (error) {
} finally {
await con.end();
}
return result;
}
}
module.exports = User
問題2
「ApiController」を作成して、ユーザ情報のJSONを表示してみましょう。