Laravel(Laradock)を使ってAuth機能を実装してみた
はじめに
ハマったところなどを忘れないように備忘録として書いています。
おかしなところがアレばご指摘頂けると幸いです。
前提
- Dockerが使えること
- Gitが使えること
環境
環境構築
1.Laradockをクローンするためのディレクトリの作成
$ mkdir MyApp && cd MyApp
2.LaradockをGitからクローン
$ git clone https://github.com/LaraDock/laradock.git
クローンが終わるとMyApp直下にlaradockディレクトリができています。
laradockのディレクトリに移動して、ls -alするとlaradockに内包されているものが一覧で確認できます。
3.laradock配下にあるenv-exampleを.envにして任意で編集
cp env-example .env
今回、GUIツールのSequel Proでデータベースに繋ぎたかったのでMySQLは5.6を使用しています。
データベース名やユーザ名など、任意で設定してください。
### MYSQL ################################################# MYSQL_VERSION=5.6 MYSQL_DATABASE=default MYSQL_USER=root MYSQL_PASSWORD=secret MYSQL_PORT=3306 MYSQL_ROOT_PASSWORD=root MYSQL_ENTRYPOINT_INITDB=./mysql/docker-entrypoint-initdb.d
docker-composeコマンドでコンテナをビルド、起動します。
$ docker-compose up -d nginx mysql php-fpm
初回起動時は結構時間がかかると思います。
起動が終わるとdocker-compose psでコンテナのプロセスを確認します。
Name Command State Ports -------------------------------------------------------------------------------------------------------------- laradock_docker-in-docker_1 dockerd-entrypoint.sh Up 2375/tcp, 2376/tcp laradock_mysql_1 docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp laradock_nginx_1 /bin/bash /opt/startup.sh Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp laradock_php-fpm_1 docker-php-entrypoint php-fpm Up 9000/tcp laradock_workspace_1 /sbin/my_init Up 0.0.0.0:2222->22/tcp
コンテナが立ち上がっていればOKです。
4.プロジェクトの作成
以下のコマンドでコンテナにアクセスします。
$ docker-compose exec workspace bash
コンテナに入れたらまずはパッケージリストを更新します。
$ apt-get update
更新したら以下のコマンドでプロジェクトを作成します。
$ composer create-project --prefer-dist laravel/laravel MyProject
作成が完了したらlaradockと同階層にMyProjectが出来ています。
MyProject配下にあるstorageとcacheのディレクトリのパーミッションを変更します。
$ chmod 777 storage $ chmod 777 bootstrap/cache
5.プロジェクトの設定
手順通りに進めていれば、現在workspaceのコンテナに入っている状態なのでexitでコンテナから出ます。
コンテナから出た後、立ち上げたコンテナを以下のコマンドで停止します。
$ docker-compose stop
コンテナを停止したらコードのパスを設定するためlaradock配下にある.envを編集します。
### Paths ################################################# # Point to the path of your applications code on your host APP_CODE_PATH_HOST=../MyProject/
上記の様にしておくことでworkspaceのコンテナに入った時のルートディレクトリの位置が変わってるはずです。
MyProject側の.envも以下のように編集します。
私の場合、DB_HOSTをmysqlにしないとconnection refusedのエラーが出て繋がらなかったです。
DB_CONNECTION=mysql DB_HOST=mysql DB_PORT=3306 DB_DATABASE=default DB_USERNAME=root DB_PASSWORD=root
ここまで設定した後、再度コンテナを起動させブラウザでhttp://localhostへアクセスします。
$ docker-compose up -d nginx mysql php-fpm
もし、404の画面になった場合Nginxのドキュメントルートを変更します。
設定ファイルの場所はlaradock配下にあるnginx/sites/default.conf
変更箇所はline:13あたり
root /var/www/public;
6.パッケージリストのインストール
再び、workspaceのコンテナに入ります。
$ docker-compose exec workspace bash
コンテナに入ったらcomposerとnpmをインストールするだけです。
$ composer install $ npm install
7.ログイン機能の実装
今回、ログイン機能はLaravel標準のものを使用します。
以下のコマンドを実行します。
$ artisan migrate
すると以下のようなエラーが出るかと思います。(※実行後の全文)
Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `users` add unique `users_email_unique`(`email`)) at /var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:669 665| // If an exception occurs when attempting to run a query, we'll format the error 666| // message to include the bindings with SQL, which will make this exception a 667| // lot more helpful to the developer instead of just the database's errors. 668| catch (Exception $e) { > 669| throw new QueryException( 670| $query, $this->prepareBindings($bindings), $e 671| ); 672| } 673| Exception trace: 1 PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes") /var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:463 2 PDOStatement::execute() /var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:463 Please use the argument -v to see more details.
MySQLのリファレンスを見てみると以下のように書かれています。
デフォルトでは、単一カラムインデックスのインデックスキーを最大で 767 バイトにすることができます。
つまり、768バイト以上のカラムに対するインデックスキーは設定できません。
Laravel 5.3まではUTF-8だった為、1文字が3Byteなのでvarchar(255)は、255文字×3Byte=765Byteということでインデックスを設定することができていましたが、
Laravel 5.4以降はUTF-8mb4となり1文字が4Byteとしてあつかわれるため、制限の767Byteを超えてしまいエラーとなります。
ちなみに、MySQL5.6を使っていることも影響しているので5.7で設定していればこのエラーは出ないかと思います。
今回私は絵文字を使用することを諦め、UTF-8として使用することにしました。 修正箇所はconfig/database.phpです。
'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci',
以下のように修正。
'charset' => 'utf8', 'collation' => 'utf8_unicode_ci',
中途半端にマイグレーションが実行されている為、MySQLのコンテナに入りMySQLにログイン。一度作られたテーブルを削除してから再度workspaceのコンテナでマイグレーションを実行します。
すると無事に以下4つのテーブルが出来ているはずです。
- failed_jpbs
- migrations
- password_resets
- users
続いて、以下のコマンドを実行しauth機能を作成します。
$ artisan make:auth
すると次は以下のようなエラーが発生します。
Command "make:auth" is not defined.
Laravel 5系までは使えていたコマンドですが6系になるとなくなってるんですね。 そこで以下のコマンドを実行します。
$ composer require laravel/ui --dev $ artisan ui vue --auth
これで画面右上に登録・ログインボタンが出来上がったと思います。
実際にLOGIN或いはREGISTERをクリックしてみるとちゃんとページは遷移できます。 しかし、Laravel 6系ではCSS / JSが同梱されなくなっているためJSやCSSがあたっていない状態になっているかと思います。
そこでプロジェクト内で使用したい構成にあわせて以下から選択して実行します。 なお、vue/react/bootstrap以外にも任意のプリセットを用意したい場合、 \Laravel\Ui\UiCommand にマクロを実装することで追加が可能とのことです。
# VueやReactを利用しない、Bootstrap(+jQuery)のみのプリセット $ artisan ui bootstrap --auth # Bootstrapに加えてVue.jsを利用する $ artisan ui vue --auth # Vue.jsではなくReactを利用する $ artisan ui react --auth
生成したプリセットはコンパイルする必要があるため環境に合わせてビルドします。
# with npm $ npm i # 開発用ビルド $ npm run dev # 本番用ビルド $ npm run prod # with yarn $ yarn install # 開発用ビルド $ yarn dev # 本番用ビルド $ yarn prod
画面を確認するとJS、CSSもあたりきれいに表示されていると思います。
登録、ログインが実際に動いていることを確認できれば完成です。