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获取管理员信息测试

文章评论