Lumen用户认证主要是使用【API】的方式来进行认证,在实际开发中,我们不能只是简单的获取 api_token
直接关联数据库查找用户信息。在 API 开发中,用户认证是核心,是数据是否有保障的前提,目前主要有两种常用方式进行用户认证: JWT 和 OAuth2。
这萹文章主要讲怎么使用tymon/jwt-auth来实现JWT认证
一、安装引入jwt
composer require tymon/jwt-auth
速度慢的尝试切换阿里云镜像再执行(安装lumen应该已经配置过了)
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
二、配置文件auth.php修改
vendor/laravel/lumen-framework/config/auth.php
- auth.php修改参考:
<?php return [ /* |-------------------------------------------------------------------------- | Authentication Defaults |-------------------------------------------------------------------------- | | This option controls the default authentication "guard" and password | reset options for your application. You may change these defaults | as required, but they're a perfect start for most applications. | */ 'defaults' => [ 'guard' => env('AUTH_GUARD', 'user'), ], /* |-------------------------------------------------------------------------- | Authentication Guards |-------------------------------------------------------------------------- | | Next, you may define every authentication guard for your application. | Of course, a great default configuration has been defined for you | here which uses session storage and the Eloquent user provider. | | All authentication drivers have a user provider. This defines how the | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | | Supported: "token" | */ 'guards' => [ 'user' => [ 'driver' => 'jwt', 'provider' => 'users' ], 'operator' => [ 'driver' => 'jwt', 'provider' => 'operators' ] ], /* |-------------------------------------------------------------------------- | User Providers |-------------------------------------------------------------------------- | | All authentication drivers have a user provider. This defines how the | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | | If you have multiple user tables or models you may configure multiple | sources which represent each model / table. These sources may then | be assigned to any extra authentication guards you have defined. | | Supported: "database", "eloquent" | */ 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\User::class, ], 'operators' => [ 'driver' => 'eloquent', 'model' => App\Operator::class, ] ], /* |-------------------------------------------------------------------------- | Resetting Passwords |-------------------------------------------------------------------------- | | Here you may set the options for resetting passwords including the view | that is your password reset e-mail. You may also set the name of the | table that maintains all of the reset tokens for your application. | | You may specify multiple password reset configurations if you have more | than one user table or model in the application and you want to have | separate password reset settings based on the specific user types. | | The expire time is the number of minutes that the reset token should be | considered valid. This security feature keeps tokens short-lived so | they have less time to be guessed. You may change this as needed. | */ 'passwords' => [ // ], ];
其中users代表前台用户,operators代表后台管理用户,App\User是前台用户Model,App\Operator是后台管理用户Model
App\User.php参考
<?php namespace App; use Illuminate\Auth\Authenticatable; use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Database\Eloquent\Model; use Laravel\Lumen\Auth\Authorizable; use Tymon\JWTAuth\Contracts\JWTSubject; /** * Class User * @property integer id 用户ID * @property string uname 登陆账号 * @property string password 密码 * @property string code 辅助加密 * @property string nick 昵称 * @property string head 用户头像 * @property string realname 真实姓名 * @property integer sex 性别 * @property string state_code 国家码 * @property string mobile 手机号 * @property string email 电子邮箱 * @property string birthday 生日 * @property string last_ip 最后登陆IP * @package App */ class User extends Model implements AuthenticatableContract, AuthorizableContract, JWTSubject { use Authenticatable, Authorizable; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'nick', 'realname', 'state_code', 'mobile', 'birthday', 'sex' ]; protected $casts = [ 'created_at' => 'timestamp', 'updated_at' => 'timestamp', ]; /** * The attributes excluded from the model's JSON form. * * @var array */ protected $hidden = [ 'password', 'code', "reset_code", "reset_time", "robots", "head" ]; public function getJWTIdentifier() { return $this->getKey(); } public function getJWTCustomClaims() { return [ 'token' => $this->token, ]; } public function toArray() { $arr = parent::toArray(); if (!empty($this->head)) { $arr['head_img'] = url($this->head); } return $arr; } }
App\Operator.php参考
<?php namespace App; use Illuminate\Auth\Authenticatable; use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Database\Eloquent\Model; use Laravel\Lumen\Auth\Authorizable; use Tymon\JWTAuth\Contracts\JWTSubject; /** * Class Operator * @package App * @property integer id 管理员ID * @property string username 管理员登陆账号 * @property string password 密码 * @property string code 辅助加密 * @property string name 姓名 * @property string mobile 电话 * @property string email 邮箱 * @property boolean super 是否超级管理员 * @property integer role_id 角色ID * @property string last_ip 最后登陆IP * @property string memo 员工简介 */ class Operator extends Model implements AuthenticatableContract, AuthorizableContract, JWTSubject { use Authenticatable, Authorizable; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = ['name', 'mobile', 'email', 'super', 'role_id', 'last_ip', 'memo']; protected $casts = [ 'super' => 'boolean', 'created_at' => 'timestamp', 'updated_at' => 'timestamp', ]; /** * The attributes excluded from the model's JSON form. * * @var array */ protected $hidden = [ 'password', 'code' ]; public function getJWTIdentifier() { return $this->getKey(); } public function getJWTCustomClaims() { return []; } /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function role() { return $this->belongsTo(Role::class); } }
三、注册ServiceProvider:
1、在bootstrap/app.php中注册对应的Provider
$this->app->register(\Tymon\JWTAuth\Providers\LumenServiceProvider::class);
2、在bootstrap/app.php中打开配置withFacades,去掉$app->withFacades();前面的注释
$app->withFacades();
3、增加auth中间件
$app->routeMiddleware([ 'auth' => App\Http\Middleware\Authenticate::class, ]);
bootstrap/app.php代码参考:
<?php require_once __DIR__.'/../vendor/autoload.php'; (new Laravel\Lumen\Bootstrap\LoadEnvironmentVariables( dirname(__DIR__) ))->bootstrap(); /* |-------------------------------------------------------------------------- | Create The Application |-------------------------------------------------------------------------- | | Here we will load the environment and create the application instance | that serves as the central piece of this framework. We'll use this | application as an "IoC" container and router for this framework. | */ $app = new Laravel\Lumen\Application( dirname(__DIR__) ); $app->withFacades(); $app->withEloquent(); /* |-------------------------------------------------------------------------- | Register Container Bindings |-------------------------------------------------------------------------- | | Now we will register a few bindings in the service container. We will | register the exception handler and the console kernel. You may add | your own bindings here if you like or you can make another file. | */ $app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, App\Exceptions\Handler::class ); $app->singleton( Illuminate\Contracts\Console\Kernel::class, App\Console\Kernel::class ); /* |-------------------------------------------------------------------------- | Register Config Files |-------------------------------------------------------------------------- | | Now we will register the "app" configuration file. If the file exists in | your configuration driectory it will be loaded; otherwise, we'll load | the default version. You may register other files below as needed. | */ $app->configure('app'); $app->configure('translatable'); /* |-------------------------------------------------------------------------- | Register Middleware |-------------------------------------------------------------------------- | | Next, we will register the middleware with the application. These can | be global middleware that run before and after each request into a | route or middleware that'll be assigned to some specific routes. | */ $app->middleware([ App\Http\Middleware\CorsMiddleware::class ]); $app->routeMiddleware([ 'auth' => App\Http\Middleware\Authenticate::class, ]); /* |-------------------------------------------------------------------------- | Register Service Providers |-------------------------------------------------------------------------- | | Here we will register all of the application's service providers which | are used to bind services into the container. Service providers are | totally optional, so you are not required to uncomment this line. | */ $app->register(Tymon\JWTAuth\Providers\LumenServiceProvider::class); $app->register(Illuminate\Redis\RedisServiceProvider::class); $app->register(Astrotomic\Translatable\TranslatableServiceProvider::class); // $app->register(App\Providers\AppServiceProvider::class); // $app->register(App\Providers\AuthServiceProvider::class); // $app->register(App\Providers\EventServiceProvider::class); /* |-------------------------------------------------------------------------- | Load The Application Routes |-------------------------------------------------------------------------- | | Next we will include the routes file so that they can all be added to | the application. This will provide all of the URLs the application | can respond to, as well as the controllers that may handle them. | */ $app->router->group([ 'namespace' => 'App\Http\Controllers', ], function ($router) { require __DIR__.'/../routes/web.php'; }); return $app;
中间件App\Http\Middleware\Authenticate代码参考如下:
<?php namespace App\Http\Middleware; 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); } // 判断当前用户是否登录 if ($this->auth->guard($guard)->check()) { $user = $this->auth->guard($guard)->user(); // 获取登陆信息 \Illuminate\Support\Facades\Auth::setUser($user); // 设置Auth获取的用户信息 } return $next($request); } }
四、jwt需要生成secret,修改配置文件设置过期时间等参数
1、jwt需要生成secret,执行后会生成在.env文件中
php artisan jwt:secret
2、配置文件中配置过期时间等参数,如下
JWT_SECRET=lCWOhg***********************************G98VwvwE7l #有效时间-单位:分钟 7天 JWT_TTL = 10080 #刷新时间-单位:分钟 默认 30天 JWT_REFRESH_TTL = 43200 #宽限时间 单位:秒 JWT_BLACKLIST_GRACE_PERIOD = 60
五、配置路由进行测试,这里使用后台用户测试
routes/web.php 路由代码参考:
$router->group(['namespace' => 'Admin', 'prefix' => 'admin'], function () use ($router) { $router->post('login', ['name' => '管理员登陆', 'uses' => 'LoginController@login']); $router->group(['middleware' => 'auth:operator'], function () use ($router) { $router->get('operator', ['name' => '获取管理员信息', 'uses' => 'OperatorController@userinfo']); }); });
其中'middleware'=>'auth:operator'是设置后台管理的中间键
登陆控制器App\Http\Controllers\Admin\LoginController.php代码参考:
<?php namespace App\Http\Controllers\Admin; use App\Http\Lib\Result; use App\Operator; use Illuminate\Http\Request; use Laravel\Lumen\Routing\Controller; use Tymon\JWTAuth\Facades\JWTAuth; class LoginController extends Controller { /** * 用户登陆 * @return \Illuminate\Http\JsonResponse */ public function login(Request $request) { if ($request->has('username') && $request->has('password')) { $user = Operator::query() ->where('username', '=', $request->input('username')) ->first(); if ($user == null) { return Result::error(Result::ERR_UNAME, '管理员账户不存在!'); } if ($user && $user->password === md5($request->input('password') . $user->code)) { $user->last_ip = $request->getClientIp(); $user->save(); $token = JWTAuth::fromUser($user); $formatToken = $this->formatToken($token); $formatToken['uuid'] = $user->username; return Result::success($formatToken); } else { return Result::error(Result::ERR_PWD, '密码错误'); } } else { return Result::error(Result::ERR_PARAM, '登录信息不完整,请输入用户名和密码'); } } /** * Get the token array structure. * * @param string $token * * @return array */ protected function formatToken($token) { return [ 'access_token' => $token, 'token_type' => 'Bearer', 'expires_in' => time() + JWTAuth::factory()->getTTL() * 60 ]; } }
获取管理员信息的控制器App\Http\Controllers\Admin\OperatorController.php代码参考:
<?php namespace App\Http\Controllers\Admin; use App\Http\Lib\Result; use App\Operator; use Illuminate\Support\Facades\Auth; class OperatorController extends AuthController { /** * 获取用户信息 * @return \Illuminate\Http\JsonResponse */ public function userinfo() { $user = Auth::user(); return Result::success($user); } }
六、POSTMAN接口测试
1、登陆接口测试:
2、通过access_token获取管理员信息测试
文章评论