Skip to content

Instantly share code, notes, and snippets.

@GithubMrxia
Last active March 26, 2020 06:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GithubMrxia/a48dd62d4dcec29273d43904482515e4 to your computer and use it in GitHub Desktop.
Save GithubMrxia/a48dd62d4dcec29273d43904482515e4 to your computer and use it in GitHub Desktop.
Auth.php
<?php
namespace App\Libs\Auth;
use App\Libs\Auth\Jwt;
use App\Libs\RedisLib;
class Auth
{
// 验证成功
const SUCCESS = 'RC00000';
// 验证失败
const FAIL = 'RC00001';
/**
* 获取token
*
* @param string $userNo
* @param array $data 有效数据
* @return string
*/
public static function getToken(string $userNo, array $data)
{
$obj = self::getObj();
$data = self::getData($data);
$token = $obj->getToken($data);
$key = self::getKey($userNo);
$exp = self::getExp();
if ($exp) {
RedisLib::set($key, $token, $exp);
} else {
RedisLib::set($key, $token);
}
return $token;
}
/**
* 验证token
*
* @param string $token
* @return array
*/
public static function verify(string $token)
{
$obj = self::getObj();
$data = $obj->verify($token);
if (! $data) {
return self::response(self::FAIL, 'token无效');
}
if (! isset($data['iat']) || $data['iat'] > time()) {
return self::response(self::FAIL, '签发时间错误');
}
// if (! isset($data['exp']) || $data['exp'] < time()) {
// return self::response(self::FAIL, '已过期');
// }
if (! isset($data['data'])) {
return self::response(self::FAIL, '无有效数据');
}
$key = self::getKey($data['data']['user_no']);
$redisToken = RedisLib::get($key);
if (empty($redisToken)) {
return self::response(self::FAIL, '登陆已过期');
}
if ($redisToken != $token) {
return self::response(self::FAIL, '此账户已在其他地方登陆,请重新登陆');
}
$exp = self::getExp();
if ($exp) {
RedisLib::expire($key, $exp);
}
return self::response(self::SUCCESS, '成功', $data['data']);
}
/**
* 响应
*
* @param string $code
* @param string $msg
* @param array $data
* @return array
*/
protected static function response(string $code, string $msg, array $data = [])
{
return [
'code' => $code,
'msg' => $msg,
'data' => $data
];
}
/**
* 获取数据
*
* @param array $data
* @return array
*/
protected static function getData(array $data)
{
$exp = self::getExp();
return [
'iat' => time(),
'exp' => time() + $exp,
'data' => $data
];
}
/**
* 获取token过期时间
*
* @return int
*/
protected static function getExp()
{
return (int)config('auth.expire_time');
}
/**
* 获取obj
*
* @return obj
*/
protected static function getObj()
{
$secret = config('auth.secret');
return new Jwt('HS512', $secret);
}
/**
* 获取key
*
* @param string $userNo
* @return string
*/
protected static function getKey(string $userNo)
{
return 'user:token:'.$userNo;
}
}
<?php
namespace App\Libs\Auth;
class Jwt
{
// 加密算法
protected $alg;
// 密钥
protected $secret;
protected $algs = [
'HS256' => 'sha256',
'HS512' => 'sha512',
];
/**
* init
*
* @param string $alg
* @param string $secret
*/
public function __construct($alg = 'HS256',$secret = ')^$@^%')
{
$this->alg = $alg;
$this->secret = $secret;
}
/**
* 获取header
*
* @return array
*/
protected function getHeader()
{
return [
'typ' => 'JWT',
'alg' => $this->alg,
];
}
/**
* 获取token
*
* @param array $payload
* @return string
*/
public function getToken(array $payload)
{
$header = $this->getHeader();
$str = $this->base64UrlEncode(json_encode($header)) . '.' . $this->base64UrlEncode(json_encode($payload));
return $str . '.' . $this->signature($str);
}
/**
* 编码
*
* @param string $str
* @return string
*/
public function base64UrlEncode(string $str)
{
return str_replace('=', '', strtr(base64_encode($str), '+/', '-_'));
}
/**
* 解码
*
* @param string $str
* @return string
*/
public function base64UrlDecode(string $str)
{
$remainder = strlen($str) % 4;
if ($remainder) {
$addlen = 4 - $remainder;
$str .= str_repeat('=', $addlen);
}
return json_decode(base64_decode(strtr($str, '-_', '+/')), true);
}
/**
* 签名
*
* @param string $str
* @return string
*/
public function signature(string $str)
{
$algo = $this->algs[$this->alg];
return $this->base64UrlEncode(hash_hmac($algo, $str, $this->secret, true));
}
/**
* 验证token
*
* @param string $token
* @return void
*/
public function verify(string $token)
{
$arr = explode('.', $token);
if (count($arr) != 3) {
return false;
}
$header = $arr[0];
$payload = $arr[1];
$signature = $arr[2];
$str = $header . '.' . $payload;
if ($this->signature($str) != $signature) {
return false;
}
return $this->base64UrlDecode($payload);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment