個人開発のログイン画面がくそダサすぎだったのでいい感じに作ってみた。フロントの技術力が前進したのは間違いない。😪 pic.twitter.com/1njDrE12A0
— adachin👾SRE (@adachin0817) October 31, 2021
さて、着々と個人開発が進んでいるわけですが、アプリケーションに関しては駆け出しエンジニアなので、色々と学ぶことが多いですが、今回初めてCakePHP4でログインセッションをRedis化してみました。そもそもセッションとは何なのかという概要から説明していきましょう。
ログインセッションとは
- 流れ
ログインセッションよりもまずはクッキーとセッションについて勉強しておく必要がありまずが、以下二点を利用して認証を行います。
・クッキー
・ユーザー側のコンピュータに保存されているデータ
・セッション
・サーバー側に保存されているデータ
上記がログインセッションとしての流れとなりますが、ログアウトする場合はPCからのクッキーセッションidが消えて、サーバー側からもセッション情報がなくなります。なので、ログインセッションを実装しておくことで他のユーザーから勝手にアクセスされることはありません。そこでサーバー側の保存先としてデータベースや非リレーショナルデータベース(NoSQL)を利用することが多いです。ちなみにセッションファイルをサーバー上に格納してしまうとサーバーのディスクが増加してしまうのでデータベースで管理するのが良いでしょう。
また、非リレーショナルデータベースで有名なのはMemcachedやRedisとなります。Redisは単純なKey-Valueだけでなく複雑な種類のデータも扱えて、可用性を保ちつつ高速にデータを扱うことが可能です。現在はデータベースよりRedisで運用することが一般的になってきたと感じています。次はPHPがRedisへ接続するための設定等を説明していきます。
Docker/開発環境
- docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
version: '2' services: hoge-app: container_name: hoge-app build: ./app/ image: hoge-app ports: - '80:80' volumes: - ~/git/github/hoge:/var/www/hoge:delegated tty: true depends_on: - hoge-mysql - hoge-redis hoge-mysql: container_name: hoge-mysql build: ./mysql/ image: hoge-db ports: - '3306:3306' environment: MYSQL_DATABASE: hoge MYSQL_ROOT_PASSWORD: hoge TZ: "Asia/Tokyo" volumes: - ./mysql/db_data:/var/lib/mysql hoge-redis: container_name: hoge-redis image: "redis:latest" ports: - '6379:6379' volumes: - ./redis/db_data:/data |
- Dockerfile (App container)
1 2 3 4 5 6 7 8 9 10 11 12 |
FROM php:7.4-fpm-alpine ~省略~ # install packages RUN apk update && \ apk upgrade && \ apk add --update --no-cache \ redis \ #追加 hoge # Install php-redis RUN pecl install xdebug redis |
- php.ini
1 |
extension=redis.so |
開発環境はDockerでAppコンテナはAlpineを利用していますが、peclでredisパッケージをインストールとphp.iniにextensionを追加してredisコンテナを指定するだけで準備OKとなります。以下AppコンテナからRedisコンテナに接続できれば完璧です。
※ちなみにAmazon Linux2だとphp-pecl-redisになります。CakePHP4 Dockerでの開発環境については以下GitHubで公開しているので参考に。
https://github.com/RVIRUS0817/dev_cakephp4/tree/master/docker/dev
- 動作確認
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
bash-5.1# php -i | grep -e redis -e Redis redis Redis Support => enabled Redis Version => 5.3.4 Redis Sentinel Version => 0.1 redis.arrays.algorithm => no value => no value redis.arrays.auth => no value => no value redis.arrays.autorehash => 0 => 0 redis.arrays.connecttimeout => 0 => 0 redis.arrays.consistent => 0 => 0 redis.arrays.distributor => no value => no value redis.arrays.functions => no value => no value redis.arrays.hosts => no value => no value redis.arrays.index => 0 => 0 redis.arrays.lazyconnect => 0 => 0 redis.arrays.names => no value => no value redis.arrays.pconnect => 0 => 0 redis.arrays.previous => no value => no value redis.arrays.readtimeout => 0 => 0 redis.arrays.retryinterval => 0 => 0 redis.clusters.auth => no value => no value redis.clusters.cache_slots => 0 => 0 redis.clusters.persistent => 0 => 0 redis.clusters.read_timeout => 0 => 0 redis.clusters.seeds => no value => no value redis.clusters.timeout => 0 => 0 redis.pconnect.connection_limit => 0 => 0 redis.pconnect.echo_check_liveness => 1 => 1 redis.pconnect.pool_pattern => no value => no value redis.pconnect.pooling_enabled => 1 => 1 redis.session.lock_expire => 0 => 0 redis.session.lock_retries => 10 => 10 redis.session.lock_wait_time => 2000 => 2000 redis.session.locking_enabled => 0 => 0 Registered save handlers => files user redis rediscluster This program is free software; you can redistribute it and/or modify bash-5.0# redis-cli -h hoge-redis hoge-redis:6379> exit |
CakePHP4 x Redis
https://book.cakephp.org/4/ja/development/sessions.html#id7
- app_local.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
<?php return [ 'debug' => filter_var(env('DEBUG', true), FILTER_VALIDATE_BOOLEAN), 'Security' => [ 'salt' => env('SECURITY_SALT', 'SECURITY_SALT'), ], 'Datasources' => [ 'default' => [ 'host' => env('DB_HOST'), //'port' => 'non_standard_port_number', 'username' => env('DB_USER'), 'password' => env('DB_PASSWORD'), 'database' => env('DB_NAME'), 'url' => env('DATABASE_URL', null), ], 'test' => [ 'host' => 'localhost', //'port' => 'non_standard_port_number', 'username' => 'my_app', 'password' => 'secret', 'database' => 'test_myapp', //'schema' => 'myapp', 'url' => env('DATABASE_TEST_URL', null), ], ], 'EmailTransport' => [ 'default' => [ 'host' => 'localhost', 'port' => 25, 'username' => null, 'password' => null, 'client' => null, 'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null), ], ], 'Cache' => [ 'session' => [ 'className' => 'Redis', 'prefix' => 'hoge_redis_', 'path' => CACHE, 'port' => 6379, 'host' => env('REDIS_HOST'), 'duration' => '+180 days', 'fallback' => 'default', ], ], 'Session' => [ 'defaults' => 'cache', 'handler' => [ 'config' => 'session', ], ], ]; |
36行目から52行目にかけてCacheとSessionを追加しましょう。hostは.envで環境変数にしているので適当に。最後にSessionでconfigのsessionを読み込むように設定するだけです。なんて簡単なのか…!あとはログインしてみよう!
- ログイン後確認
1 2 3 |
bash-5.1# redis-cli -h hoge-redis hoge-redis:6379> keys * 1) "hoge_redis_eee13ba0e6d18d883c18baaacb91c7e5" |
まとめ
個人開発のログインセッションをRedisにしたのだが、まったく動かずお手上げ状態で、よくコードを見てみると.envで指定していた環境変数が間違っていた…バカモノめ!!!
— adachin👾SRE (@adachin0817) November 6, 2021
最近凡ミスが多いのでしっかりしないとな…これでちゃんとセッションが保たれる…!! RailsはデフォルトでDBにセッションを管理するように作られてるけど(わからん曖昧)、インフラ構築してる人はやはりElasticache/Redisを使うことが多いですね。参考に!!
次はSendGridでメール送信実装せねば!!
0件のコメント