诚城的成长 诚城的成长
首页
  • 高数基础
  • 数一

    • 高等数学
    • 线性代数
    • 概率论与数理统计
  • 820

    • 数据结构
    • 计算机操作系统
  • 英一

    • 单词
    • 语法
    • 阅读理解
    • 作文
  • 政治

    • 马克思主义基本原理
    • 毛泽东
    • 近代史
    • 思修
    • 时事
  • openpose
  • html5
  • css3
  • UI

    • Tailwind Css
    • Element-Plus
    • UniApp
  • 框架

    • Vue3
  • 拓展包

    • 包管理工具
    • 包开发
  • 开发语言

    • C语言
    • PHP
    • Phyton
  • 框架

    • Laravel
  • 会计

    • 初级经济法基础
    • 初级会计实务
  • 软考

    • 信息系统项目管理师
  • 博客

    • vitepress
    • vuepress
  • manim
  • git
  • vsCode
  • latex
  • docker
  • axios
  • vim
  • mac
  • Jetbrains

    • phpstorm
    • clion
突发奇想
GitHub (opens new window)

诚城

我有N个梦想……
首页
  • 高数基础
  • 数一

    • 高等数学
    • 线性代数
    • 概率论与数理统计
  • 820

    • 数据结构
    • 计算机操作系统
  • 英一

    • 单词
    • 语法
    • 阅读理解
    • 作文
  • 政治

    • 马克思主义基本原理
    • 毛泽东
    • 近代史
    • 思修
    • 时事
  • openpose
  • html5
  • css3
  • UI

    • Tailwind Css
    • Element-Plus
    • UniApp
  • 框架

    • Vue3
  • 拓展包

    • 包管理工具
    • 包开发
  • 开发语言

    • C语言
    • PHP
    • Phyton
  • 框架

    • Laravel
  • 会计

    • 初级经济法基础
    • 初级会计实务
  • 软考

    • 信息系统项目管理师
  • 博客

    • vitepress
    • vuepress
  • manim
  • git
  • vsCode
  • latex
  • docker
  • axios
  • vim
  • mac
  • Jetbrains

    • phpstorm
    • clion
突发奇想
GitHub (opens new window)
  • 入门指南
  • passport

    • 总结
      • 修改文件
        • 模型
        • 服务提供者
        • auth config
      • 自定义用户名字段
      • 自定义密码验证
      • 未授权 处理
      • 自定义 passport 路由
      • 单点登录
      • 解决跳转到 login
      • 登录后,获取当前用户token
      • bearerToken
    • 多守卫
    • 错误总结
  • 表单验证

  • 模型与迁移

  • 中间件
  • event and listen
  • trait
  • artisan 命令
  • laravel9
  • passport
诚城
2022-06-13
目录

总结原创

| 模式 | 优点 | 不足 | 使用场景 |
| :--------: | :---------------------: | :-----------: |
| 密码授权 | token有效期可以手动指定 | 无法切换guard | 只使用一个用户数据表进行认证,使用不同scope进行用户分组 |
| 个人访问端 | 也可以使用账号密码认证 | token不会过期 | 可以使用多个用户数据表进行认证 |

composer require laravel/passport # 安装拓展

php artisan passport:keys # 第一次部署时 生成新的密钥 

php artisan vendor:publish --tag=passport-migrations # 导出passport默认迁移文件,并做相应的修改
php artisan migrate # 数据库迁移

php artisan passport:install --uuids # 使用uuid

# 修改文件

# 模型

在执行 passport:install 命令后, 添加 Laravel\Passport\HasApiTokens trait 到你的 App\Models\User 模型中。 这个 trait 会提供一些帮助方法用于检查已认证用户的令牌和权限范围。如果您的模型已经在使用 Laravel\Sanctum\HasApiTokens trait,您可以删除该 trait:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;
}

# 服务提供者

接着你需要在 App\Providers\AuthServiceProvider 类的 boot 方法中调用 Passport::routes 方法。这个方法将注册一些必须的路由,用于发布或撤销访问令牌,操作客户端以及个人的访问令牌:

点击查看
<?php

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
use Laravel\Passport\Passport;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * 应用的策略映射。
     *
     * @var array
     */
    protected $policies = [
        'App\Models\Model' => 'App\Policies\ModelPolicy',
    ];

    /**
     * 注册鉴权/授权服务。
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        if (! $this->app->routesAreCached()) {
            Passport::routes();
            Passport::tokensExpireIn(now()->addDays(15)); // token有效期 addMinutes addHours
            Passport::refreshTokensExpireIn(now()->addDays(30)); // 刷新token 的有效期
            Passport::personalAccessTokensExpireIn(now()->addMonths(6));
        }
    }
}

# auth config

最后,在你应用的配置文件 config/auth.php 中, 将 api 的授权看守器 guards 的 driver 参数的值设置为 passport。此调整会让你的应用程序使用 Passport 的 TokenGuard 鉴权 API 接口请求:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

# 自定义用户名字段

在对应模型中修改,如 User 模型。

    /**
     * 查找给定用户名的用户实例。
     *
     * @param  string  $username
     * @return \App\Models\User
     */
    public function findForPassport($username)
    {
        switch ($username) {
            case filter_var($username, FILTER_VALIDATE_EMAIL): //判断账户是否是邮箱
                return $this->where('email', $username)->first();
                break;
            case preg_match_all('/^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|17[0-9]|18[0-9])\d{8}$/', $username) == 1: //验证是否是手机号号码
                return $this->where('phone', $username)->first();
                break;
            case preg_match_all('/^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/', $username) == 1: //验证是否是身份证号码
                return $this->where('card_id', $username)->first();
                break;
            default:
                return $this->where('user_name', $username)->first();
        }
    }

# 自定义密码验证

在对应模型中修改,如 User 模型。

    /**
     * 验证用户的密码以获得 Passport 密码授权。
     *
     * @param  string  $password
     * @return bool
     */
    public function validateForPassportPasswordGrant($password)
    {
        return Hash::check($password, $this->password);
    }

# 未授权 处理

文件app/Exceptions/Handler.php添加以下内容对 passport 授权失效坐判断。

点击查看
    protected function unauthenticated($request, AuthenticationException $exception)
    {
        return response()->json([
            'code'=> 401,
            'message'=> '未授权!'
        ],401);
    }

# 自定义 passport 路由

文件位置 vendor/laravel/passport/src/RouteRegistrar.php 注销对应的方法即可。

public function all()
{
    $this->forAuthorization();
    $this->forAccessTokens();
    $this->forTransientTokens();
    // $this->forClients();
    $this->forPersonalAccessTokens();
}

# 单点登录

使用事件和监听,在 Laravel 应用中的 EventServiceProvider 注册passport事件

protected $listen = [
    ……
    // 添加 passport 事件
    'Laravel\Passport\Events\AccessTokenCreated' => [
        'App\Listeners\RevokeOldTokens',
    ],
    'Laravel\Passport\Events\RefreshTokenCreated' => [
        'App\Listeners\PruneOldTokens',
    ],
];

在 App\Listeners\RevokeOldTokens 定义:

public function handle(AccessTokenCreated $event)
{
    DB::table('oauth_access_tokens')
        ->where('user_id',$event->userId)
        ->where('client_id',$event->clientId)
        ->where('id','<>',$event->tokenId)
        ->delete();
}

注意 DB 和 AccessTokenCreated 的引入。

# 解决跳转到 login

php artisan make:middleware Api/AcceptHeaderMiddleware

设置内容:

public function handle(Request $request, Closure $next)
{
    $request->headers->set('Accept', 'application/json');
    return $next($request);
}

其实就是请求头里增加 Accept:application/json

最后将该 中间件 添加到 app/Http/Kernel.php api 路由中间件组中。

protected $middlewareGroups = [
    'api' => [
        AcceptHeaderMiddleware::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

# 登录后,获取当前用户token

修改 过期时间

$token = auth()->user()->token(); //可以获取到当前用户的token
$token->expires_at = now()->addMinute(3); // ->addDays(15)
$token->save();

# bearerToken

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Lcobucci\JWT\Configuration;

class CheckApiTokenExpireInMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        // 获取请求头中的 token
        $bearerToken=$request->bearerToken();
        // passport ^10.4 从 bearerToken 获取token解析后的相关字段,如 jti
        // use Lcobucci\JWT\Configuration;
        $tokenId = Configuration::forUnsecuredSigner()->parser()->parse($bearerToken)->claims()->get('jti');
        $exp = Configuration::forUnsecuredSigner()->parser()->parse($bearerToken)->claims()->get('exp');
        $userId = Configuration::forUnsecuredSigner()->parser()->parse($bearerToken)->claims()->get('sub');
        $clientId = Configuration::forUnsecuredSigner()->parser()->parse($bearerToken)->claims()->get('aud');
        dd($tokenId,$exp,now(),$userId,$clientId);
        $psr = $this->server->validateAuthenticatedRequest($request->bearerToken());
//        dd($request->bearerToken());
        return $next($request);
    }
}

笔记

laravel/passport": "^8.0
使用:

use Lcobucci\JWT\Parser;

$bearerToken = request()->bearerToken();
$tokenId = (new Parser())->parse($bearerToken)->getClaim('jti');

上次更新: 2022/08/23, 18:12:45
入门指南
多守卫

← 入门指南 多守卫→

Theme by Vdoing | Copyright © 2022-2022 carveybunt | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×
×

特别申明:

本站所有内容均为个人理解或转载,如有不当之处,敬请大佬指导!