我司前后端分离,所有的服务器端工程都是在开发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', 'ApiUserController@login');
创建一个controller,App/Http/Controllers/Api/UserController,在login方法中,保存加密过的api_token,并将未加密的api_token返回给请求者。
<?php namespace AppHttpControllersApi; use IlluminateHttpRequest; use AppHttpControllersHOBaseController; use AppHttpRequestsUserLoginRequest; use AppHttpModelsUser; use IlluminateSupportStr; 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', 'ApiTestController@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); }