laravel 內建 Auth 功能實測

@ver 0.1.4 @date 2019-05-09 05:51:33 (星期四)

@ver 0.1.3 @date 2019-03-12 10:58:21 (星期二)

@ver 0.1.2 @date 2019-03-04 21:46:12 (星期一)

@ver 0.1.1 @date 2019-03-02 12:05:52 (星期六)

artisan wiki

匠人, 職人, 是指擁有某項熟練技巧, 手工一流的專業人員

  1. 測試專案開始

### 建立新的測試專案

#### 安裝前置作業, 工具整備 bash [alex@nvda ~ ]$ composer -V Composer version 1.8.4 2019-02-11 10:52:10 [alex@nvda ~ ]$ laravel -V bash: laravel:命令找不到 # 先用 composer 安裝 laravel install 到自己的 home 目錄之下 [alex@nvda ~ ]$ composer global require "laravel/installer" # 等待 ... 出現命令列提示符號 [alex@nvda ~ ]$ ll ~/.config/composer/vendor/bin/laravel lrwxrwxrwx 1 alex admin 28 3月 3 21:16 /home/alex/.config/composer/vendor/bin/laravel -> ../laravel/installer/laravel* # # # 把 bin 路徑加入 .profile vi ~/.profile # 跳到最後一行, 加入 PATH="$HOME/.config/composer/vendor/bin:$PATH" # 登出再登入 [alex@nvda ~ ]$ laravel -V Laravel Installer 2.0.1 [alex@nvda ~ ]$

#### 工作目錄 plaintext 開發中, 習慣把的各種專案集中放在 ~/jobs/ 目錄裡, 這裡就是 `工作目錄`, 每個人可以依照自己的方式, 找個地方當作工作目錄. 在任何目錄之下都可以執行上面安裝 `Laravel Installer` 建立專案. 如果在 ~/ 之下執行 laravel new testAuth, 它就會建立新的 ~/testAuth/ 專案. 如果在 ~/abc/ 之下執行 laravel new testAuth, 它就會建立新的 ~/abc/testAuth/ 專案. 如果在 /tmp/ 之下執行 laravel new testAuth, 它就會建立新的 /tmp/testAuth/ 專案.

#### 安裝命令及說明 bash # 進入工作目錄(或自行建立新的子目錄) cd ~/jobs # 執行創立新的 laravel 套件命令, 有兩種方式 # 方式之一, 用 Laravel Installer, 執行 laravel new testAuth # 方式之二, 直接使用 composer , 執行 composer create-project --prefer-dist laravel/laravel testAuth # 等待約 60 秒, 出現命令列提示符號, 完成. 再進入專案的工作目錄 cd testAuth/ # 查看版本 php artisan -V # Laravel Framework 5.8.2 # 修改預設 .gitignore , 加入自已平常工作用的相關忽略文件 vi .gitignore # 修改資料連結的參數 vi .env # 用上面修改的參數, 到 mysql 建立資料庫, charset 用 utf8mb4 # (可不用修改, 使用預設 utf8mb4_unicode_ci) mysql 資料庫 collation 預設 utf8mb4_unicode_ci 改為 utf8mb4_general_ci # (可不用修改, 使用預設 utf8mb4_unicode_ci) vi config/database.php # 修改系統基礎設定, 時間 timezone 預設 UTC, 改為 Asia/Taipei # 修改系統基礎設定, 本地化 locale 預設 en, 改為 zh-TW vi config/app.php # 另外有一個 'fallback_locale' => 'en', 這個是指如果 'zh-TW' 找不到的話, 它要找誰的語言來替代顯示, 因為所有各種版本都一定有英文對應文字, 所以就用 'en' 即可, 改成 'zh-TW' 或其他語言也沒有什麼問題, 只是可能會顯示空白, 也許剛好可以拿來測試未翻譯本地化的文字. # (可暫時跳過) 修改 建立 自定義版本 log # (可暫時跳過) 自定義的單一日期時間 log 檔案, 每一次 request 產生一個記錄 # (可暫時跳過) 複製自定義 log class, app/Loggers/my1LocalLogger.php # (可暫時跳過) 複製自定義 json 輸出 class, app/Loggers/JsonFormatter.php vi config/logging.php # 啟動 laravel 內建 WEB 服務器, 預設 listen ip 為本機 127.0.0.1 , prot=8000, 可自定義, 只要不與原有或其他使用者互相衝突即可. 現在暫時用 2019 port 來啟動, 以下命令為本機 php artisan serve --port=2019 # 如果在雲端主機, 記得要加上 --host=nvda ( nvda 在 /etc/hosts 已指定 ip ), 把 listen ip 改為外部 ip 或 domain php artisan serve --host=nvda --port=2019 # 進入瀏覽器, 本機就用 http://127.0.0.1:2019, 雲端主機就用 http://www.nvda.org.tw:2019 或 http://172.104.76.106:2019

### git 初始化並提交

#### 命令 bash git init git st -s git add . git commit -m 'init testAuth'

完成新的專案及 git

  1. 建立資料庫

### create db

配合 .env 裡的設定, 進入 mysql 命令列, 以下 MYDATABASE, MYDBUSER, MYDBPASSWORD 請修改對應

#### 命令 bash DROP DATABASE IF EXISTS MYDATABASE; CREATE DATABASE MYDATABASE DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; # mysql 5.7 以下可以使用 `WITH mysql_native_password` 或 `WITH sha256_password` 兩種不同的密碼加密方式, 若是 mysql 5.6 以下, 就把這兩個單字移除 CREATE USER 'MYDBUSER'@'localhost' IDENTIFIED WITH mysql_native_password BY 'MYDBPASSWORD'; GRANT ALL ON MYDATABASE.* TO 'MYDBUSER'@'localhost'; FLUSH PRIVILEGES; # 修改 USER 加密方式 ALTER USER 'MYDBUSER'@'localhost' IDENTIFIED WITH sha256_password BY 'MYDBPASSWORD'; ALTER USER 'MYDBUSER'@'localhost' IDENTIFIED WITH mysql_native_password BY 'MYDBPASSWORD';

### sha256_password 登入問題

#### 命令 bash mysql -u MYDBUSER -p MYDATABASE php artisan migrate --seed

#### 執行結果 ```shell [alex@nvda ~/jobs/testAuth ]$ mysql -u MYDBUSER -p MYDATABASE Enter password: ERROR 2061 (HY000): Authentication plugin 'sha256_password' reported error: Authentication requires SSL encryption [alex@nvda ~/jobs/testAuth ]$ [alex@nvda ~/jobs/testAuth ]$ php artisan migrate --seed

PDOException : SQLSTATE[HY000] [2006] MySQL server has gone away

at /home/alex/jobs/testAuth/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:70 66| if (class_exists(PDOConnection::class) && ! $this->isPersistentConnection($options)) { 67| return new PDOConnection($dsn, $username, $password, $options); 68| } 69| > 70| return new PDO($dsn, $username, $password, $options); 71| } ```

如果 CREATE USER 時使用 sha256_password, 在登入出現 ERROR 2061 (HY000): Authentication plugin 'sha256_password' reported error: Authentication requires SSL encryption 時必須使用 SSL

執行 php artisan migrate --seed 也會出現 PDOException : SQLSTATE[HY000] [2006] MySQL server has gone away 的錯誤訊息

用新的 mysql 8 版本測試, 完全沒問題, 可能是此版本 (mysql 5.7.25) 沒有把 ssl 套件包進去, 或者要另做其他處理

如果碰到此問題, 先暫時使用 IDENTIFIED WITH mysql_native_password 的方式, 建立資料使用者密碼.

  1. make:auth

laravel 有內建的使用者帳號註册認證...等基本功能, 可以節省不少開發時間, 只要 php artisan make:auth 一鍵即可產生 auth 相關程式, 並用 git 觀察增加了那一些檔案.

### 在命令列執行 make:auth

#### 命令 bash # 產生 auth 相關程式 php artisan make:auth # git 觀察增加了那一些檔案 git st -s git add . git st -s

#### 執行結果 shell [alex@nvda ~/jobs/testAuth ] $ php artisan make:auth Authentication scaffolding generated successfully. [alex@nvda ~/jobs/testAuth ] $ [alex@nvda ~/jobs/testAuth ] $ git st -s M routes/web.php ?? app/Http/Controllers/HomeController.php ?? resources/views/auth/ ?? resources/views/home.blade.php ?? resources/views/layouts/ [alex@nvda ~/jobs/testAuth ] $ git add . [alex@nvda ~/jobs/testAuth ] $ git st -s A app/Http/Controllers/HomeController.php A resources/views/auth/login.blade.php A resources/views/auth/passwords/email.blade.php A resources/views/auth/passwords/reset.blade.php A resources/views/auth/register.blade.php A resources/views/auth/verify.blade.php A resources/views/home.blade.php A resources/views/layouts/app.blade.php M routes/web.php [alex@nvda ~/jobs/testAuth ] $

此命令修改了 routes/web.php. 增加了 8 個檔案, 其中包含 7 個 view 檔案, 以及一個 app/Http/Controllers/HomeController.php.

進入 瀏覽器 可以看到右上角多了 Login Register 兩個連結, 到目前為止, 很順利

  1. migrate 生成及遷移資料庫

查看預設版本的 users 資料庫欄位, 並執行 migrate, 同時產生 seed

### 在命令列執行 migrate --seed

#### 命令 bash # 查看預設版本的 users 資料庫欄位 vi database/migrations/2014_10_12_000000_create_users_table.php vi database/migrations/2014_10_12_100000_create_password_resets_table.php # 執行 migrate php artisan migrate --seed

#### 執行結果 shell 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`))

### mysql index 錯誤處理

出現了一個很頑固且常見的錯誤, 這跟 laravel 無關, 看看 2014_10_12_000000_create_users_table.php 檔案, 有一行程式碼

php $table->string('email')->unique();

string() 代表 varchar(), 若沒有指定長度, 預設是 varchar(255), 因為我們指定它為 unique(), 所以建立資料庫時會產生一行指令 unique users_email_unique(email).

mysql charset 為 utf8mb4. 每個字是 4 bytes , 4 X 255 = 1020 bytes, 超過 mysql 預設的最大長度 766 bytes. 所以要修改 email 的長度為 190 ( 4 X 190 = 760).

php $table->string('email', 190)->unique();

另一個檔案 2014_10_12_100000_create_password_resets_table.php 裡的 email 欄位也一樣狀況, 改長度為 190.

修改完成後 migrate , 如果又出現錯誤, 可能是先前升級一半, 沒有完成, 舊的 table 還在.

### 重新生成及遷移資料庫

> migrate 逐次生成及遷移, 它會查詢資料庫裡的 migrations table, 比對日期時間檔名, 未遷移檔案裡的欄位用 alter 加入 table. > > migrate:fresh 放下一切, 重新做人. 它會 DROP 所有 table, 然後 create 新的 table, 而不是逐次生成及遷移, 要小心使用, 重要 : 記得隨時先備份原有資料庫.

#### 命令 bash php artisan migrate --seed php artisan migrate:fresh --seed # 重要 : 記得隨時先備份原有資料庫

#### 執行結果 ```shell [alex@nvda ~/jobs/testAuth ] $ php artisan migrate --seed Migrating: 2014_10_12_000000_create_users_table

Illuminate\Database\QueryException : SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'users' already exists ........

[alex@nvda ~/jobs/testAuth ] $ php artisan migrate:fresh --seed Dropped all tables successfully. Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table Database seeding completed successfully. [alex@nvda ~/jobs/testAuth ] $ ```

  1. 網頁與資料庫第一次接觸

### 第一次註冊

重新遷移升級完成後, 進入 Register 頁面 測試, 照規則輸入簡單的註冊資訊, 按下提交. 好像沒那麼簡單...

#### 頁面錯誤訊息 bash ReflectionException (-1) Class setEventDispatcher does not exist

這個時候, 先重新啟動 WEB 服務器. 遇到任何問題, 第一個考慮的方式 ... :-D

回到命令列, 用 Ctrl+C 結束先前執行的 php artisan serve --port=2019. 結束之後, 再重新執行一次, 問題依然發生.

google 很久很久才找到 This is a known PHP 7.3.0 bug. You should update your PHP version (ideally to 7.3.2). 也許 7.3.0 之前不會有問題, 所以請大家先試試看, 若出現相同問題, 再考慮升級為最新版本(7.3.2 以後).

#### (可跳過) mac 升級 php 7.3.0 為 7.3.2 `` [alex] $ brew install php@7.3 Error: php 7.3.0_1 is already installed To upgrade to 7.3.2, runbrew upgrade php ==>brew cleanup` has not been run in 30 days, running now... Error: Permission denied @ unlink_internal - /usr/local/lib/node_modules/electron-prebuilt/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/Libraries

[alex] $ brew upgrade php Updating Homebrew... ==> Upgrading 1 outdated package: php 7.3.0_1 -> 7.3.2 ... [alex] $ php -v PHP 7.3.2 (cli) (built: Feb 14 2019 10:08:45) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.3.2, Copyright (c) 1998-2018 Zend Technologies with Zend OPcache v7.3.2, Copyright (c) 1999-2018, by Zend Technologies ```

升級完成, 重新啟動 WEB 服務器, 再測試輸入註冊資訊, 果然成功.

#### 頁面訊息 shell Dashboard You are logged in!

### 檢查資料庫

#### 命令 sql select * from users;

#### 執行結果 ```shell mysql> select * from users; +----+------+---------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+ | id | name | email | email_verified_at | password | remember_token | created_at | updated_at | +----+------+---------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+ | 1 | aa | a@b.com | NULL | $2y$10$zEoyfDL/uTp4ScResbMx/uQbzObWsIy/dhkD115yoiVbJ72GW4fQO | NULL | 2019-03-02 15:59:27 | 2019-03-02 15:59:27 | +----+------+---------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+ 1 row in set (0.00 sec)

mysql> ```

  1. 訊息在地中文化

### 出現英文錯誤訊息

回到頁面上 Logout (登出), 再進入 Register 重新註冊, 但仍使用 a@b.com 這個 email, 因為我們設定 email 為 unique, 會出現下列的錯誤訊息

參考文件

#### 頁面訊息 shell E-Mail Address The email has already been taken.

### 訊息檔案目錄 resources/lang/

為了要中文化, 我們要 cp -frp en zh-TW (先前修改系統基礎設定, 本地化 locale 預設 en, 改為 zh-TW) 整個子目錄.

#### 命令 bash cd resources/lang/ cp -frp en zh-TW ls cd zh-TW ls

#### 執行結果 shell [alex@nvda ~/jobs/testAuth ] $ cd resources/lang/ [alex@nvda ~/jobs/testAuth/resources/lang ] $ cp -frp en zh-TW # 有兩個子目錄 [alex@nvda ~/jobs/testAuth/resources/lang ] $ ls en zh-TW [alex@nvda ~/jobs/testAuth/resources/lang ] $ cd zh-TW/ # 有 4 個 php 檔案 [alex@nvda ~/jobs/testAuth/resources/lang/zh-TW ] $ ls auth.php pagination.php passwords.php validation.php

### 第一次中文化就上手

resources/lang/zh-TW/validation.php 這個檔案裡有一段

php 'unique' => 'The :attribute has already been taken.', 改成中文 php 'unique' => ':attribute 已經存在。',

存檔完成後, 返回瀏覽器註冊頁, 重試一次 email 欄位 a@b.com, 此刻會出現剛剛在地中文化之後的錯誤訊息. 傑克, 真是太神奇了...

#### 頁面訊息 shell E-Mail Address email 已經存在。

#### 別忘了 git 一下 bash git add . git commit -m 'Auth + 第一次在地中文化完成'

  1. 在地化的語言套件

剛剛在 resources/lang/zh-TW/ 裡的那 4 個 php 檔案, 大約不到 200 個訊息字串, 不是很多. 逐一自行翻譯, 看起來不是苦差事, 但也不是好差事. 每次建造一台車子, 都要重新發明輪子, 這也真的太辛苦了, 還好有

Laravel-lang 套件

從網站的 README.md 得知安裝方式

#### 命令及說明 shell # 安裝 caouecs/laravel-lang # Laravel 5.8 composer require caouecs/laravel-lang:~4.0 # Laravel 5.1-5.7 composer require caouecs/laravel-lang:~3.0 # 等待約 60 秒, 出現命令列提示符號, 查看 ls vendor/caouecs/laravel-lang/src/zh-TW/ # 有 4 個 php 檔案 auth.php pagination.php passwords.php validation.php # 複製這 4 個已在地中文化的 php 檔案到實際運作的 resources/lang/zh-TW/ cp -f vendor/caouecs/laravel-lang/src/zh-TW/* resources/lang/zh-TW/ # 或 cp -fRp vendor/caouecs/laravel-lang/src/zh-TW resources/lang/ # 查看是否正確 vi resources/lang/zh-TW/validation.php # 補充-1 @date 2019-05-09 21:17:56 (星期四) # 還有一個主要的檔案 json 也要複製, 這個檔案包含很多基本語句本地化 cp vendor/caouecs/laravel-lang/json/zh-TW.json resources/lang/

> 補充-1 說明 > > 還有一個主要的檔案 json 也要複製, 這個檔案包含很多基本語句本地化, 例如 resources/views/auth/login.blade.php 裡有 {{ __('Login') }}, 在英文版本正常狀態下, 會在瀏覽器上顯示 Login 這五個英文字, 先前忘了複製這個檔案, 所以即使我們在 config/app.php 裡設定 'locale' => 'zh-TW', 它還是顯示為英文的 Login. > > vendor/caouecs/laravel-lang/json/zh-TW.json 複製完成之後, 再更新網頁, 已經看到 登入 中文本地化的文字.

返回瀏覽器註冊頁, 嘗試各種錯誤, 讓它顯示在地中文化之後的任何訊息. 如果看到這個版本的中文太糟糕, 隨時自己動手修改這幾個 php 檔, 改成感覺良好的中文訊息.

#### git bash git add . git commit -m 'Auth + Laravel-lang 在地化的語言套件完成'

  1. 本章總結

### 本章使用 laravel 命令總結 bash composer global require ... # composer 到 home 目錄下 laravel new project # 建立 laravel 專案 php artisan serve # 啟動內建 WEB 服務器 php artisan serve --port=2019 # 啟動內建 WEB 服務器 php artisan serve --host=nvda --port=2019 # 啟動內建 WEB 服務器 php artisan make:auth # 產生 auth 使用者帳號註册 php artisan migrate --seed # 生成及遷移資料庫 php artisan migrate:fresh --seed # 完整重新生成及遷移資料庫 resources/lang/ # 訊息在地中文化 composer require caouecs/laravel-lang:~3.0 # Laravel-lang 在地化的語言套件