本书未发布
3.3. 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('用户账号或密码错误',403);
}
//获取最后一次的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路由之后:
提交git
$ git add -A
$ git commit -m "JWT 实现单设备登录"