はじめに
こちらの記事でcoesite3レポジトリについて記載しました。本記事ではローカル環境でcoesite3レポジトリを利用してみたいと思います。特にmysqlがセッション情報の保存に使用されているところを理解したいと思います。
環境
mac OS Sequoia バージョン15.3
チップ:Apple M3
MySQL 8.0.41
MySQL
MySQLに関して記載していきます。
MySQLのインストール
Homebrew を使って MySQL をインストールします。
Homebrew を最新に更新
brew update
MySQL をインストールします。 ちなみに、開発環境のサーバでは、Ver 8.0.27を使用していました。
Homebrew では、MySQL の LTS 版(安定版)として MySQL 8.0 をインストールできます。
brew install mysql@8.0
mysql --version
mysql Ver 8.0.41 for macos15.2 on arm64 (Homebrew)
と表示され、無事にインストールされました。
MySQLを起動する
brew services start mysql@8.0
とすると、
Successfully started mysql
(label: homebrew.mxcl.mysql)
と表示され、MySQLが起動されました。
brew services list
で、MySQL の起動状態を確認出来ます。
MySQLにログイン
mysql -u root
でログイン出来ます。-uは--userの短縮形でrootユーザとしてログインという意味です。
セッションストア用のデータベースとユーザーを作成
セッション用のデータベースを作成
CREATE DATABASE session_db;
新しいデータベース session_db を作成します。
MySQL ユーザーを作成
CREATE USER 'session_user'@'localhost' IDENTIFIED BY 'password123';
新しい MySQL ユーザー session_user を作成し、そのユーザーに password123 というパスワードを設定するものです。
@'localhost' にすると、このユーザーはローカルマシンからのみ MySQL に接続できる ようになります。
セッション用データベースの権限を付与
GRANT ALL PRIVILEGES ON session_db.* TO 'session_user'@'localhost';
FLUSH PRIVILEGES;
MySQL の session_db データベースに対するすべての権限を session_user に付与 するものです。
MySQL は 権限情報をキャッシュ しているため、GRANT を実行しただけではすぐに反映されないことがあります。FLUSH PRIVILEGES; を実行すると、権限の変更をすぐに反映 できます。
データベースの設定が正しくできたか確認
SHOW DATABASES;
session_db がデータベースに含まれています。
ユーザの設定が正しくできたか確認
SELECT user, host FROM mysql.user;
MySQL サーバーに登録されているユーザーと、それぞれのホスト情報を表示します。
userに「session_user」があり、hostに「localhost」があるので、「session_user」はlocalhostのみから接続を許可されていることが分かります。
変更を確実に反映するために MySQL を再起動します。
brew services restart mysql
Express に MySQL ストアを設定
作成した session_user を使って express-mysql-session をセットアップしてみます。
const express = require('express');
const session = require('express-session');
const MySQLStore = require('express-mysql-session')(session);
const app = express();
// MySQL の接続情報
const mysqlOptions = {
host: 'localhost',
port: 3306,
user: 'session_user',
password: 'password123', // 作成したパスワード
database: 'session_db'
};
// MySQL ストアを作成
const sessionStore = new MySQLStore(mysqlOptions);
const sess = {
secret: 'mysecretkey',
cookie: { maxAge: 60000000 }, // 16時間40分
store: sessionStore, // MySQL をセッションストアとして使用
resave: false,
saveUninitialized: false
};
app.use(session(sess));
app.get('/', (req, res) => {
if (!req.session.views) {
req.session.views = 1;
} else {
req.session.views++;
}
res.send(`あなたの訪問回数: ${req.session.views}`);
});
// サーバーを起動
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
node apptest.jsを実行すると、express-mysql-session は、自動的に sessions テーブルを作成 します。この sessions テーブルがセッションデータを保存する場所になります。
http://localhost:3000/
にアクセスすると、以下の通り表示されます。
データベース session_db を選択
USE session_db;
MySQLにログイン
SELECT * FROM sessions;
とすると以下のような内容が表示されます。(形式は異なります)
{
"session_id": "-rXZVl4s-fsbG4LJeJDpsUCne0me3ZBH",
"expires": 1739876772,
"cookie": {
"originalMaxAge": 60000000,
"expires": "2025-02-18T11:06:11.582Z",
"httpOnly": true,
"path": "/"
},
"views": 1
}
- セッションの有効期限 (expires) は 2025-02-18T11:06:11.582Z(UTC 時間)
- クライアント側の Cookie も同じ有効期限 (cookie.expires)
- httpOnly: true のため、JavaScript では Cookie にアクセスできない
- path: "/" のため、このセッションはサイト全体で有効
ページをリロードするたびに、viewsの数字が一つ増え、expiresの値も更新されます。
こちらのコードはGitHubページにあります。
coesite3を実行する
MySQLの設定
MySQLにログインして、セッション用のデータベースを作成
CREATE DATABASE coesite3_db;
MySQL ユーザーを作成
CREATE USER 'coesite3_user'@'localhost' IDENTIFIED BY 'coesite3pass';
セッション用データベースの権限を付与
GRANT ALL PRIVILEGES ON coesite3_db.* TO 'coesite3_user'@'localhost';
FLUSH PRIVILEGES;
データベースの設定が正しくできたか確認
SHOW DATABASES;
coesite3_db がデータベースに含まれています。
ユーザの設定が正しくできたか確認
SELECT user, host FROM mysql.user;
変更を確実に反映するために MySQL を再起動します。
brew services restart mysql@8.0
HTTPSのための設定
自己証明書を作成
openssl req -newkey rsa:2048 -nodes -keyout localhost-key.pem -out localhost.csr
いくつか質問されますが、適当に答えます。
A challenge passwordはpasswordとしました。
An optional company name []は、optionとしました。
作成した CSR を使用して、自己署名証明書 (localhost-cert.pem) を発行します。
openssl x509 -req -days 365 -in localhost.csr -signkey localhost-key.pem -out localhost-cert.pem
• localhost-key.pem → サーバーの秘密鍵
• localhost-cert.pem → サーバーの証明書
.envの設定
sample.envを.envに名称変更して、さらに設定を変更します。
特に
OAUTH_REDIRECT_URI=https://localhost:3000/unvt/auth/callback
とします。unvtがあることに注意が必要です。
さらにEntra IDにも上記URLをRedirect URIsに加えておきます。
MySQLの設定は以下としています。
MYSQL_USER=coesite3_user
MYSQL_PASSWORD=coesite3pass
MYSQL_DATABASE=coesite3_db
default.hjsonの設定
以下の通りの設定とします。
privkeyPath: ./key/localhost-key.pem
fullchainPath: ./key/localhost-cert.pem
port: 3000
証明書の場所もパスに合わせて変更します。
デフォルトページを表示する
node app.js
として、
https://localhost:3000/unvt/
にアクセスします。
しかし、以下のエラーが発生しました。
MySQL 8.0 以降 でデフォルトの認証方式が caching_sha2_password に変更されたため、古い MySQL クライアント (mysql npm パッケージ) が caching_sha2_password に対応していない場合に発生するらしいです。
MySQL にログイン後、現在の認証方式を確認します。
SELECT user, host, plugin FROM mysql.user;
plugin の列が caching_sha2_password になっていたので、変更が必要です。
ユーザーの認証方式を変更
ALTER USER 'coesite3_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'coesite3pass';
FLUSH PRIVILEGES;
これで、エラーは出なくなりましたが、新たなエラーが発生しました。
OAUTH_CLIENT_SECRETの値を変えた方がいい気がするので、そうしてみます。
しかし、変更してもエラーは解決できません。
OAUTH_REDIRECT_URI=https://127.0.0.1:3000/unvt/auth/callback
として、さらにEntra IDにも登録しましたが、解決できません。
やはり、自己署名証明書はEntra IDでは使用できないのかもしれません。
まとめ
MySQLについては、そんなに難しいものではないことが分かりました。
しかしcoesite3については、自己署名証明書を使っているからなのか、Entra IDの認証がうまくいきませんでした。何か分かったら、また追記しようと思います。
Reference