UserFrostingによるユーザ登録システム

以前紹介したFlexisipなどのユーザ登録型アプリをサービス提供する場合、ユーザ登録用画面・登録ユーザ専用画面といったウェブフロントエンドもセットで用意する必要があります。巷に出回っているPHPによるユーザ管理用サンプルコードをベースにすれば簡易的な登録システムは構築できますが、パスワード管理、管理ユーザによるメール認証方式など商業レベルまでの機能を実現するとなると大幅な工数が必要になります。

今回Flexisipアプリのサインインシステムとして、他のアプリにも同サインインシステムを導入できることや、ユーザのグループ化・権限付与、パスワードの暗号化・リセット、メールによるユーザ認証、デザインのカスタマイズなど、商業レベルでの使用にも十分対応できるサインインシステムに特化したフレームワークであるUserFrosingを採用することにしました。

UserFrosting

UserFrosting Github:GitHub - userfrosting/UserFrosting: 🍩 Modern PHP user login and management framework++.

UserFrostingによるサインインシステムの主な特徴は以下の通りです。

  • ユーザ登録・メールによる認証
  • 登録ユーザのグループ化・権限付与
  • パスワードリセット
  • ユーザ登録情報の編集
  • ユーザ登録用画面、ユーザ専用ダッシュボード、アプリ用メイン画面
  • 日本語ローカライズ
  • MVC(Model-View-Controller)デザインによるカスタマイズ・拡張性
  • MITライセンスによるフリーオープンソース

ドキュメントにインストールからカスタマイズの方法まで良く纏められています。インストールしたデフォルトの状態から Sprinkles というフォルダにルールに則ったカスタマイズコードファイル郡を配置することで、内容を上書き・反映させることができます。


管理ユーザ:ダッシュボード

インストール環境

Dockerコンテナを使用しない場合

Nginx,PHP-FPM, MariaDB, phpMyAdmin, Git, Composer, Node.js, npmの各レポジトリを直接インストールして下さい。

(Ubuntu,Debian:apt-get install コマンド)

Dockerコンテナ(Composerイメージ)を利用する場合

Nginx,PHP, MariaDB, phpMyAdmin公式Dockerイメージをインストール先PC環境に合わせてComposerファイル内で指定します。

Tags指定により好みのイメージを選択して下さい。

  1. Nginx: image: nginx:alpine
  2. MariaDB: image: mariadb
  3. PHP-FPM: image: php:7.2-fpm-alpine
  4. phpMyAdmin: image: phpmyadmin/phpmyadmin:fpm-alpine

Docker-Composeサンプルファイル(Nginx+PHP-FPM+phpMyAdmin)

Docker-Composeファイルが用意されていますが、これを参考にNGINX,PHP-FPMコンテナのイメージファイルを選定しました。

以下、Nginx-ProxyとLet’sEncryptによるSSL接続に対応させるための設定です。

Nginx-Proxy+Let’sEncryptによるコンテナ稼働についてはフォーラム記事を参照願います。

version: '3'

services:
  mariadb:
    container_name: mariadb
    image: mariadb
    restart: always
    volumes:
      - ./db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=root_passowrd
      - MYSQL_DATABASE=your_database
      - MYSQL_USER=your_user
      - MYSQL_PASSWORD=user_password
    networks:
      proxy-tier:
        ipv4_address: 172.18.0.4

  # nginx, additional install $ docker exec nginx apk add bash nano
  nginx:
    container_name: nginx
    image: nginx:alpine
    tty: true
    environment:
      - VIRTUAL_HOST=test-site.com
      - VIRTUAL_ROOT=/var/www/html
      - VIRTUAL_PORT=80
      # - VIRTUAL_PROTO=fastcgi
      - LETSENCRYPT_HOST=test-site.com
      - [email protected]
    volumes:
      # shared nginx default.conf between host and container
      - ./nginx_default.conf:/etc/nginx/conf.d/default.conf
      # shared the directory /var/www/html in php-fpm container
      - ./html:/var/www/html/register
      # shared the directory /var/www/html in phpmysql-fpm container
      - ./phpmyadmin_data:/var/www/html/phpmyadmin
    restart: always
    networks:
      proxy-tier:
        ipv4_address: 172.18.0.6

  # php-fpm, additional install $ docker exec php-fpm apk add bash nano
  # php extension mysqli should be installed, $ docker exec php-fpm docker-php-ext-install mysqli
  php-fpm:
    container_name: php-fpm
    image: php:7.2-fpm-alpine
    tty: true
    expose: 
      - "9000"
    volumes:
      - ./html:/var/www/html/register
    depends_on:
      - mariadb
    restart: always
    networks:
      proxy-tier:
        ipv4_address: 172.18.0.7

  # phpmyadmin-fpm, additional install $ docker exec phpmyadmin-fpm apk add bash nano 
  # php extension mysqli should be installed, $ docker exec phpmyadmin-fpm docker-php-ext-install mysqli
  phpmyadmin:
    container_name: phpmyadmin-fpm
    image: phpmyadmin/phpmyadmin:fpm-alpine
    tty: true
    expose: 
      - "9000"
    environment:
      - PMA_HOST=mariadb
      - PMA_PORT=3306
      - PMA_ABSOLUTE_URI=http://localhost/phpmyadmin
    volumes:
      - ./phpmyadmin_data:/var/www/html
      - /sessions
    depends_on:
      - mariadb
    restart: always
    networks:
      proxy-tier:
        ipv4_address: 172.18.0.8

networks:
  proxy-tier:
    external:
      name: nginx-proxy

volumes:
  shared:
    external: true   

上記docker-composeファイルにより各コンテナを起動します。

$ docker-compose up -d

上記項目3.PHP-FPMの追加レポジトリ: composer, node.js, npm, nano, bash(Alpine-Linux:apk add コマンド)をインストールします。

$ docker exec php-fpm apk add composer nodejs npm nano bash

php-fpmコンテナ内にbashコマンドで移動し、Userfrostingに必要な以下パッケージとphp機能拡張モジュールをインストールします。

$ docker exec -ti php-fpm bash

# apk add libpng-dev freetype-dev libjpeg-turbo-dev zip
# docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/
# docker-php-ext-install -j$(nproc) gd
# docker-php-ext-install -j$(nproc) pdo pdo_mysql
# docker-php-ext-install -j$(nproc) zip

php-fpmコンテナから出て再起動。

# exit
$ docker container restart php-fpm

UserFrostingのダウンロード・コピー

コンテナ外の環境でgit cloneコマンドによりUserFrostingソースコードをダウンロードします。

(PHP-FPMコンテナ内にgitをインストールしてダウンロードしても構いません)

$ git clone https://github.com/userfrosting/UserFrosting.git userfrosting

PHP-FPMコンテナ内の/var/www/htmlディレクトリにUserFrostingフォルダの中身をコピーします。

$ docker cp userfrosting/. php-fpm:/var/www/html

PHP-FPMコンテナ内の/var/www/htmlディレクトリ内でcomposerコマンドによりPHP関連ライブラリ・サードパーティPHPフレームワークなどをダウンロードします。

$ docker exec php-fpm composer install

またはPHP-FPMのコンテナ内にbashコマンドで入り、現ディレクトリを確認後composerコマンドを実行します。

$ docker exec -it php-fpm bash

# pwd
/var/www/html
# composer install

NGINXコンテナの設定

PHP-FPM, phpMyAdminコンテナに対応したNGINXの設定をします。Nginx-proxyとLet’sencryptコンテナを事前に稼働させている条件(SSL接続)での設定となります。

$ docker exec nginx apk add nano

$ docker exec nginx nano /etc/nginx/conf.d/default.conf

/etc/nginx/conf.d/default.conf

resolver 127.0.0.11 valid=15s;

server {
    listen 80;
    root /var/www/html;
    server_name "";
      
    location / {
      add_header X-Frame-Options SAMEORIGIN;
      add_header X-Content-Type-Options nosniff;

      root /var/www/html/public;
      index index.php;
      try_files $uri /index.php?$query_string;

      location = /index.php {
          fastcgi_split_path_info ^(.+\.php)(/.+)$;
          fastcgi_keep_conn on;
          fastcgi_param  HTTPS 'on';
          fastcgi_pass   php-fpm:9000;
          fastcgi_index  index.php;
          include        fastcgi_params;
          fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
      }
      location ~* \.(png|gif|jpg|jpeg|ico|css|js|woff|ttf|otf|woff2|eot)$ {
          include /etc/nginx/mime.types;
          expires max;
          try_files $uri /index.php?$query_string;
      }
      client_max_body_size 100M;
   }

  # subdirectory for phpmyadmin pages

  location ^~ /phpmyadmin {

    alias /var/www/html/phpmyadmin;
    try_files $uri $uri/ @phpmyadmin;

    location ~ \.php$ {
      fastcgi_split_path_info ^\/phpmyadmin\/(.+\.php)(.*)$;
      fastcgi_param  HTTPS 'on';
      fastcgi_pass phpmyadmin-fpm:9000;
      include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
    }
  }

  location @phpmyadmin {
     rewrite /phpmyadmin/(.*)$ /phpmyadmin/index.php?/$1 last;
  }

}

設定をリロードします。

$ docker exec nginx nginx -s reload

phpMyAdminによるデータベース作成

MariaDBのユーザとパスワードはcomposerファイルの中で設定済なので、以下アドレスでMariaDBデータベースにアクセスします。

https://test-site.com/phpmyadmin

アプリ専用のデータベースtest-database(名称は任意)を作成します。

Bakery CLIによるインストール

PHP-FPMコンテナ内にbashコマンドで入り、以下のコマンドを実行してUserFrostingをインストールします。上記で設定したMariaDBデータベース、ユーザ名、パスワードなどを入力します。

$ docker exec -it php-fpm bash

メールによるユーザ認証などにSMTPサーバへのアクセスが必要になるため、事前にSMTPサーバ用ユーザ名とパスワードをメモしておいて下さい。

# php bakery bake

 _   _              ______             _   _
| | | |             |  ___|           | | (_)
| | | |___  ___ _ __| |_ _ __ ___  ___| |_ _ _ __   __ _
| | | / __|/ _ \ '__|  _| '__/ _ \/ __| __| | '_ \ / _` |
| |_| \__ \  __/ |  | | | | | (_) \__ \ |_| | | | | (_| |
 \___/|___/\___|_|  \_| |_|  \___/|___/\__|_|_| |_|\__, |
                                                    __/ |
                                                   |___/

UserFrosting's Database Setup Wizard
====================================

 ! [NOTE] Database credentials will be saved in `/var/www/html/app/.env` 
  [0] MySQL / MariaDB
  [1] ProgreSQL
  [2] SQL Server
  [3] SQLite
 > 0

 Hostname [localhost]:
 > mariadb

 Port [3306]:
 > 

 Database name [userfrosting]:
 > test-database

 Username [userfrosting]:
 > your_user

 Password:
 > 


 [OK] Database connection successful


Saving data
-----------


 [OK] Database config successfully saved in `/var/www/html/app/.env`


UserFrosting's SMTP Setup Wizard
================================

 ! [NOTE] SMTP credentials will be saved in `/var/www/html/app/.env`

In order to send registration emails, UserFrosting requires an outgoing mail server. 
 Select setup method [SMTP Server]:
  [0] SMTP Server
  [1] Gmail
  [2] No email support
 > 1

 Your full Gmail (e.g. [email protected]):
 > [email protected]

 Your Gmail password:
 > 

Saving data
-----------

 [OK] SMTP credentials saved to `/var/www/html/app/.env`    

UserFrosting
============

UserFrosing version : 4.3.3
OS Name : Linux
Project Root : /var/www/html
Environment mode : 
PHP Version : 7.2.24
Node Version : v10.16.3
NPM Version : 6.9.0

動作確認

以下設定したアドレスにアクセスして動作を確認して下さい。アプリ用のデフォルト画面が表示されます。画面右上 “Sign In” をクリックするとログイン画面が表示されます。上記インストール時に設定した管理ユーザ名とパスワードでログインして下さい。

以下メイン画面上の “UserFrosting” という表記や内容はデフォルトのものであり、各々のアプリに合わせてカスタマイズします。

メイン画面のカスタマイズ、ユーザテーブルデータの拡張方法などについては次回のブログ・フォーラムでフォローする予定です。

https://test-site.com/


UserFrostingアプリ用メイン画面



ユーザ登録画面



ユーザログイン画面



ユーザアカウント設定画面



登録ユーザ管理画面

php extension エラー

php-fpmコンテナを再構築後に上記不具合発生。php機能拡張モジュールが正しくインストールされていないことによる。

Userfrostingをphp-fpmコンテナ内で稼働させる場合、以下のapkパッケージ、php機能拡張が必要です。(上記のインストールプロセスでの記入漏れです。すみません。)

https://github.com/userfrosting/UserFrosting/blob/master/docker/php/Dockerfile

コンテナ内にbashコマンドで移動

$ docker exec -ti php-fpm bash

以下パッケージとphp機能拡張モジュールをインストール

# apk add libpng-dev freetype-dev libjpeg-turbo-dev zip
# docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/
# docker-php-ext-install -j$(nproc) gd
# docker-php-ext-install -j$(nproc) pdo pdo_mysql
# docker-php-ext-install -j$(nproc) zip

php-gd機能拡張モジュールを確認する場合(他のモジュールを確認する場合はgdをpdo,pdo_mysql,zipに置換え)

# php -i | grep -i gd
Additional .ini files parsed => /usr/local/etc/php/conf.d/docker-php-ext-gd.ini,
gd
GD Support => enabled
GD Version => bundled (2.1.0 compatible)
gd.jpeg_ignore_warning => 1 => 1

コンテナから出ます

# exit

コンテナの再起動

$ docker container restart php-fpm

補足:SMTPサーバ設定・変更

.envまたはapp/sprinkles/core/config/default.phpに設定内容を直接記述することで、SMTPの設定・変更ができます。

default.php

    /*
    * ----------------------------------------------------------------------
    * Mail Service Config
    * ----------------------------------------------------------------------
    * See https://learn.userfrosting.com/mail/the-mailer-service
    */
    'mail'    => [
        'mailer'          => 'smtp', // Set to one of 'smtp', 'mail', 'qmail', 'sendmail'
        'host'            => getenv('SMTP_HOST') ?: null,
        'port'            => 587,
        'auth'            => true,
        'secure'          => 'tls', // Enable TLS encryption. Set to `tls`, `ssl` or `false` (to disabled)
        'username'        => getenv('SMTP_USER') ?: null,
        'password'        => getenv('SMTP_PASSWORD') ?: null,
        'smtp_debug'      => 4,
        'message_options' => [
            'CharSet'   => 'UTF-8',
            'isHtml'    => true,
            'Timeout'   => 15,
        ],
    ],

メモ:Elastic Emailは5000件/日の送信が可能なフリーのメールサービス