Amazon Lightsail の CentOS に構築した MySQLサーバーに Laravel で接続する3/3 ~ Laravelからアクセス編 ~

はじめに

前回までに、Amazon Lightsail 上で構築した CentOSLinux)に MySQLサーバーのインストール、まっさらなMySQLサーバーの初期設定までを行った。

今回は、ローカルマシンで作成した Laraveアプリケーションからクラウド上のMySQLサーバーに直接アクセスして使えるようにするための作業を行っていく。

 

目次

 

前提

ローカル環境

クラウド環境(Amazon Lightsail)

 

LaravelからMySQLサーバーへの接続

Laravelプロジェクトの作成

ローカルマシンでLaravelのプロジェクトを作成する。 任意のフォルダで以下のコマンドを実行する。

composer create-project --prefer-dist laravel/laravel DbTest

 

作成済みのLaravelプロジェクトは以下のフォルダ構成となっている。

※今回の説明に必要なファイルだけ表示している。

DbTest
├ app/
│ └ Http
│  └ Controllers
│   └ DbController.php
├ bootstrap/
├ config/
├ database/
├ public/
├ resources/
│ └ views
│   └ welcome.blade.php
├ routes/
│ └ web.php
├ storage/
├ tests/
├ vendor/
└.env

 

デフォルトで記載されているMySQLのDB定義を以下の通り変更する。

.env(抜粋)

DB_CONNECTION=mysql
DB_HOST=3.114.2.13
DB_PORT=3306
DB_DATABASE="test_db"
DB_USERNAME=laravelapp
DB_PASSWORD="L@ravel123"

 

.envを変更したのでプロジェクトのルートフォルダで以下のコマンドを実行し、キャッシュをクリアする。

アプリケーション起動前なので必要ないかもしれないが、Laravelでは.envの変更が反映されない問題が時々発生するため、変更後は必ず実行する習慣にした方が良い。

$ php artisan config:cache;
Configuration cache cleared!
Configuration cached successfully!

 

ルーティングの設定は以下の通り。

routes\web.php(ソース中のコメント文は割愛)

<?php
Route::get('/', 'DbController@index');

 

プロジェクトのルートフォルダ(DbTest)で以下のコマンド実行し、コントローラークラスを作成する。

コマンドの実行によってapp\Http\Controllers\DbController.phpが作られる。

php artisan make:controller DbController

 

作成したコントローラーを以下の通り修正する。

コードの内容としてはweb.phpで定義したDBのtest_usersのレコードを全件取得するSQLを実行し、取得結果をddコマンドで画面にダンプしているだけである。

app\Http\Controllers\DbController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\DB;

class DbController extends Controller
{
    public function index() {
        $users = DB::select('select * from test_users;');
        dd($users);
    }
}

 

これでMySQLサーバーに接続するために必要なファイルが揃ったのでいよいよLaravelアプリケーションを起動する。

以下のコマンドでローカルサーバーが立ち上がる。起動したらWebブラウザhttp://127.0.0.1:8000にアクセスする。

$ php artisan serve
Laravel development server started: <http://127.0.0.1:8000>

 

MySQLサーバーへの接続エラー対応1(ISPからのアクセスを許可)

エラー発生。LaravelからMySQLへの接続が許可されていない旨のメッセージ。

自宅のISP(インターネットサービスを契約しているプロバイダ)はso-netなのだが、どうやらso-net経由でアクセスする際のホスト名 xxxxxxxxx.xxxxxxxx.xx.so-net.ne.jp が許可されていないようだ。

Illuminate \ Database \ QueryException (1130)
SQLSTATE[HY000] [1130] Host 'xxxxxxxxx.xxxxxxxx.xx.so-net.ne.jp' is not allowed to connect to this MySQL server (SQL: select * from test_users;)

 

ホスト名 xxxxxxxxx.xxxxxxxx.xx.so-net.ne.jp からのアクセスを許可するには新たにユーザーを作成する必要がある。

まずはMySQLサーバーに rootユーザーでログインする。

$ mysql -u root -p
Enter password:

 

ユーザー名が「laravelapp」でホスト名「 xxxxxxxxx.xxxxxxxx.xx.so-net.ne.jp 」のユーザーを作成する。

mysql> create user 'laravelapp'@'xxxxxxxxx.xxxxxxxx.xx.so-net.ne.jp' identified by 'L@ravel123';
Query OK, 0 rows affected (0.03 sec)

  ユーザーが作成されたことを確認する。

mysql> select host, user from mysql.user;
+------------------------------------+------------------+
| host                               | user             |
+------------------------------------+------------------+
| localhost                          | laravelapp       |
| localhost                          | mysql.infoschema |
| localhost                          | mysql.session    |
| localhost                          | mysql.sys        |
| localhost                          | root             |
| xxxxxxxxx.xxxxxxxx.xx.so-net.ne.jp | laravelapp       |
+------------------------------------+------------------+
6 rows in set (0.00 sec)

 

作成したユーザーに権限を与える。

mysql> grant all privileges on test_db.* to 'laravelapp'@'xxxxxxxxx.xxxxxxxx.xx.so-net.ne.jp';
Query OK, 0 rows affected (0.00 sec)

 

権限が付与されたことを確認する。

mysql> show grants for 'laravelapp'@'xxxxxxxxx.xxxxxxxx.xx.so-net.ne.jp';
+------------------------------------------------------------------------------------------+
| Grants for laravelapp@xxxxxxxxx.xxxxxxxx.xx.so-net.ne.jp                                 |
+------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `laravelapp`@`xxxxxxxxx.xxxxxxxx.xx.so-net.ne.jp`                  |
| GRANT ALL PRIVILEGES ON `test_db`.* TO `laravelapp`@`xxxxxxxxx.xxxxxxxx.xx.so-net.ne.jp` |
+------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

 

MySQLサーバーへの接続エラー対応2(認証方式の変更)

再度、ローカルマシンのWebブラウザhttp://127.0.0.1:8000にアクセスする。

残念ながら、また別のMySQLエラーが発生。

未知の認証方式で接続しようとしている旨のエラーメッセージが表示された。

"SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client (SQL: select * from test_users;)"

さらにスタックトレースをたどると、以下のメッセージも出力されていた。

"PDO::__construct(): The server requested authentication method unknown to the client [caching_sha2_password]"

 

これは、MySQL8.0.4 からデフォルトの認証方式が変更されたことによる影響だと分かった。

MySQL8.0.4以降 のログイン認証方式はcaching_sha2_passwordがデフォルトになったが、PHPMySQL接続ライブラリが未対応のため接続不可となってしまっているようだ。

 

MySQLサーバーでの操作に戻って、 rootユーザーで以下のコマンドを実行し、現在の認証方式を確認する。

確かにhostがxxxxxxxxx.xxxxxxxx.xx.so-net.ne.jpのユーザーのpluginがcaching_sha2_passwordとなっている。

mysql> SELECT user, host, plugin FROM mysql.user;
+------------------+------------------------------------+-----------------------+
| user             | host                               | plugin                |
+------------------+------------------------------------+-----------------------+
| laravelapp       | localhost                          | caching_sha2_password |
| mysql.infoschema | localhost                          | caching_sha2_password |
| mysql.session    | localhost                          | caching_sha2_password |
| mysql.sys        | localhost                          | caching_sha2_password |
| root             | localhost                          | caching_sha2_password |
| laravelapp       | xxxxxxxxx.xxxxxxxx.xx.so-net.ne.jp | caching_sha2_password |
+------------------+------------------------------------+-----------------------+
6 rows in set (0.00 sec)

 

解決策としては、認証方式をmysql_native_passwordに戻すことで接続できるようなる。

mysql> ALTER USER 'laravelapp'@'xxxxxxxxx.xxxxxxxx.xx.so-net.ne.jp' IDENTIFIED WITH mysql_native_password BY 'L@ravel123';
Query OK, 0 rows affected (0.01 sec)

 

認証方式が変更されたことを確認

mysql> SELECT user, host, plugin FROM mysql.user;
+------------------+------------------------------------+-----------------------+
| user             | host                               | plugin                |
+------------------+------------------------------------+-----------------------+
| laravelapp       | localhost                          | caching_sha2_password |
| mysql.infoschema | localhost                          | caching_sha2_password |
| mysql.session    | localhost                          | caching_sha2_password |
| mysql.sys        | localhost                          | caching_sha2_password |
| root             | localhost                          | caching_sha2_password |
| laravelapp       | xxxxxxxxx.xxxxxxxx.xx.so-net.ne.jp | mysql_native_password |
+------------------+------------------------------------+-----------------------+
6 rows in set (0.00 sec)

 

もう一度、ローカルマシンのWebブラウザhttp://127.0.0.1:8000にアクセスする。

ようやくデータが取得できた。

array:1 [▼
  0 => {#202 ▼
    +"user_name": "test-user"
    +"mail_address": "test@sample.com"
    +"password": "123456"
    +"created": "2019-07-07 20:50:49"
    +"modified": "2019-07-07 20:50:49"
  }
]

f:id:pachiquli:20190711015305p:plain
LaravelからMySQLのデータが取得できた

 

おわりに

ようやく完成した環境。なかなか苦労した。

環境構築ひとつとってみても、ネットワークやOS、データベースなど様々な知識や経験が必要とされることを痛感した。

今回の一連の作業でちょっぴりオトナになれた気がする。

これに懲りず、今後もいろいろと挑戦し精進していきたい。

 

参考にさせて頂いた記事