PHP & Laravel & 掌握 api 生成 token 的几种方式以及一些注意事项(坑)

介绍

本章略长,采用了 3 种创建 token 方式,读者可以选择任意一节阅读,但本人建议全部看完,掌握多种生成 token 方式何乐而不为呢。

准备工作

  1. 创建 Laravel 项目并命名为 example-app
composer create-project laravel/laravel example-app
cd example-app
php artisan serve

没有特殊情况的话可以看到项目已正常运行输出

Starting Laravel development server: http://127.0.0.1:8000
  1. 本章所使用的 php 版本是 7.3
  2. 本章所使用的 Laravel 版本是 8X ,Laravel 7X 没有试过。

1. 使用 Sanctrum

Laravel 默认采用 web session 认证机制,没有提供 api 认证,但最新版 Laravel 中内置了 santum,它是专门用来 api 认证生成 token 的扩展包,不过需要自己配置才能使用。

1.1 配置数据库

sanctum 对 token 的管理是在数据库中,我们还需要到 .env 环境变量文件里进行配置

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
# 填上你的数据库名、数据库用户、数据库密码
DB_DATABASE=product
DB_USERNAME=root
DB_PASSWORD=123456

1.2 安装 sanctum

1.2.1 下载 sanctum

提示:最新 Laravel 已经提前下载好 sanctum 我们可以在 compose.json 中查看,如果没有找到则可以使用下面命令下载

# 下载 sanctum
composer require laravel/sanctum
# 发布并更新配置
# 修改内容包括 migrage 、app/Models/User.php、以及 routes/api.php 
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
# 生成 sanctum 定义好的表
php artisan migrate

1.2.2 配置 config/auth.php

'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        // 新增 api 士兵
        'api' => [
            'driver' => 'sanctum',
            'provider' => 'users',
        ],
    ],

1.3 新增创建 token 接口

routes/api.php 代码如下

<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Models\User;
Route::post('/tokens/create', function (Request $request) {
   
   
    # 创建用户,这里写死作为案例。
    $user = User::create([
        'name' => 'cookcyq',
        'email' => '[email protected]',
        'password' => Hash::make('123457')
    ]);
    # 给 cookcyq 用户生成 token, $key 是秘钥,平时秘钥一定设置复杂点,这里仅作为案例。
    $key = 'hello';
    $token = $user->createToken($key);
    # 返回
    return ['token' => $token->plainTextToken];
});

接下来使用 postman 访问 http://localhost:8000/api/tokens/create
注意要带上 api 前缀
效果如图:
在这里插入图片描述
可以看到成功创建用户并返回 token,现在来看看users 表是存在此用户
在这里插入图片描述
再来看看 personal_access_tokens 表,这个表就是 sanctum 定义的,我们来看看是否存放用户对应的 token 相关字段信息
在这里插入图片描述
如图所示一切正常,你可能注意到 personal_access_tokens 表里的 token 内容与 postman 返回的token 不一致,这个无需担心,这是 sanctum 自己要处理的逻辑,我们只需拿接口返回的 token 去使用即可。

1.4 新增获取用户信息接口

拿到 token 后,我们开始新增用户信息接口来验证 token 是否对应上该用户。
routes/api.php 代码如下

// ...
// 以上省略

// 新增
Route::post('/getProfile', function (Request $request) {
   
   
	// 获取用户信息:sanctum 帮我们从数据库中寻找,它能寻找是因为我们已经在 auth.php 中配置好 provider:users 对应的 Elquent User 模型
    $user = $request->user();
    // 也可以用以下方式获取
    // $user = auth()->guard('api')->user();
    
    return response([
        'data' => $user
    ]);
})->middleware('auth:api');

现在拿刚才接口返回的 token 去访问http://localhost:8000/api/getProfile
sanctum 是采用 Bearer Token 形式,需要带上 Bearer 前缀,header 请求格式如下:
Authorization: Bearer 1|Vjq5FOkhnwX6laVxNLE2YAEZTrMopmQeHtC4KyA2

访问效果图:
在这里插入图片描述
可以看到根据 token 可以返回对应的用户信息,现在我们用无效的 token 试试
注意:在使用前,确保 postman 里的 header 设置为 Accept:application/json
否则会报如下错误:Route[login] not defined.
在这里插入图片描述
这个报错是因为 Laravel 默认情况下会对 Access 做出相应的认证判断,由于 postman header 默认设置为 Access: * ,而 Laravel 默认的授权认证是采用 web session 机制,所以未授权的用户都会重定向到 login 页面,触发逻辑代码可在 app/http/Middleware/Authenticate.php 中看到

class Authenticate extends Middleware
{
   
   
    /**
     * Get the path the user should be redirected to when they are not authenticated.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return string|null
     */
    protected function redirectTo($request)
    {
   
   
        if (! $request->expectsJson()) {
   
   
            return route('login');
        }
    }
}

由于我们是针对 api 不是 web ,不需要重定向,这里可以重写一下逻辑。

class Authenticate extends Middleware
{
   
   
    /**
     * Get the path the user should be redirected to when they are not authenticated.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return string|null
     */
    protected function redirectTo($request)
    {
   
   
        if (! $request->expectsJson()) {
   
   
            // 换成这句
            return response([
				'msg' => '请登录',
				'code' => -10000
			]);
        }
    <
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cookcyq

请作者喝杯暖暖的奶茶

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值