token令牌生成和验证
<?php
/**
* 登录保持的token令牌
* 登录成功创建token令牌
* 后续用token令牌保持登陆
*/
namespace app\common\model;
use think\facade\Request;
class Token
{
#token文件前缀
private $fileName = "admin_token";
#token后台保存目录
private $fileCatalog = "share";
/**
* 生成用户的token,保持登陆
* @param $userid int 用户id
* @return $token string 用户token
*/
public function createToken( $id )
{
$id_rand = rand(10,99).$id.rand(0,9);
//设置token保存的文件目录
$token= MD5( $id.uniqid().rand( 00000000,99999999 ) ).'_'.$id_rand;
#获取token保存目录
$app_model = $this->fileCatalog;
#应用不同, token保存的目录就不同,方便万能使用
$file_dir = root_path()."public".DS."token".DS.$app_model.DS;
if( !file_exists( $file_dir ) )
{
mkdir($file_dir,0777,true);
}
$token_file_name =$file_dir.$this->fileName."_".$id;
$fh = fopen( $token_file_name,'w' );
#数据
$data['time'] = time();
$data['token'] = $token;
$data['id'] = $id;
$data['ip'] = Request::ip();
#写入
fwrite( $fh,serialize( $data ) );
fclose( $fh );
return $token;
}
/**
* 用户登陆验证,利用key获取管理员id
* 3天内有登陆再次更改为3天有效key
* @param $token string 管理员key
* @return [type] id 管理员id
*/
public function checkToken($token)
{
if( $token == FALSE )
{
returnJson( -1001, "token不存在,请重新登陆");
}
$max_time=86400 * 3; //3天过期时间,单位是秒
$id = getTokenId( $token ); //取到用户id
#获取token保存目录
$app_model = $this->fileCatalog;
$file_dir = root_path()."public".DS."token".DS.$app_model.DS;
$file =$file_dir.$this->fileName."_".$id;#//找到token文件
//token存在的情况
if( file_exists( $file ) )
{
$fh = @fopen($file,'r');
//反序列化出token文件数据,等到time,key,id,ip;
$f_code = unserialize(@fread($fh,filesize($file)));
@fclose($fh);
if($f_code['ip'] !== Request::ip())
{
returnJson( -1004, "登入IP异常,请重新登录");
}
if($f_code['time']+$max_time < time())
{
returnJson( -1002, "token过期,请重新登陆");
}else
{
//没有过期,过期时间重新计算,避免用户每3天登陆一次
$id = $f_code['id'];
$fh1 = fopen( $file,'w' );
#数据
$data['time'] = time();
$data['token'] = $token;
$data['id'] = $id;
$data['ip'] = Request::ip();
//重新写入当前时间,确保3天以内登陆的用户一直不需要重新登陆
fwrite( $fh1,serialize( $data ) );
fclose( $fh1 );
return $id;
}
}else
{
returnJson( -1003, "token异常,请重新登陆");
}
}
}