#### **1.安装 jwt-auth。**
~~~
composer require tymon/jwt-auth 1.*@rc
~~~
#### **2.将服务提供程序添加到配置文件中的`providers`数组,`config/app.php`如下所示:**
~~~
'providers' => [
...
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
]
~~~
#### **3.运行以下命令以发布程序包配置文件:**
~~~
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
~~~
#### **4.生成加密密钥:**
~~~
php artisan jwt:secret
~~~
#### **5.修改 config/auth.php**
~~~
'guards' => [
'auth_admin' => [
'driver' => 'jwt',
'provider' => 'auth_admins'
]
],
~~~
```
'providers' => [
'auth_admins' => [
'driver' => 'eloquent',
'model' => Modules\Admin\Models\AuthAdmin::class,
]
],
```
#### **6.创建模型**
```
<?php
namespace Modules\Admin\Models;
use DateTimeInterface;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class AuthAdmin extends Authenticatable implements JWTSubject
{
use Notifiable;
protected $guard = 'auth_admin';
protected $hidden = [
'password'
];
/**
* @name jwt标识
* @description
* @author 西安咪乐多软件
* @date 2021/6/12 3:11
**/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* @name jwt自定义声明
* @description
* @author 西安咪乐多软件
* @date 2021/6/12 3:11
**/
public function getJWTCustomClaims()
{
return [];
}
/**
* @name 更新时间为null时返回
* @description
* @author 西安咪乐多软件
* @date 2021/6/12 3:11
**/
public function getUpdatedAtAttribute($value)
{
return $value?$value:'';
}
/**
* @name 关联权限组表 多对一
* @description
* @author 西安咪乐多软件
* @date 2021/6/12 3:12
**/
public function auth_groups()
{
return $this->belongsTo('Modules\Admin\Models\AuthGroup','group_id','id');
}
/**
* @name 关联平台项目表 多对一
* @description
* @author 西安咪乐多软件
* @date 2021/6/12 3:12
**/
public function auth_projects()
{
return $this->belongsTo('Modules\Admin\Models\AuthProject','project_id','id');
}
/**
* @name 时间格式传唤
* @description
* @author 西安咪乐多软件
* @date 2021/6/17 16:15
**/
protected function serializeDate(DateTimeInterface $date)
{
return $date->format('Y-m-d H:i:s');
}
}
```
#### **7.创建token的Services**
```
<?php
/**
* @Name 管理员信息服务
* @Description
* @Auther 西安咪乐多软件
* @Date 2021/6/11 17:10
*/
namespace Modules\Admin\Services\auth;
use Modules\Admin\Services\BaseApiService;
use Modules\Common\Exceptions\ApiException;
use Modules\Common\Exceptions\MessageData;
use Modules\Common\Exceptions\StatusData;
use Tymon\JWTAuth\Exceptions\TokenBlacklistedException;
use Tymon\JWTAuth\Facades\JWTAuth;
class TokenService extends BaseApiService
{
/**
* @name 设置token 生成机制
* @description
* @author 西安咪乐多软件
* @date 2021/6/11 17:23
* @return JSON
**/
public function __construct()
{
\Config::set('auth.defaults.guard', 'auth_admin');
\Config::set('jwt.ttl', 60);
}
/**
* @name 设置token
* @description
* @author 西安咪乐多软件
* @date 2021/6/11 17:24
* @param data Array 用户信息
* @param data.username String 账号
* @param data.password String 密码$
* @return JSON | Array
**/
public function setToken($data){
if (! $token = JWTAuth::attempt($data)){
$this->apiError('token生成失败');
}
return $this->respondWithToken($token);
}
/**
* @name 刷新token
* @description
* @author 西安咪乐多软件
* @date 2021/6/11 17:48
* @return JSON
**/
public function refreshToken()
{
try {
$old_token = JWTAuth::getToken();
$token = JWTAuth::refresh($old_token);
}catch (TokenBlacklistedException $e) {
// 这个时候是老的token被拉到黑名单了
throw new ApiException(['status'=>StatusData::TOKEN_ERROR_BLACK,'message'=>MessageData::TOKEN_ERROR_BLACK]);
}
return $this->apiSuccess('', $this->respondWithToken($token));
}
/**
* @name 管理员信息
* @description
* @author 西安咪乐多软件
* @date 2021/6/11 19:11
* @return Array
**/
public function my():Object
{
return JWTAuth::parseToken()->touser();
}
/**
* @name
* @description
* @author 西安咪乐多软件
* @date 2021/6/16 9:53
* @method GET
* @param
* @return JSON
**/
public function info()
{
$data = $this->my();
return $this->apiSuccess('',['username'=>$data['username']]);
}
/**
* @name 退出登录
* @description
* @author 西安咪乐多软件
* @date 2021/6/11 19:12
* @return JSON
**/
public function logout()
{
JWTAuth::parseToken()->invalidate();
return $this->apiSuccess('退出成功!');
}
/**
* @name 组合token数据
* @description
* @author 西安咪乐多软件
* @date 2021/6/11 17:47
* @return Array
**/
protected function respondWithToken($token):Array
{
return [
'token' => $token,
'token_type' => 'bearer',
'expires_in' => JWTAuth::factory()->getTTL() * 60
];
}
}
```
#### **8.创建登录Services**
```
<?php
/**
* @Name 用户登录服务
* @Description
* @Auther 西安咪乐多软件
* @Date 2021/6/11 16:50
*/
namespace Modules\Admin\Services\auth;
use Modules\Admin\Services\BaseApiService;
use Modules\Admin\Models\AuthAdmin as AuthAdminModel;
class LoginService extends BaseApiService
{
/**
* @name 用户登录
* @description
* @author 西安咪乐多软件
* @date 2021/6/11 16:53
* @param data Array 用户信息
* @param data.username String 账号
* @param data.password String 密码
* @return JSON
**/
public function login(array $data){
if (true == \Auth::guard('auth_admin')->attempt($data)) {
$userInfo = AuthAdminModel::where(['username'=>$data['username']])->select('id','username')->first();
if($userInfo){
$user_info = $userInfo->toArray();
$user_info['password'] = $data['password'];
$token = (new TokenService())->setToken($user_info);
return $this->apiSuccess('登录成功!',$token);
}
}
$this->apiError('账号或密码错误!');
}
}
```
#### **9.创建中间件**
```
<?php
// +----------------------------------------------------------------------
// | Name: 咪乐多管理系统 [ 为了快速搭建软件应用而生的,希望能够帮助到大家提高开发效率。 ]
// +----------------------------------------------------------------------
// | Copyright: (c) 2020~2021 https://www.lvacms.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed: 这是一个自由软件,允许对程序代码进行修改,但希望您留下原有的注释。
// +----------------------------------------------------------------------
// | Author: 西安咪乐多软件 <997786358@qq.com>
// +----------------------------------------------------------------------
// | Version: V1
// +----------------------------------------------------------------------
/**
* @Name 后台权限验证中间件
* @Description
* @Auther 西安咪乐多软件
* @Date 2021/6/4 13:37
*/
namespace Modules\Admin\Http\Middleware;
use Closure;
use Modules\Admin\Services\log\OperationLogService;
use Modules\Common\Exceptions\ApiException;
use Illuminate\Http\Request;
use Modules\Common\Exceptions\MessageData;
use Modules\Common\Exceptions\StatusData;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
use Tymon\JWTAuth\Exceptions\TokenBlacklistedException;
use JWTAuth;
use Modules\Admin\Models\Admin as AdminModel;
use Modules\Admin\Models\AuthGroup as AuthGroupModel;
use Modules\Admin\Models\AuthRule as AuthRuleModel;
class AdminApiAuth
{
public function handle($request, Closure $next)
{
\Config::set('auth.defaults.guard', 'auth_admin');
\Config::set('jwt.ttl', 60);
$route_data = $request->route();
$url = str_replace($route_data->getAction()['prefix'] . '/',"",$route_data->uri);
$url_arr = ['auth/login/login','auth/index/getMain','auth/index/refreshToken'];
$api_key = $request->header('apikey');
if($api_key != config('admin.api_key')){
throw new ApiException(['status'=>StatusData::TOKEN_ERROR_KEY,'message'=>MessageData::TOKEN_ERROR_KEY]);
return $next();
}
if(in_array($url,$url_arr)){
return $next($request);
}
try {
if (! $user = JWTAuth::parseToken()->authenticate()) { //获取到用户数据,并赋值给$user 'msg' => '用户不存在'
throw new ApiException(['status'=>StatusData::TOKEN_ERROR_SET,'message'=>MessageData::TOKEN_ERROR_SET]);
return $next();
}
}catch (TokenBlacklistedException $e) {
//token无效
if(in_array($url,['auth/index/logout'])){
return $next($request);
}
// 这个时候是老的token被拉到黑名单了
throw new ApiException(['status'=>StatusData::TOKEN_ERROR_BLACK,'message'=>MessageData::TOKEN_ERROR_BLACK]);
return $next();
} catch (TokenExpiredException $e) {
//token无效
if(in_array($url,['auth/index/logout'])){
return $next($request);
}
//token已过期
throw new ApiException(['status'=>StatusData::TOKEN_ERROR_EXPIRED,'message'=>MessageData::TOKEN_ERROR_EXPIRED]);
return $next();
} catch (TokenInvalidException $e) {
//token无效
if(!in_array($url,['auth/index/refresh','auth/index/logout'])){
throw new ApiException(['status'=>StatusData::TOKEN_ERROR_JWT,'message'=>MessageData::TOKEN_ERROR_JWT]);
}
return $next();
} catch (JWTException $e) {
//'缺少token'
throw new ApiException(['status'=>StatusData::TOKEN_ERROR_JTB,'message'=>MessageData::TOKEN_ERROR_JTB]);
return $next();
}
// 写入日志
(new OperationLogService())->store($user['id']);
// if(!in_array($url,['auth/index/refresh','auth/index/logout'])){
// if($user['id'] != 1 && $id = AuthRuleModel::where(['href'=>$url])->value('id')){
// $rules = AuthGroupModel::where(['id'=>$user['group_id']])->value('rules');
// if(!in_array($id,explode('|',$rules))){
// throw new ApiException(['code'=>6781,'msg'=>'您没有权限!']);
// }
// }
// }
return $next($request);
}
}
```