Laravel 中使用 JWT 作用户登录,身份认证

news2025/4/6 21:43:34

什么是JWT:

JWT 全名 JSON Web Token,是一种开放标准 (RFC 7519)。

用于在网络应用环境间安全地传输信息作为 JSON 对象。

它是一种轻量级的认证和授权机制,特别适合分布式系统的身份验证。

核心特点

  1. 紧凑格式:体积小,可通过URL、POST参数或HTTP头发送
  2. 自包含:包含所有必要信息,减少数据库查询
  3. 可验证:使用数字签名保证完整性
  4. 跨语言支持:几乎所有主流编程语言都有实现

JWT 的结构

由三部分组成,用点(.)分隔:

Header.Payload.Signature

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vZGV2LXNob3AtbWFuYWdlLWFwaS5ob21lLmtsZi5jb20vc2hvcC1hcGkvbG9naW4iLCJpYXQiOjE3NDM0MTM1NjcsImV4cCI6MTc0MzQxNzE2NywibmJmIjoxNzQzNDEzNTY3LCJqdGkiOiJUZjR1OENxRHB0dW9vTHZpIiwic3ViIjoiNDgwMyIsInBydiI6IjI3ZjQxNDY0MDE3YjAwZTE5MmIxNzUyNjMzNGJlNmI1ZGIwYTBkOTQifQ.5uRxjozQ89eK-zSPLF8aV2bKxWXpsJRgR5XmU9sCy3Q

工作流程

  1. 用户登录:客户端发送凭据到认证服务器
  2. 验证凭据:服务器验证后生成JWT
  3. 返回JWT:服务器将JWT返回给客户端
  4. 存储JWT:客户端存储JWT(通常localStorage或cookie)
  5. 携带JWT:客户端在请求头中发送JWT
Authorization: Bearer <token>
  1. 验证JWT:服务器验证JWT并授权访问

laravel 安装配置JWT

1.安装JWT包

composer require tymon/jwt-auth

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/e5df5c6f62ed41e5aee53e68f09e9c8e.png

2.发布 JWT 配置文件

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

在这里插入图片描述
此时会在config 目录下生成 jwt.php 配置文件

3. 生成密钥

php artisan jwt:secret

这会在 .env 文件中添加 JWT_SECRET,注意的是 生产环境单独生成,为了安全

用户登录配置

1.用户模型配置

创建用户模型文件,必须继承 Authenticatable ,实现 两个方法 getJWTIdentifiergetJWTCustomClaims,必须的。

<?php

namespace App\Models;

use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Foundation\Auth\User as Authenticatable;

class AdminUser extends Authenticatable implements JWTSubject
{
    // ... 其他代码
    
    /**
     * 获取JWT标识符
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * 获取JWT自定义声明
     */
    public function getJWTCustomClaims()
    {
        return [
            'role' => $this->role,  // 示例:添加用户角色到token
            // 可以添加更多自定义声明
        ];
    }
}

2.配置 auth.php

文件: config/auth.php

(2.1) 配置 Guard(守卫)

Guard 是 Laravel 认证系统的核心概念之一,它定义了:

  • 如何认证用户(使用什么驱动 driver)

    • session:传统的 web 应用认证方式(使用 cookies 和 session)

    • token:API 令牌认证(Laravel 自带的基础 token 认证)

    • jwt:使用 JWT 包提供的认证驱动

  • 从哪里获取用户信息(使用什么 provider

    • 指定使用哪个用户提供者(在 providers 数组中定义)

代码如下:

'guards' => [
    'web' => [
         'driver' => 'session',
         'provider' => 'users',
     ],
     //后台api守卫
     'admin-api' => [
         'driver' => 'jwt',  // 修改为 jwt 驱动
         'provider' => 'admin-user',  // 使用admin-user 作为 provider
     ],
 ],
  1. admin-api 是我定义的后台api的守卫
  2. driver驱动 设置JWT
  3. provider 用户提供者 用 admin-user
(2.2) 配置 providers (用户提供者)
'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\Models\User::class,
    ],
    'admin-user' => [
        'driver' => 'eloquent',
        'model' => AdminUser::class,
    ]
],
  1. admin-user 为前面引用的 用户提供者 名称
  2. driver 为 数据驱动
    • eloquent 驱动(最常用),使用 Eloquent ORM 从数据库获取用户
      • 使用 eloquent 驱动时,模型必须实现 Authenticatable 接口,具体看第一步
    • database 驱动,直接使用数据库查询构造器(非 Eloquent)
  3. model 为第一步定义的用户模型 AdminUser
(2.3) 配置 默认守卫
 'defaults' => [
        'guard' => 'admin-api',
        'passwords' => 'users',
    ],

passwords 配置项用于定义密码重置功能的相关设置。此文章不细说

3.登录控制器开发

login控制器有两种验证机制:

  1. 手动验证登录,auth 生成token【常用】
  2. 自动验证登录,生成token【注意密码】

手动验证登录

// 获取用户实例
$user = User::where('mobile', $request->mobile)->first();

// 手动验证密码
if (!Hash::check($request->password, $user->password)) {
    return response()->json(['error' => '密码错误'], 401);
}

// 生成Token的三种方式(任选其一)
// 方式1:直接通过用户实例生成
$token = JWTAuth::fromUser($user); 

// 方式2:使用auth辅助函数
$token = auth()->login($user); 

// 或者自定义claims
$token = JWTAuth::claims([
    'user_type' => $user->type,
    'exp' => now()->addDays(30)->timestamp // 自定义过期时间
])->fromUser($user); 

// 返回带Token的响应
return response()->json([
    'access_token' => $token,
    'token_type' => 'bearer',
    'user' => auth()->user(),
]);

上述就是登录验证 和 获取token 分离

  1. auth 为laravel的认证系统,使用默认守卫进行生成token
  2. auth()->user() 可获取到登录的用户信息

自动验证登录

// 验证输入
$validator = Validator::make($request->all(), [
     'mobile' => 'required|string|size:11', // 假设手机号是11位
     'password' => 'required|string|min:6',
 ]);

 if ($validator->fails()) {
     return response()->json([
         'status' => 'error',
         'message' => '参数验证失败',
         'errors' => $validator->errors()
     ], 422);
 }
 
// 使用手机号作为登录凭证
$credentials = $request->only('mobile', 'password');

$token = Auth::guard('admin-api')->attempt(['mobile' => $mobile, 'password' => $password, 'state' => 1]);
 if($token){
     $user = Auth::guard('admin-api')->user();
     return $this->success('登录成功', [
         'token' => $token,
         'user' => $user,
     ]);
 }else{
     return $this->error('您输入的账号或密码错误', 103);
 }

注意

使用 attempt 方法时,需要注意你的密码是否是用 Bcrypt 算法哈希,如果不是,则会有以下报错

This password does not use the Bcrypt algorithm.
在这里插入图片描述
原因Laravel 默认认证系统 Auth(包括 attempt() 方法)强制要求使用 Bcrypt 算法,只有Bcrypt 算法生成的密码,才能验证通过。

通过在 Hash Facade 上调用 make 方法来哈希密码

Hash::make($request->newPassword)

小结下:

  • 自动验证要求比较严格,但是也是有解决办法的。这里不过多说明,
  • 正常情况下。我是手动验证。然后生成token.。
  • 目前的遇到的验证,账号密码,手机号验证码等等。手动验证,灵活一点

4.前端构建请求

在这里插入图片描述

5.中间件补充

目录:app/Http/Middleware/UserCheckToken.php

<?php

namespace App\Http\Middleware;

use App\Http\Trait\ResponseJson;
use Closure;
use Tymon\JWTAuth\Facades\JWTAuth;

class UserCheckToken
{
    use ResponseJson;

    public function handle($request, Closure $next)
    {
        try{
            $user = auth()->user();
            if(!$user){
                return $this->error('用户未找到', 401);
            }
        }
        catch(\Exception $e){
            return $this->error('Token 验证失败', 401);
        }

        return $next($request);
    }

}

创建中间件 UserCheckToken

auth()->user() 的作用

  • 验证请求携带有效的 JWT Token(Authorization: Bearer xxx)
  • JWT 会自动解析 Token还原用户信息

注意:

  1. 同一次请求中多次调用 auth()->user() 不会重复查询数据库,第一次查询数据库,第二次返回内存缓存
  2. 缓存持续到当前 HTTP 请求结束下次请求会重新解析 Token。

6. 路由配置中间件

Route::middleware([UserCheckToken::class])->group(function(){
    Route::get('/test', [TestController::class, 'index']);
});

将需要验证登录信息的接口,放在此中间件下即可。

上述即完整的用Jwt 实现用户的登录。里面有很多的知识点都可以进行扩展,可以实现很多强大的,自定义的需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2328740.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VBA中类的解读及应用第二十二讲:利用类判断任意单元格的类型-5

《VBA中类的解读及应用》教程【10165646】是我推出的第五套教程&#xff0c;目前已经是第一版修订了。这套教程定位于最高级&#xff0c;是学完初级&#xff0c;中级后的教程。 类&#xff0c;是非常抽象的&#xff0c;更具研究的价值。随着我们学习、应用VBA的深入&#xff0…

STM32F103_LL库+寄存器学习笔记13 - 梳理外设CAN与如何发送CAN报文(串行发送)

导言 CAN总线因其高速稳定的数据传输与卓越抗干扰性能&#xff0c;在汽车、机器人及工业自动化中被广泛应用。它采用分布式网络结构&#xff0c;实现多节点间实时通信&#xff0c;确保各控制模块精准协同。在汽车领域&#xff0c;CAN总线连接发动机、制动、车身系统&#xff0c…

Linux系统调用编程

文章目录 一、进程和线程二、Linux的虚拟内存管理和stm32的真实物理内存**Linux虚拟内存管理**STM32物理内存映射2. 主要区别 三、Linux系统调用函数 fork()、wait()、exec()1. fork()&#xff1a;创建子进程2. wait()&#xff1a;等待子进程状态改变3. exec()&#xff1a;替换…

游戏引擎学习第203天

回顾当前情况 在这里我将直播完成整个游戏的制作。我们现在面临一些技术上的困难&#xff0c;确实如此。我的笔记本电脑的电源接口坏了&#xff0c;所以我不得不准备了这台备用笔记本&#xff0c;希望它能够正常工作。我所以希望一切都还好&#xff0c;尽管我不完全确定是否一…

深度学习数据集划分比例多少合适

在机器学习和深度学习中&#xff0c;测试集的划分比例需要根据数据量、任务类型和领域需求灵活调整。 1. 常规划分比例 通用场景 训练集 : 验证集 : 测试集 60% : 20% : 20% 适用于大多数中等规模数据集&#xff08;如数万到数十万样本&#xff09;&#xff0c;平衡了训练数…

CExercise_1_5 水仙花数

题目&#xff1a; 经典循环案例&#xff1a;请求出所有的水仙花数&#xff0c;并统计总共有几个。 所谓的水仙花数是指一个三位数&#xff0c;其各位数字的立方和等于该数本身。 举例&#xff1a;153就是一个水仙花数&#xff0c;153 1 * 1 * 1 5 * 5 * 5 3 * 3 * 3 1 125…

哈密尔顿路径(Hamiltonian Path)及相关算法题目

哈密尔顿路径要求访问图中每个顶点恰好一次&#xff0c;通常用于解决旅行商问题&#xff08;TSP&#xff09;或状态压缩DP问题。 哈密尔顿路径&#xff08;Hamiltonian Path&#xff09;是指在一个图中经过每个顶点恰好一次的路径。如果这条路径的起点和终点相同&#xff08;即…

MINIQMT学习课程Day10

开始获取股票数据课程的学习&#xff1a; 获取qmt账号的持仓情况后&#xff0c;我们进入下一步&#xff0c;如何获得当前账号的委托状况 还是之前的步骤&#xff0c;打开qmt&#xff0c;选择独立交易&#xff0c; 之后使用pycharm&#xff0c;编写py文件 导入包&#xff1a…

JAVA实战开源项目:智慧图书管理系统(Vue+SpringBoot) 附源码

本文项目编号 T 152 &#xff0c;文末自助获取源码 \color{red}{T152&#xff0c;文末自助获取源码} T152&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

Linux 系统管理综合实训 —— 基于 NAT 模式的多 IP 配置、Nginx 服务部署及存储管理

1. 虚拟机网络配置&#xff1a;NAT模式与多IP地址设置 将你的虚拟机的网卡模式设置为nat模式&#xff0c;给虚拟机网卡配置三个主机位分别为100、200、168的ip地址 设置静态IP [rootlocalhost ~]# nmcli c modify ens160 ipv4.method manual ipv4.addresses 192.168.2.100/2…

如何在windows 环境、且没有显卡的情况下用python跑通从ModelScope下载的大模型的调用

文章目录 背景介绍源代码&#xff1a;安装调试过程1.设置第三方镜像源2.预先安装&#xff1a;3.在python中创建代码&#xff1a;4.最终修改程序,将device_map从“cuda”改成“auto”&#xff0c;大模型调用1.5B&#xff08;1___5B)的5.最终跑出结果解释&#xff1a;示例&#x…

黑马点评redis改 part 1

本篇将主要阐述短信登录的相关知识&#xff0c;感谢黑马程序员开源&#xff0c;感谢提供初始源文件&#xff08;给到的是实战第7集开始的代码&#xff09;【Redis实战篇】黑马点评学习笔记&#xff08;16万字超详细、Redis实战项目学习必看、欢迎点赞⭐收藏&#xff09;-CSDN博…

【Ragflow】11. 文件解析流程分析/批量解析实现

概述 本文继续对ragflow文档解析部分进行分析&#xff0c;并通过脚本的方式实现对文件的批量上传解析。 文件解析流程 文件解析的请求处理流程大致如下&#xff1a; 1.前端上传文件&#xff0c;通过v1/document/run接口&#xff0c;发起文件解析请求 2.后端api\apps\docum…

第三期:深入理解 Spring Web MVC [特殊字符](数据传参+ 特殊字符处理 + 编码问题解析)

✨前言&#xff1a;传参和状态管理&#xff0c;看似简单其实门道不少 在 Web 开发中&#xff0c;前端和后端最核心的交流方式就是“传参”&#xff0c;而“传参”除了涉及如何写代码获取参数&#xff0c;还藏着很多开发者容易忽略的细节&#xff1a; 为什么 URL 带了中文&…

Everything 安装教程与使用教程(附安装包)

文章目录 前言一、Everything 介绍二、Everything 安装教程1.Everything 安装包下载2.选择安装文件3.选择安装语言4.接受许可协议5.选择安装位置6.配置安装选项7.完成安装 三、Everything 使用教程1.启动软件2.简单关键词搜索3.按类型搜索 前言 在日常使用电脑时&#xff0c;随…

SQL语句(三)—— DQL

目录 基本语法 一、基础查询 1、查询多个字段 2、字段设置别名 3、去除重复记录 4、示例代码 二、条件查询 1、语法 2、条件列表常用的运算符 3、示例代码 三、分组查询 &#xff08;一&#xff09;聚合函数 1、介绍 2、常见的聚合函数 3、语法 4、示例代码 &…

Opencv计算机视觉编程攻略-第九节 描述和匹配兴趣点

一般而言&#xff0c;如果一个物体在一幅图像中被检测到关键点&#xff0c;那么同一个物体在其他图像中也会检测到同一个关键点。图像匹配是关键点的常用功能之一&#xff0c;它的作用包括关联同一场景的两幅图像、检测图像中事物的发生地点等等。 1.局部模板匹配 凭单个像素就…

汇编学习之《push , pop指令》

学习本章前线了解ESP, EBP 指令 汇编学习之《指针寄存器&大小端学习》-CSDN博客 栈的特点&#xff1a; 好比一个垂直容器&#xff0c;可以陆续放入物体&#xff0c;但是先放的物体通常会被后面放的物体压着&#xff0c;只有等上面后放的物品拿出来后&#xff0c;才能…