🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
#### **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); } } ```