XF_Index/Class/Token.php

123 lines
5.0 KiB
PHP
Raw Normal View History

2023-05-02 10:30:55 +08:00
<?php
/*
* Copyright © 2016 - 2023 筱锋xiao_lfeng. All Rights Reserved.
* 开发开源遵循 MIT 许可,若需商用请联系开发者
* https://www.x-lf.com/
*/
class Token
{
/** @var int|null Token生成长度 */
public int $Data_TokenLong;
/** @var string 生成的Token或获取的Token */
public ?string $Data_Token = null;
/** @var bool 检查是否是Token创建模式 */
public bool $Data_TokenCreate;
/**
* @param int|null $Token_Long 获取Token计算长度
* @param bool $Token_Create 是否为 Token 创建模式
*/
public function __construct(int $Token_Long, bool $Token_Create)
{
$this->Data_TokenLong = $Token_Long;
$this->Data_TokenCreate = $Token_Create;
}
/**
* 获取一个新的 Token
* 说明:
*
* 1. Token长度说明
* - 在Token长度小于5时判断Token为错误类型不允许生成Token过于简单
* - 在Token长度大于等于5小于等于20时判断Token随机生成16进制随机数若要进行判断请使用SESSION或COKKIE进行自行编译判断
* - 在Token长度大于20不大于等于40时创建带时间Token进行判断可直接使用类中 examineToken 函数进行判断是否正确请注意依旧需要使用COOKIE进行存储Token
* @return string Token检查错误返回对应错误代码当Token正确生成输出结果为Token:xxx
*/
public function getToken(): string
{
$this->Data_Token = null;
// 令牌合法化检测
if ($this->checkToken() == "SUCCESS") {
// Token设计
if ($this->Data_TokenLong <= 20) {
for ($CC_i = 0; $CC_i < $this->Data_TokenLong; $CC_i++) {
$Data_RandNumber = dechex(rand(0,15));
$this->Data_Token .= $Data_RandNumber;
}
} else if ($this->Data_Token <= 40) {
for ($CC_i = 0; $CC_i < 5 ; $CC_i++) {
$Data_RandNumber = dechex(rand(0,15));
$this->Data_Token .= $Data_RandNumber;
}
$this->Data_Token .= (int)hexdec($this->Data_Token)%7;
$this->Data_Token .= (int)hexdec($this->Data_Token)%2;
$this->Data_Token .= date("ymdHi");
$this->Data_Token .= (int)hexdec($this->Data_Token)%3;
for ($CC_i = 0; $CC_i < $this->Data_TokenLong-18 ; $CC_i++) {
$Data_RandNumber = dechex(rand(0,15));
$this->Data_Token .= $Data_RandNumber;
}
}
// 结果输出
return "Token:" . $this->Data_Token;
} else
return $this->checkToken();
}
/**
* 令牌合法化检测令牌检测需要必须大于5位数否则视为违法令牌
* 返回值:
*
* - TokenTooShort [令牌太短]
* - TokenTooLong [令牌太长]
* - NotAvailable [非令牌获取模式]
* @return string 返回上述结果
*/
private function checkToken(): string
{
if (!$this->Data_TokenCreate)
return "NotAvailable";
if ($this->Data_TokenLong < 5)
return "TokenTooShort";
else if ($this->Data_TokenLong > 40)
return "TokenTooLong";
return "SUCCESS";
}
/**
* Token检查是否合法
* 说明:
*
* 1. Token长度说明
* - Token长度在小于5为过短非正常Token
* - Token长度在大于等于5小于等于20为输出随机16进制数字此情况中此函数不予检测请自行构建
* - Token长度在大于20小于等于40为输出带时间Token可直接使用此函数进行判断合法Token并且通过验证返回SUCCESS
* - Token长度大于40为非法Token
* 2. 返回结果说明
* - SUCCESS [验证通过]
* - FAIL [检查不通过]
* - NotAvailable [不支持此数据也就是说你的Token长度为大于等于5小于等于20的情况下]
* - TimeFail [验证超时]
* @param string $Token Token检查输入Token记录值计算Token是否合法
* @return string 如果检查通过输出SUCCESS错误输出有多种
*/
public function examineToken(string $Token,int $Token_ExpDate): string
{
$this->Data_Token = $Token;
// Token正规化检查
if ($this->Data_TokenLong >= 5 && $this->Data_TokenLong <= 20)
return "NotAvailable";
else if ($this->Data_TokenLong <= 40) {
if (hexdec(substr($this->Data_Token,1,5))%7 != substr($this->Data_Token,6,1))
return "FAIL";
if (hexdec(substr($this->Data_Token,1,6))%2 != substr($this->Data_Token,7,1))
return "FAIL";
if (strtotime(substr($this->Data_Token,8,10))+$Token_ExpDate <= time())
return "TimeFail";
if (hexdec(substr($this->Data_Token,1,17))%3 == substr($this->Data_Token,18,1))
return "FAIL";
}
return "SUCCESS";
}
}