PDOを使ってMySQLデータベースに接続しようとした際にハマったので少し調べてみました。
ハマった時の状況
出たエラー
【接続失敗】SQLSTATE[HY000] [1044] Access denied for user 'takeshi'@'%' to database 'testdb'
PHP
「takeshi」というユーザーでMySQLの「testdb」というデータベースに接続しようとしています。
<?php
$host = "db";
$dbname = "testdb";
$user = 'takeshi';
$password = 'brock';
$dsn = 'mysql:host='.$host.';dbname='.$dbname.';charset=utf8';
try {
$dbh = new PDO($dsn, $user, $password);
echo "【接続成功】";
} catch (PDOException $e) {
echo "【接続失敗】" . $e->getMessage();
exit();
}
MySQL
takeshiの権限
「leader」というロールを与えています。
mysql> show grants for takeshi;
+-------------------------------------+
| Grants for takeshi@% |
+-------------------------------------+
| GRANT USAGE ON *.* TO `takeshi`@`%` |
| GRANT `leader`@`%` TO `takeshi`@`%` |
+-------------------------------------+
leaderロールの権限
testdb内のすべてのテーブルに対してSELECT, INSERTが可能な権限を与えています。
mysql> show grants for leader;
+----------------------------------------------------+
| Grants for leader@% |
+----------------------------------------------------+
| GRANT USAGE ON *.* TO `leader`@`%` |
| GRANT SELECT, INSERT ON `testdb`.* TO `leader`@`%` |
+----------------------------------------------------+
解決方法
SET DEFAULT ROLEする
ロールは付与しただけでは意味がないようで明示的に有効化する必要がありました。
mysql> set default role leader to takeshi;
ロールを使わない
ロールを使わずにleaderと同等の権限をtakeshiに与えるだけです。
mysql> grant select, insert on testdb.* to takeshi;
おわりに
今回はSELECTとINSERTの権限を与えていますが、データベースレベルの権限(参考URL)なら何でも良さそうな雰囲気なので用途に合わせて変えてください。
いくら練習といえどALL権限与えるのは乱暴すぎると思うのでやめたほうがいいと思います。