版本
Lumen6.0
中文文档:https://learnku.com/docs/lumen/5.7/cache/2411
实现功能效果
1、使用缓存存储用户token
2、从请求头head 中获取用户token
3、返回指定的认证失败结构体
4、对指定的接口路由做身份验证
第一步:解除注释
注意:
在使用 Lumen 的认证功能前,
1、取消
bootstrap/app.php
文件中的AuthServiceProvider
调用代码的注释。2、去掉
bootstrap/app.php
文件中$app->withFacades()
方法调用的注释。3、去掉
bootstrap/app.php
文件中 $app->routeMiddleware([
'auth' => App\Http\Middleware\Authenticate::class,
]); 注释
第二步:接口路由验证身份 routes/web.php
<?php
$router->post('/user/login', 'UserController@login'); //登录/*** 需要登录的路由 使用 Auth 中间件*/
$router->group(['middleware' => ['auth']], function () use ($router) {$router->get('/user/info', 'UserController@user_info'); //获取用户信息
});
第三步:修改验证器方法 App\Providers\AuthServiceProvider.php
<?phpnamespace App\Providers;use App\Models\UserToken;
use App\Services\Cache\AuthCache;
use App\User;
use Illuminate\Support\ServiceProvider;class AuthServiceProvider extends ServiceProvider
{/*** Register any application services.** @return void*/public function register(){//}/*** Boot the authentication services for the application.** @return void*/public function boot(){// Here you may define how you wish users to be authenticated for your Lumen// application. The callback which receives the incoming request instance// should return either a User instance or null. You're free to obtain// the User instance via an API token or any other method necessary.// $this->app['auth']->viaRequest('api', function ($request) {
// if ($request->input('api_token')) {
// return User::where('api_token', $request->input('api_token'))->first();
// }
// });$this->app['auth']->viaRequest('api', function ($request) {/*** 下面验证内容是自定义的* 下面是用了两个表一个存token,一个存用户* 从请求头中获取token* 去用户user_token表中验证,存在则查出来用户信息返回到模型中*///从消息头获取传入的token$token = $request->headers->get('Authorization');$a = explode(" ", $token);if (isset($a[1]) && $a[1]) {$token = $a[1];}//token验证通过返回当前认证用户
// $token = UserToken::where('token',$token)->first();//从缓存中获取用户id$user_id = AuthCache::get_token_user_id($token);if($user_id){//返回user模型return User::where('id',$user_id)->first();}return null;});}
}
以上方式是通过缓存中查询token的,此处也可以改成数据库中查询,或者使用jwt解析
原理就是通过请求接口传输过来的token信息,通过token查询到关联的用户id,然后再查询用户信息,返回整个用户模型,之后就可以使用Auth::user() 拿到用户数据
第四步:查看user model模型下的内容,正常安装后是不需要改动的,这里我继承了一个自己写的BaseModel父类。
<?php
namespace App\Models;use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Laravel\Lumen\Auth\Authorizable;class User extends BaseModel implements AuthenticatableContract, AuthorizableContract
{protected string $title = '用户表';protected $guarded = ['id'];protected $table = 'users';/*** 复用下面两个trait类*/use Authenticatable, Authorizable;// /**
// * The attributes that are mass assignable.
// *
// * @var array
// */
// protected $fillable = [
// 'name', 'email',
// ];/*** The attributes excluded from the model's JSON form.** @var array*/protected $hidden = ['password',];}
第五步:修改认证失败后的,返回结构App/Http/Middleware/Authenticate.php
看一下默认返回结构
修改后返回结构,这里可以自定义,正常情况我们应在项目定义一个全局的返回结构体方法提供使用。
<?phpnamespace App\Http\Middleware;use App\Common\Common;
use App\Common\StatusConstants;
use Closure;
use Illuminate\Contracts\Auth\Factory as Auth;class Authenticate
{/*** The authentication guard factory instance.** @var \Illuminate\Contracts\Auth\Factory*/protected $auth;/*** Create a new middleware instance.** @param \Illuminate\Contracts\Auth\Factory $auth* @return void*/public function __construct(Auth $auth){$this->auth = $auth;}/*** Handle an incoming request.** @param \Illuminate\Http\Request $request* @param \Closure $next* @param string|null $guard* @return mixed*/public function handle($request, Closure $next, $guard = null){if ($this->auth->guard($guard)->guest()) {//这是默认的返回结构
// return response('Unauthorized.', 401);//修改返回结构return response()->json(['code'=>404,'msg'=>'无效的token','data'=>[]]);// Common::response_result(StatusConstants::ERROR_UNAUTHORIZED_TOKEN,'无效的token');}//验证通过return $next($request);}
}