黑狐家游戏

laravel jwt auth,laravel jwt单设备登录

欧气 3 0

标题:实现 Laravel JWT 单设备登录的全面指南

在当今的 Web 应用开发中,用户身份验证是至关重要的一环,为了提供更安全和高效的登录体验,许多开发者选择使用 JSON Web Token(JWT)来管理用户身份,本文将详细介绍如何在 Laravel 框架中实现 JWT 单设备登录,并提供代码示例和详细的解释。

一、JWT 简介

JWT 是一种用于在网络应用中表示用户身份的开放标准,它将用户的身份信息编码在一个紧凑的 JSON 对象中,并使用数字签名进行验证,JWT 具有以下优点:

1、轻量级:JWT 是基于 JSON 的,易于传输和解析。

2、安全:JWT 使用数字签名来验证签名的完整性和真实性,防止数据被篡改。

3、可扩展性:JWT 可以包含任意的用户信息,并且可以根据需要进行扩展。

4、无状态:JWT 不依赖于服务器的会话状态,因此可以在分布式系统中使用。

二、Laravel JWT 安装

在 Laravel 中使用 JWT,我们需要安装tymon/jwt-auth 包,可以通过 Composer 进行安装:

composer require tymon/jwt-auth

安装完成后,需要在config/app.php 文件中注册服务提供者和别名:

'providers' => [
    // 其他服务提供者
    Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class,
],
'aliases' => [
    // 其他别名
    'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
    'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
],

三、创建用户模型

我们需要创建一个用户模型来存储用户的信息,在app/User.php 文件中,添加以下代码:

<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
    use Notifiable;
    protected $table = 'users';
    protected $fillable = [
        'name', 'email', 'password',
    ];
    protected $hidden = [
        'password', 'remember_token',
    ];
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }
    public function getJWTCustomClaims()
    {
        return [];
    }
}

在上述代码中,我们定义了一个用户模型,并实现了getJWTIdentifiergetJWTCustomClaims 方法。getJWTIdentifier 方法用于返回用户模型的唯一标识,通常是用户的 ID。getJWTCustomClaims 方法用于返回自定义的 JWT 声明,可以根据需要添加用户的其他信息。

四、创建 JWT 控制器

我们需要创建一个 JWT 控制器来处理 JWT 的生成和验证,在app/Http/Controllers/AuthController.php 文件中,添加以下代码:

<?php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
class AuthController extends Controller
{
    public function login(Request $request)
    {
        $credentials = $request->only('email', 'password');
        try {
            if (!$token = JWTAuth::attempt($credentials)) {
                return response()->json(['error' => 'invalid_credentials'], 401);
            }
        } catch (JWTException $e) {
            return response()->json(['error' => 'could_not_create_token'], 500);
        }
        return $this->respondWithToken($token);
    }
    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => JWTAuth::factory()->getTTL() * 60
        ]);
    }
}

在上述代码中,我们定义了一个login 方法来处理用户登录请求,该方法接收用户的邮箱和密码作为参数,并使用JWTAuth::attempt 方法尝试验证用户的凭证,如果验证成功,将生成一个 JWT 并返回给客户端,如果验证失败,将返回一个包含错误信息的响应。

五、实现单设备登录

为了实现单设备登录,我们需要在用户登录成功后,将用户的设备信息存储在 JWT 中,可以在App\User 模型中添加一个last_login_device 字段来存储用户的最后登录设备信息:

<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
    use Notifiable;
    protected $table = 'users';
    protected $fillable = [
        'name', 'email', 'password', 'last_login_device',
    ];
    protected $hidden = [
        'password', 'remember_token',
    ];
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }
    public function getJWTCustomClaims()
    {
        return [
            'last_login_device' => $this->last_login_device,
        ];
    }
}

在上述代码中,我们在getJWTCustomClaims 方法中添加了一个last_login_device 字段,用于存储用户的最后登录设备信息。

在 JWT 控制器中,我们需要在生成 JWT 时,将用户的设备信息添加到 JWT 中:

<?php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
class AuthController extends Controller
{
    public function login(Request $request)
    {
        $credentials = $request->only('email', 'password');
        try {
            if (!$token = JWTAuth::attempt($credentials)) {
                return response()->json(['error' => 'invalid_credentials'], 401);
            }
        } catch (JWTException $e) {
            return response()->json(['error' => 'could_not_create_token'], 500);
        }
        // 获取用户的设备信息
        $device = $request->header('User-Agent');
        // 更新用户的最后登录设备信息
        User::find(JWTAuth::parseToken()->getPayload()->get('sub'))->update(['last_login_device' => $device]);
        return $this->respondWithToken($token);
    }
    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => JWTAuth::factory()->getTTL() * 60
        ]);
    }
}

在上述代码中,我们在login 方法中获取了用户的设备信息,并使用update 方法更新了用户的最后登录设备信息。

六、验证 JWT

为了验证 JWT 的有效性,我们可以在需要验证用户身份的地方调用JWTAuth::parseToken()->authenticate() 方法,JWT 有效,将返回用户模型实例,JWT 无效,将抛出Tymon\JWTAuth\Exceptions\TokenInvalidException 异常。

以下是一个示例,演示如何在控制器中验证 JWT:

<?php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
class UserController extends Controller
{
    public function show(Request $request)
    {
        try {
            $user = JWTAuth::parseToken()->authenticate();
            return response()->json($user);
        } catch (TokenInvalidException $e) {
            return response()->json(['error' => 'token_invalid'], 401);
        } catch (TokenExpiredException $e) {
            return response()->json(['error' => 'token_expired'], 401);
        } catch (\Exception $e) {
            return response()->json(['error' => 'token_absent'], 401);
        }
    }
}

在上述代码中,我们在show 方法中调用了JWTAuth::parseToken()->authenticate() 方法来验证 JWT 的有效性,JWT 有效,将返回用户模型实例,并返回用户信息,JWT 无效,将抛出相应的异常,并返回相应的错误信息。

七、总结

我们介绍了如何在 Laravel 框架中实现 JWT 单设备登录,通过使用tymon/jwt-auth 包,我们可以轻松地实现 JWT 的生成、验证和存储用户设备信息,这样可以提供更安全和高效的登录体验,同时也可以防止用户在多个设备上同时登录。

标签: #jwt #单设备登录

黑狐家游戏
  • 评论列表

留言评论