JWT 在项目中的实际使用
关于 JWT 可以参考 JWT 完整使用详解 这里说一下在实际项目中的使用:
laravel 5.5
php7.1
"tymon/jwt-auth": "1.*@rc"
JWT token
的刷新 和 基于 JWT 实现单用户登陆
TOKEN 的刷新#
理解#
用户登陆后 获取到 tokenA
(这个时候 tokenA
的有效期是 60 分钟)
通过 tokenA
获取到 tokenB
(这个时候 tokenB
的有效期是 60 分钟,tokenA
开始进行 60 秒的 倒计时,60 秒后就会被拉黑)
tokenB
换取 tokenC
(成功后 tokenB
开始进行 60 秒倒计时,60 秒后会被拉黑)
env
配置如下:#
JWT_SECRET=jbSn01PbHsFoRzEqHtuOsM3rV3FCsGcI
JWT_BLACKLIST_ENABLED=true # 是否开启toekn黑名单 生产环境需要开启 宽限时间需要开启黑名单(默认是开启的),黑名单保证过期token不可再用,最好打开
JWT_BLACKLIST_GRACE_PERIOD=60 # 设定宽限时间,单位:秒
JWT_REFRESH_TTL=20160 # 刷新时间 单位:分钟
JWT_TTL=60 # 有效时间 单位:分钟
单用户登陆#
基于 JWT token
的单用户登陆,在 token
的载荷配置中做一点手脚即可:
<?php
namespace App\Http\Controllers;
use Auth;
use App\Business\UserBusiness;
use App\Transformers\UserTransformer;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Facades\JWTFactory;
/**
* 用户相关
*
* @Resource("user", uri="/api")
*/
class UserController extends Controller
{
protected $userBusiness;
/**
* UserController constructor.
* @param UserBusiness $userBusiness
*/
public function __construct(UserBusiness $userBusiness)
{
$this->userBusiness = $userBusiness;
}
/**
* 用户登陆
*
* 使用 `username` 和 `password` 进行登陆。
*
* @Post("/login")
* @Versions({"v1"})
* @Transaction({
* @Request({"username": "foo", "password": "bar"}),
* @Response(200, body={"code":1,"time":"2018-08-10 09:32:44","message":"success","data":{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9hcGkuc21hcnR2aWRlby5jb21cL2FwaVwvbG9naW4iLCJpYXQiOjE1MzM4NjQ3NjQsImV4cCI6MTUzMzg2ODM2NCwibmJmIjoxNTMzODY0NzY0LCJqdGkiOiJsZTJObzRLVDZlT0NyVnZCIiwic3ViIjoiZGVkZjYyZTI5MDA0MTFlODgzM2I1NGVlNzVlNTM1MzciLCJwcnYiOiI4N2UwYWYxZWY5ZmQxNTgxMmZkZWM5NzE1M2ExNGUwYjA0NzU0NmFhIn0.OdJlE_pUuttqIxsjKF-FAcZOhMYitS69fh18lPZAYmQ","token_type":"bearer","expires_in":3600}}),
* @Response(200, body=
* {
* "message": "用户不存在",
* "code": 4000,
* "status_code": 500
* }
* )
*
* })
*/
public function login(Request $request)
{
$rules = [
'username' => 'required',
'password' => 'required'
];
$this->_validate($request, $rules);
$spbill_create_ip = $request->header('x-real-ip')?: $request->ip();
iLog('----------spbill_create_ip------------'. $spbill_create_ip);
$username = $request->username;
$password = $request->password;
$login_time = time();
$user = $this->userBusiness->dologin($username,$password,$spbill_create_ip,$login_time);
// Get the token
$factory = JWTFactory::customClaims([
'sub' => $user->guid,
'ip' => $spbill_create_ip,
'login_time' => $login_time
]);
$payload = $factory->make();
$token = JWTAuth::encode($payload);
return $this->_response($this->respondWithToken((string)$token));
}
protected function respondWithToken($token)
{
return [
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => JWTAuth::factory()->getTTL() * 60
];
}
}
<?php
namespace App\Http\Middleware;
use App\Business\ResponseException;
use App\Common\ResponseCode;
use Closure;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
class ClientCheck extends BaseMiddleware
{
/**
* @param $request
* @param Closure $next
* @return mixed
* @throws ResponseException
*/
public function handle($request, Closure $next)
{
$array = $this->auth->payload()->jsonSerialize();
$user = $this->auth->user();
if (key_exists('ip',$array) && key_exists('login_time',$array)) {
if ($array['ip'] != $user->ip || $array['login_time'] != $user->login_at) throw new ResponseException("该账户已在其他设备登陆",ResponseCode::OTHER_CLIENT_LOGIN);
}
return $next($request);
}
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: