ローカル環境でcoesite3レポジトリを利用する

# はじめに
[こちらの記事](https://qiita.com/k96mz/items/9a191ee7881f7bf9f07e)で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ユーザとしてログインという意味です。

## セッションストア用のデータベースとユーザーを作成

セッション用のデータベースを作成
```sql
CREATE DATABASE session_db;
```
新しいデータベース session_db を作成します。


MySQL ユーザーを作成
```sql
CREATE USER 'session_user'@'localhost' IDENTIFIED BY 'password123';
```
新しい MySQL ユーザー session_user を作成し、そのユーザーに password123 というパスワードを設定するものです。
@'localhost'  にすると、このユーザーはローカルマシンからのみ MySQL に接続できる ようになります。


セッション用データベースの権限を付与
```sql
GRANT ALL PRIVILEGES ON session_db.* TO 'session_user'@'localhost';
FLUSH PRIVILEGES;
```
MySQL の session_db データベースに対するすべての権限を session_user に付与 するものです。
MySQL は 権限情報をキャッシュ しているため、GRANT を実行しただけではすぐに反映されないことがあります。FLUSH PRIVILEGES; を実行すると、権限の変更をすぐに反映 できます。


データベースの設定が正しくできたか確認
```sql
SHOW DATABASES;
```
session_db  がデータベースに含まれています。


ユーザの設定が正しくできたか確認
```sql
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 をセットアップしてみます。

```javascript: apptest.js
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/
にアクセスすると、以下の通り表示されます。

![スクリーンショット 2025-02-17 13.28.32.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/64eb2ce7-18d8-4af2-935c-9f87ffd52680.jpeg)

データベース session_db を選択
```sql
USE session_db;
```


MySQLにログイン
```sql
SELECT * FROM sessions;
```
とすると以下のような内容が表示されます。（形式は異なります）

```json
{
    "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ページ](https://github.com/k96mz/20250217localmysql)にあります。


# coesite3を実行する


## MySQLの設定

MySQLにログインして、セッション用のデータベースを作成
```sql
CREATE DATABASE coesite3_db;
```

MySQL ユーザーを作成
```sql
CREATE USER 'coesite3_user'@'localhost' IDENTIFIED BY 'coesite3pass';
```

セッション用データベースの権限を付与
```sql
GRANT ALL PRIVILEGES ON coesite3_db.* TO 'coesite3_user'@'localhost';
FLUSH PRIVILEGES;
```


データベースの設定が正しくできたか確認
```sql
SHOW DATABASES;
```
coesite3_db  がデータベースに含まれています。


ユーザの設定が正しくできたか確認
```sql
SELECT user, host FROM mysql.user;
```


変更を確実に反映するために MySQL を再起動します。
```sql
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/
にアクセスします。

しかし、以下のエラーが発生しました。

![スクリーンショット 2025-02-17 15.01.46.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/31c1d447-5374-4fb0-bdbd-997c562f933b.jpeg)

MySQL 8.0 以降 でデフォルトの認証方式が caching_sha2_password に変更されたため、古い MySQL クライアント (mysql npm パッケージ) が caching_sha2_password に対応していない場合に発生するらしいです。


MySQL にログイン後、現在の認証方式を確認します。
```sql
SELECT user, host, plugin FROM mysql.user;
```

![スクリーンショット 2025-02-17 15.06.44.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/9cf94baf-dff9-4116-bc34-0b0394bab9df.jpeg)

plugin の列が caching_sha2_password になっていたので、変更が必要です。

ユーザーの認証方式を変更
```sql
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
https://qiita.com/k96mz/items/9a191ee7881f7bf9f07e

https://qiita.com/monga3/items/6583c07a9b275b469608