2.2. JWT 实现单设备登录

未匹配的标注

前言

在日常开发中,我们大部分项目都会用到单设备登录,即在同一时间内只允许单个设备登陆。

在下面我将以一种比较简单且容易理解的方式来实现这个需求。

实现思路

在保证前面内容不变的情况下,将用户最后一次登录的token储存到数据表的一个字段中,每次登录验证通过的时候,将上一个token加入“黑名单”,从而实现单设备登录。

JWT 中实现单设备登录

切换jwt_dev分支:

$ git checkout jwt_dev

user迁移文件添加字段:

$table->text('last_token');

修改controller相关代码,并添加一个测试方法userInfo

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\AuthorizationRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;

class AuthorizationsController extends Controller
{
    /**
     * @param AuthorizationRequest $request
     * @return array|string[]
     */
    public function login(AuthorizationRequest $request){
        $username = $request->username;

        //php7.0新东西,FILTER_VALIDATE_EMAIL为php自带的email过滤器
        filter_var($username, FILTER_VALIDATE_EMAIL) ?
            $credentials['email'] = $username :
            $credentials['phone'] = $username;

        //接收传来的值
        $credentials['password']=$request->password;

        //验证密码是否正确
        if (!$token = \Auth::guard('api')->attempt($credentials)) {
            abort('用户账号或密码错误',401);
        }
        //获取最后一次的token并加入黑名单
        $user=\Auth::guard('api')->user();
        if ($user->last_token) {
            try{
                \JWTAuth::setToken($user->last_token)->invalidate();
            }catch (TokenExpiredException $e){
                //因为让一个过期的token再失效,会抛出异常,所以我们捕捉异常,不需要做任何处理
            }
        }
        $user->last_token = $token;
        $user->save();

        return response()->json([
            'access_token' => $token,
            'token_type' => 'Bearer',
            'expires_in' => \Auth::guard('api')->factory()->getTTL() * 60
        ])->setStatusCode(201);
    }

    //测试方法
    public function userInfo(){
        return 1;
    }
}

测试

单点登录
重新请求login路由之后:

单点登录

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
lochpure
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
贡献者:1
讨论数量: 0
发起讨论 只看当前版本


暂无话题~