本文將用Lumen來實現一個完整的用戶注冊、登錄及獲取用戶信息的API。
Lumen環境搭建和初始化詳細步驟請參考上篇文章《Lumen安裝配置使用入門》一文。
一、准備工作
1、Lumen環境搭建
可參考上篇文章《Lumen安裝配置使用入門》一文。
2、數據庫信息
數據庫地址:localhost
數據庫名稱:lumenauth
數據庫用戶:root
數據庫密碼:******
二、初始化Lumen
lumen new LumenAuth
三、配置
1、數據庫配置
在命令行進入項目所在文件夾,執行命令:
copy .env.example .env
用文本編輯器打開.env文件,根據之前准備的數據庫信息作相應修改。
--------------------------------------- LumenAuth\.env --------------------------------------- APP_ENV=local APP_DEBUG=true APP_KEY= DB_CONNECTION=mysql DB_HOST=localhost DB_PORT=3306 DB_DATABASE=lumenauth DB_USERNAME=root DB_PASSWORD= CACHE_DRIVER=memcached QUEUE_DRIVER=sync ---------------------------------------
2、認證及修改生效配置
打開項目文件夾LumenAuth\bootstrap\app.php文件,我們將在這里作幾處修改。
(1)配置修改生效設置
首先,把以下兩行代碼取消注釋,讓數據庫信息和認證服務修改可以生效。
$app->withFacades(); $app->withEloquent();
(2)認證中間件注冊
參照LumenAuth\bootstrap\app.php文件中”Register Middleware” 部分的中間件注冊代碼,在它下面注冊一個認證路由中間件,這個路由中間件需要我們后面在LumenAuth\app\Http\Middleware文件夾中自定義,我們這里先做配置,后面進行代碼實現。注冊中間件使用以下代碼:
$app->routeMiddleware([ 'authToken' => App\Http\Middleware\AuthToken::class, ]);
(3)開啟注冊服務提供者
認證中間件的生效還需要注冊服務提供者支持,在LumenAuth\bootstrap\app.php文件下面把以下兩行代碼的注釋去掉即可開啟注冊服務提供者:
$app->register(App\Providers\AppServiceProvider::class); $app->register(App\Providers\AuthServiceProvider::class);
最后,LumenAuth\bootstrap\app.php文件有效代碼如下:
--------------------------------------- LumenAuth\bootstrap\app.php --------------------------------------- <?php require_once __DIR__.'/../vendor/autoload.php'; try { (new Dotenv\Dotenv(__DIR__.'/../'))->load(); } catch (Dotenv\Exception\InvalidPathException $e) { // } $app = new Laravel\Lumen\Application( realpath(__DIR__.'/../') ); $app->withFacades(); $app->withEloquent(); $app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, App\Exceptions\Handler::class ); $app->singleton( Illuminate\Contracts\Console\Kernel::class, App\Console\Kernel::class ); $app->routeMiddleware([ 'authToken' => App\Http\Middleware\AuthToken::class, ]); $app->register(App\Providers\AppServiceProvider::class); $app->register(App\Providers\AuthServiceProvider::class); $app->group(['namespace' => 'App\Http\Controllers'], function ($app) { require __DIR__.'/../app/Http/routes.php'; }); return $app; ---------------------------------------
四、用戶登錄認證案例需求及邏輯
本來這部分應該放在第一部分,但是由於這部分與下面幾部分關系比較緊密,因此放在這里一起。
這個案例要實現用戶注冊、登錄和獲取用戶信息三個功能。
1、用戶注冊
后端接收用戶附加用戶信息(用戶名、用戶密碼和郵箱)的請求后:
(1)判斷信息是否完整,如信息完整則進行下一步寫入數據庫階段,如果信息完整並成功寫入數據庫,則返回“用戶注冊成功!”信息,否則返回“用戶注冊失敗!”;
(2)如果信息不完整,不用操作數據庫,直接返回“請輸入完整用戶信息!”提示信息。
(3)用戶密碼處理:使用sha1加密方式並附加一個隨機自定義字符。
2、用戶登錄
(1)把用戶登錄和用戶信息請求分開,用戶登錄功能只是為了獲取一個可以請求獲取用戶信息的Token,而且每次用戶登錄成功后都會隨機改變Token值並更新數據庫中的Token。
(2)如果要獲取用戶信息,需要根據登錄成功后返回的Token另外單獨請求專門獲取用戶信息的API,核對Token值與數據庫保存的Token值后返回結果。
(3)用戶登錄成功后返回用戶最新Token;登錄失敗返回“用戶名或密碼不正確,登錄失敗!”;登錄信息不完整返回“登錄信息不完整,請輸入用戶名和密碼登錄!”。
3、獲取用戶信息
(1)根據用戶Token驗證返回用戶信息;
(2)使用Header包含Token形式附帶Token;
五、數據庫模型及數據表建立
1、建立數據模型
通過以上分析,可以建立基本的數據模型,這里只要用一張用戶表格就行了,用戶表結構如下:
------------------------------------------------- 字段 | 類型 | 其它 ------------------------------------------------- id | int(10) | AUTO_INCREMENT ------------------------------------------------- username | varchar(255) | ------------------------------------------------- password | varchar(255) | ------------------------------------------------- email | varchar(255) | ------------------------------------------------- api_token | varchar(60) | UNIQUE ------------------------------------------------- created_at | timestamp | ------------------------------------------------- updated_at | timestamp | -------------------------------------------------
2、創建用戶數據模式遷移
php artisan make:migration create_users_table --create=users
3、定義數據表結構
編輯LumenAuth\database\migrations\文件夾下的*_create_users_table.php文件
--------------------------------------- LumenAuth\database\migrations\*_create_users_table.php --------------------------------------- <?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateUsersTable extends Migration { public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('username'); $table->string('password'); $table->string('email'); $table->string('api_token', 60)->unique(); $table->timestamps(); }); } public function down() { Schema::drop('users'); } } ---------------------------------------
4、創建用戶數據模型
如果你的項目文件夾LumenAuth\app\文件夾下沒有User.php文件,那么新建一個User.php文件,文件內容如下:
--------------------------------------- LumenAuth\app\User.php --------------------------------------- <?php namespace App; use Illuminate\Auth\Authenticatable; use Laravel\Lumen\Auth\Authorizable; use Illuminate\Database\Eloquent\Model; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract; class User extends Model implements AuthenticatableContract, AuthorizableContract { use Authenticatable, Authorizable; protected $fillable = ['name', 'email', 'api_token']; protected $hidden = ['password']; } ---------------------------------------
六、路由定義
定義下面三個路由,用於實現用戶注冊、登錄及獲取用戶信息。
------------------------------------------------------------------ 序號 | 路由類型 | 路由路徑 | 路由控制器 ------------------------------------------------------------------ 1 | POST | users/login | UserController@login ------------------------------------------------------------------ 2 | POST | users/register | UserController@register ------------------------------------------------------------------ 3 | GET | users/info | UserController@info ------------------------------------------------------------------
根據上表在LumenAuth\app\Http\routes.php中定義路由:
--------------------------------------- LumenAuth\app\Http\routes.php --------------------------------------- <?php $app->get('/', function () use ($app) { return $app->version(); }); $app->post('users/login', 'UserController@login'); $app->post('users/register', 'UserController@register'); $app->get('users/info', [ 'middleware' => 'authToken', 'uses' => 'UserController@info' ]); ---------------------------------------
七、Controller邏輯
在LumenAuth\app\Http\Controllers\文件夾下新建用戶控制器UserController.php,實現用戶注冊、登錄和用戶信息獲取功能。
--------------------------------------- LumenAuth\app\Http\Controllers\Controller.php --------------------------------------- <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\User; use Auth; use Laravel\Lumen\Routing\Controller as BaseController; class UserController extends Controller { private $salt; public function __construct() { $this->salt="userloginregister"; } public function login(Request $request){ if ($request->has('username') && $request->has('password')) { $user = User:: where("username", "=", $request->input('username')) ->where("password", "=", sha1($this->salt.$request->input('password'))) ->first(); if ($user) { $token=str_random(60); $user->api_token=$token; $user->save(); return $user->api_token; } else { return "用戶名或密碼不正確,登錄失敗!"; } } else { return "登錄信息不完整,請輸入用戶名和密碼登錄!"; } } public function register(Request $request){ if ($request->has('username') && $request->has('password') && $request->has('email')) { $user = new User; $user->username=$request->input('username'); $user->password=sha1($this->salt.$request->input('password')); $user->email=$request->input('email'); $user->api_token=str_random(60); if($user->save()){ return "用戶注冊成功!"; } else { return "用戶注冊失敗!"; } } else { return "請輸入完整用戶信息!"; } } public function info(){ return Auth::user(); } } ---------------------------------------
八、認證服務
必須要通過token驗證才能獲取用戶信息。在LumenAuth\app\Http\Providers\AuthServiceProvider.php中定義驗證服務。我們使用header包含token的形式來驗證。修改LumenAuth\app\Http\Providers\AuthServiceProvider.php文件代碼。
--------------------------------------- LumenAuth\app\Http\Providers\AuthServiceProvider.php --------------------------------------- <?php namespace App\Providers; use App\User; use Illuminate\Support\Facades\Gate; use Illuminate\Support\ServiceProvider; class AuthServiceProvider extends ServiceProvider { public function register() { // } public function boot() { $this->app['auth']->viaRequest('api', function ($request) { if ($request->header('api_token')) { return User:: where('api_token', '=', $request->header('api_token'))->first(); } }); } } ---------------------------------------
九、定義認證中間件
在LumenAuth\app\Http\Middleware\文件夾下定義認證路由中間件AuthToken.php,就是之前在路由中定義的”authToken”。
--------------------------------------- LumenAuth\app\Http\Middleware\AuthToken.php --------------------------------------- <?php namespace App\Http\Middleware; use Closure; use Auth; class AuthToken { public function handle($request, Closure $next) { if(Auth::check()){ return $next($request); }else{ abort(401); } } } ---------------------------------------
十、測試使用
1、用戶注冊
2、用戶登錄
用戶登錄成功后,數據庫的api_token也會進行更新。
3、獲取用戶信息
完整源碼:https://github.com/yaoyonstudio/Lumen-User-Login-Register.git