我司前后端分離,所有的服務器端工程都是在開發API,本文列出詳細的實現步驟,給不熟悉Laravel的同學們參考。
1、數據庫表結構調整
在user表中,增加這樣的代碼
Schema::table('users', function ($table) { $table->string('api_token', 80)->after('password') ->unique() ->nullable() ->default(null); });
2、為用戶生成api_token,並加密存儲
由於前后端分離,因此api_token的創建和返回,只能是在用戶登錄的時候。於是:
定義一個api路由,user/login
Route::post('/user/login', 'Api\UserController@login');
創建一個controller,App/Http/Controllers/Api/UserController,在login方法中,保存加密過的api_token,並將未加密的api_token返回給請求者。
<?php namespace App\Http\Controllers\Api; use Illuminate\Http\Request; use App\Http\Controllers\HOBaseController; use App\Http\Requests\UserLoginRequest; use App\Http\Models\User; use Illuminate\Support\Str; class UserController extends HOBaseController { // public function login(UserLoginRequest $request) { $validated = $request->validated(); $user = User::where('name', $request->username) ->where('password', $request->password) ->first(); if(null == $user){ $this->error()->incorrectUsernameOrPassword(); } $token = Str::random(60); $user->api_token = hash('sha256', $token); $user->save(); return $this->response($token); } }
在config/auth.php文件中,把api這個guard的hash屬性,設置為“true”
'api' => [ 'driver' => 'token', 'provider' => 'users', 'hash' => true, ],
3、路由保護
用auth:api來保護所有的api路由(login路由除外)
Route::middleware('auth:api')->post('/test', 'Api\TestController@test');
4、鑒權失敗后的重定向
當前的訪問沒有通過authentication的時候,系統會拋出異常,因此我們在handler里面對此異常進行處理,確保返回值格式符合公司要求。
public function render($request, Exception $exception) { //對詳細的錯誤信息,進行記錄,但是不返回給前端 Log::debug( parent::render($request, $exception) ); if ( $exception instanceof HOException ) { $msg = $exception->getMessage(); $code = $exception->getCode(); }elseif($exception instanceof AuthenticationException){ $msg = $exception->getMessage(); $code = 2003; }else{ $msg = 'Server Bad'; $code = 2001; } return response()->horesp($code, null, $msg); }