laravel5.8集成JWT记录

laravel一直是被大家说是非常优雅的框架,这次无所事事也就翻开文档看看,并且之后也使用laravel5.8适配了一个reactAdmin后台管理系统,前后端分离,所以决定使用JWT。

原本在thinkPHP中使用jwt还是非常顺利简单的,不过在laravel上却花费了一番力气才整理完毕。

1composer安装
$ composer require tymon/jwt-auth 1.0.0-rc.1
2配置
  1. 发布配置文件
# 这条命令会在 config 下增加一个 jwt.php 的配置文件
$ php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
  1. 生成加密密钥
# 这条命令会在 .env 文件下生成一个加密密钥,如:JWT_SECRET=foobar
$ php artisan jwt:secret
  1. 创建权限管理模型

    laravel对于权限等等模块都有提供相应功能,这也是我在使用时候比较费解的问题,例如框架内部集成权限是使用User模型,其实根据业务不同肯定需要改动,正常情况我更喜欢自己去实现,毕竟文档中并没有详细的讲解其提供模块的实现,使用过程中花费时间去摸索也不容易啊。

namespace App\Models;

use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\MustVerifyEmail;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;

class Admin extends BaseModel implements
    AuthenticatableContract,
    AuthorizableContract,
    CanResetPasswordContract,
    JWTSubject
{
    use Notifiable, Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail;

    protected $hidden = ['password'];

    protected $fillable = ['name', 'password'];

    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    public function getJWTCustomClaims()
    {
        return [];
    }

    public function roles() {
        return $this->belongsToMany(Role::class);
    }
}
  1. 注册两个 Facade
    这两个 Facade 并不是必须的,但是使用它们会给你的代码编写带来一点便利。
# ./config/app.php
'aliases' => [
    ...
    // 添加以下两行
    'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
    'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
],
  1. 修改 auth.php
#./config/auth.php
//此处为我项目的配置
'guards' => [
    'web' => [
        'driver' => 'jwt',
        'provider' => 'admins',
    ],

    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
        'hash' => false,
    ],
],

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => \App\Models\User::class
    ],

    'admins' => [
        'driver' => 'eloquent',
        'model' => \App\Models\Admin::class,
    ],
],
3注册登录实现
  1. 控制器、注册、登录
    这里说一下laravel权限封装,没有暴露出具体实现,我也没探究式如何生成密码的,所以账号一定要先注册后再进行登录。
namespace App\Http\Controllers\Admin;

use App\Exceptions\AuthException;
use App\Exceptions\LoginException;
use App\Http\Controllers\Controller;
use App\Logic\AuthLogic;
use App\Models\Admin;
use App\Utils\Response;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Tymon\JWTAuth\Facades\JWTAuth;

class AuthController extends Controller
{

    /**
     * 后台管理员登录
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws AuthException
     * @throws LoginException
     */
    public function login(Request $request)
    {
        if (! $token = auth("web")->attempt([
            "name" => $request->input("userName"),
            "password" => $request->input("password")
        ])) {
            throw new LoginException(['msg' => '用户名或密码错误']);
        }
        if (JWTAuth::user()->status === 0) {
            throw new AuthException(['msg' => '用户暂无权限登录']);
        }
        //将token返回给前端
        JWTAuth::user()->token = $token;
        //存储用户相关权限
        (new AuthLogic(JWTAuth::user()))->saveAuthoritiesToCache();
        return Response::result(JWTAuth::user());
    }

    /**
     * 后台管理员注册
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function register(Request $request)
    {
        $name = $request->userName;
        $password = $request->password;
        $user = Admin::create(['name' => $name, 'password' => Hash::make($password)]);
        $user->token = JWTAuth::fromUser($user);
        return Response::result($user);
    }
}
  1. 定义路由
# ./routes/web.php
Route::middleware('validator:Auth')->namespace('Admin')->prefix('admin')->group(function () {
    // 后台登录
    Route::post('login', 'AuthController@login');

    //后台注册
    Route::post('register', 'AuthController@register');

});
4中间件校验token并获取用户信息、权限等
  1. 创建校验token中间件
namespace App\Http\Middleware;

use App\Exceptions\LoginException;
use App\Exceptions\TokenException;
use Closure;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
use Tymon\JWTAuth\Facades\JWTAuth;

class CheckToken
{
    /**
     * 校验登录JWT的token
     * @param Request $request
     * @param Closure $next
     * @return mixed
     * @throws LoginException
     * @throws TokenException
     */
    public function handle(Request $request, Closure $next)
    {
        try {
            if (!$user = JWTAuth::parseToken()->authenticate()) {
                throw new LoginException(['msg' => "未登录,请先登录"]);
            }
            //如果想向控制器里传入用户信息,将数据添加到$request里面
            $request->attributes->add(["user" => $user]);//添加参数
            return $next($request);
        } catch (TokenExpiredException $e) {
            throw new TokenException(['msg' => "token 过期"]);
        } catch (TokenInvalidException $e) {
            throw new TokenException(['msg' => "token 无效"]);
        } catch (JWTException $e) {
            throw new TokenException(['msg' => "缺少token"]);
        }
    }
}
  1. 创建校验token权限中间件
namespace App\Http\Middleware;

use App\Exceptions\AuthException;
use App\Logic\AuthLogic;
use Closure;
class CheckTokenAuth
{
	//不需要经过该中间件校验的路由
    protected $except = [
        "admin/menus/getUserRoutes",
    ];

    /**
     * 校验登录用户token绑定的路由权限
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @return mixed
     * @throws AuthException
     */
    public function handle($request, Closure $next)
    {

        if (
            !(new AuthLogic($request->user()))->checkAuth($request->route()->uri) &&
            !in_array($request->route()->uri, $this->except)
        ) {
            throw new AuthException();
        }
        return $next($request);
    }
}

  1. 注册并合并上面创建的两个中间件
    修改文件 ./app/Http/Kernel.php
protected $middlewareGroups = [
    ...

    //校验token,并且校验访问路由权限
    'api.auth' => [
        'jwt.api.token',
        'jwt.api.auth',
    ],
];
    
protected $routeMiddleware = [
    //登录校验
    'jwt.api.token' => \App\Http\Middleware\CheckToken::class,

    //登录用户访问api路由权限校验
    'jwt.api.auth' => \App\Http\Middleware\CheckTokenAuth::class,
];

  1. 路由配置
# ./routes/web.php
// Admin 模块
Route::middleware('api.auth')->namespace('Admin')->prefix('admin')->group(function () {

    Route::middleware('validator:Admin')->prefix('/admins')->group(function () {
        // 获取管理员列表
        Route::get('getAdmins', 'AdminController@getAdmins');
    })
});
  1. 控制器
namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Logic\AdminLogic;
use App\Logic\AuthLogic;
use App\Models\Admin;
use App\Utils\Response;
use Illuminate\Http\Request;

class AdminController extends Controller
{
    /**
     * 获取管理员列表
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getAdmins(Request $request) {
        $admins = Admin::with("roles")->paginate($request->pageSize);
        return Response::result($admins);
    }
}
5参考项目

ReactAdmin-Laravel

课程目录: 章节1:课前准备 课时1Laravel版本的选择05:46 课时2本地开发环境的搭建07:50 课时3本地域名解析08:40 课时4git的简单介绍08:53 课时5composer的安装和使用11:12 课时6课程源码同步08:14 课时7PHPStorm插件的安装05:44 课时8项目开发流程介绍03:19 章节2aravel基础入门 课时9Laravel的安装以及安装过程中常见问题24:40 课时10Laravel入门介绍08:46 课时11Laravel基本路由27:51 课时12Laravel路由参数32:25 课时13Laravel中间件22:43 章节3:项目模块设计和模板的引入 课时14模板的分离与blade布局模板03:12 课时15功能模块设计03:59 课时16后台控制器的创建与访问20:05 课时17后台模板的引入26:27 课时18前后台模板的获取34:33 章节4:后台-系统配置模板的开发 课时19创建站点配置页面23:57 课时20数据库连接和数据表的创建24:05 课时21网站配置信息写入数据表37:24 课时22完善网站配置(新手常见问题处理)18:59 课时23数据验证与数据闪存27:58 课时24完善系统配置功能27:59 课时25使用pjax提升后用户操作体验17:25 章节5:后台-新闻模块开发 课时26数据迁移与数据填充31:27 课时27新闻列表显示与新增36:33 课时28Laravel中的文件上传23:23 课时29富文本编辑器Neditor的使用28:56 课时30pjax下编辑器的异常处理10:07 课时31Laravel表单请求验证17:35 课时32新闻的编辑与删除34:48 课时33旧图片的处理和自定义公共函数16:10 章节6:无限级分类 课时34无限级分类原理33:06 课时35无限级分类的添加33:03 课时36无限级分类的删除与编辑20:21 课时37静态方法的正确使用07:56 课时38Laravel内置验证规则和自定义验证规则28:58 课时39提示信息的本地化11:34 章节7:后台-产品管理模块开发 课时40产品管理(1)27:23 课时41产品管理(2)-自定义验证规则25:42 课时42产品添加扩展内容14:41 课时43Laravel关联模型的使用21:33 课时44产品的编辑19:39 课时45产品编辑的完善07:13 课时46产品的批量删除与单条删除35:50 课时47使用Laravel模型事件完善产品删除功能18:37 章节8:后台-案例模块的开发 课时48数据表的创建和列表显示21:00 课时49案例的添加16:16 课时50案例的编辑与删除23:50 章节9:后台-单页模块开发 课时51单页模块(1)公司简介的处理32:11 课时52单页模块(2)招贤纳士功能实现35:00 课时53单页模块(3)发展历程的实现29:57 章节10:后台-轮播图模块开发 课时54轮播图模块表的设计与数据迁移09:19 课时55轮播图管理功能(1)20:59 课时56轮播图管理功能(2)32:43 课时57轮播图管理功能(3)自定义验证规则14:06 课时58问题处理21:57 课时59ajax实现异步排序19:42 课时60Laravel中访问器的使用11:42 课时61关于删除功能的扩展27:26 章节11:后台-友情连接模块开发 课时62友情连接模块开发28:07 章节12:后台权限认证 课时63管理员表的设计与创建15:46 课时64管理员登录验证的实现(1)25:11 课时65管理员登录验证的实现(2)23:59 章节13:前台 课时66前台首页的引入与布局模板21:01 课时67前台首页的数据调用(1)29:36 课时68前台首页的数据调用(2)16:51 课时69前台产品展示(1)23:35 课时70前台产品展示(2)15:31 课时71前台新闻数据调用17:50 课时72 Laravel自定义分页样式28:44 课时73前台新闻详情页04:33 课时74 前台案例展示11:37 课时75关于我们数据展示23:45 章节14:SEO优化入门 课时76常用的搜索引擎指令16:40 课时77SEO优化-标签优化11:46 课时78SEO优化-关键词优化08:14 课时79SEO优化-URL-robots优化07:43 课时80nofollow优化和图片优化16:43 课时81网站地图09:01 课时82链接优化与内容优化09:12 课时83百度推送(1)14:26 课时84百度推送(2)自定义类库(单例模式)27:28 课时85百度推送(3)21:13 课时86Laravel中Session的用法(百度推送优化)17:01 课时87蜘蛛来访36:09 课时88内容补充(纠错)05:18 章节15:网站安全 课时89网站安全介绍08:15 课时90上传漏洞介绍12:17 课时91常见攻击类型的防范方法06:15 课时92Laravel实现登录次数的限制19:20 课时93Laravel验证码的使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值