new file: firebase-jwt-test/api.php

new file:   firebase-jwt-test/autoload.php
	new file:   firebase-jwt-test/jwt/JWT.php
	new file:   firebase-jwt-test/jwt/JWTException.php
	new file:   firebase-jwt-test/king/Tools.php
	new file:   firebase-jwt-test/token.svg
	new file:   firebase-jwt-test/token流程说明.md
	new file:   firebase-jwt-test/接口文档.md
master
fengyuexingzi 8 years ago
parent ba9b21fe9a
commit f6d50105e2

@ -0,0 +1,63 @@
<?php
/**
* Created by PhpStorm.
* User: Wind
* Date: 2017/10/31
* Time: 10:24
*/
require_once './extend/autoload.php';
require '/common.inc.php';
require DT_ROOT . '/include/post.func.php';
$gets = array(
'login'
);
$posts = array(
'login'
);
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
if (in_array($action, $gets)) {
echo 'get';
a_login('15612341234', '123456');
} else {
die('40001');
}
} elseif ($_SERVER['REQUEST_METHOD'] == 'POST') {
echo 'post';
} else {
'ajax';
}
function a_login($username, $password)
{
$username = trim($username);
$password = trim($password);
if (strlen($username) < 3) {
message('login_msg_username');
}
if (strlen($password) < 5) {
message('login_msg_password');
}
if (is_email($username)) {
die('email');
}
error_reporting(E_ALL);
$resultUser = $GLOBALS['db']->query("SELECT `username`,`passport`,`password`,`passsalt` FROM {$GLOBALS['DT_PRE']}member WHERE '$username' IN (`username`,`mobile`,`email`)");
if (mysql_num_rows($resultUser) > 0) {
while ($user = mysql_fetch_assoc($resultUser)) {
if ($user['password'] == dpassword($password, $user['passsalt'])) {
var_dump($user['password']);
echo 'find';
} else {
continue;
}
}
}
$GLOBALS['db']->query("UPDATE {$GLOBALS['DT_PRE']}_memeber SET loginip='{$GLOBALS['DT_IP']}',logintime={$GLOBALS['DT_TIME']},logintimes=logintimes+1 WHERE userid={$user['userid']}");
return $user;
}

@ -0,0 +1,16 @@
<?php
/**
* Created by PhpStorm.
* User: Wind
* Date: 2017/11/2
* Time: 11:24
*/
function autoLoad($class)
{
if (file_exists(__DIR__ . '/' . $class . '.php')) {
include __DIR__ . '/' . $class . '.php';
}
}
spl_autoload_register("autoLoad");

@ -0,0 +1,394 @@
<?php
namespace JWT;
use DateTime;
use DomainException;
use InvalidArgumentException;
use UnexpectedValueException;
class JWT
{
/**
* When checking nbf, iat or expiration times,
* we want to provide some extra leeway time to
* account for clock skew.
*/
public static $leeway = 0;
/**
* Allow the current timestamp to be specified.
* Useful for fixing a value within unit testing.
*
* Will default to PHP time() value if null.
*/
public static $timestamp = null;
public static $supported_algs = [
'HS256' => ['hash_hmac', 'SHA256'],
'HS512' => ['hash_hmac', 'SHA512'],
'HS384' => ['hash_hmac', 'SHA384'],
'RS256' => ['openssl', 'SHA256'],
'RS384' => ['openssl', 'SHA384'],
'RS512' => ['openssl', 'SHA512'],
];
/**
* Decodes a JWT string into a PHP object.
*
* @param string $jwt The JWT
* @param string|array $key The key, or map of keys.
* If the algorithm used is asymmetric, this is the public key
* @param array $allowed_algs List of supported verification algorithms
* Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
*
* @return object The JWT's payload as a PHP object
*
*
* @uses jsonDecode
* @uses urlsafeB64Decode
*/
public static function decode($jwt, $key, array $allowed_algs = array())
{
$timestamp = is_null(static::$timestamp) ? time() : static::$timestamp;
if (empty($key)) {
throw new InvalidArgumentException('Key may not be empty');
}
$tks = explode('.', $jwt);
if (count($tks) != 3) {
return [
"code" => '50001',
"message" => 'wrong token style',
//"data" => []
];
}
list($headb64, $bodyb64, $cryptob64) = $tks;
if (null === ($header = static::jsonDecode(static::urlsafeB64Decode($headb64)))) {
return [
"code" => '50001',
"message" => 'wrong header encoding',
//"data" => []
];
}
if (null === $payload = static::jsonDecode(static::urlsafeB64Decode($bodyb64))) {
return [
"code" => '50001',
"message" => 'wrong payload encoding',
//"data" => []
];
}
if (false === ($sig = static::urlsafeB64Decode($cryptob64))) {
return [
"code" => '50001',
"message" => 'wrong signature encoding',
//"data" => []
];
}
if (empty($header->alg)) {
return ["code" => '50001',
"message" => 'Empty algorithm',
//"data" => []
];
}
if (empty(static::$supported_algs[$header->alg])) {
return ["code" => '50001',
"message" => 'Algorithm not supported',
//"data" => []
];
}
if (!in_array($header->alg, $allowed_algs)) {
return ["code" => '50001',
"message" => 'Algorithm not allowed',
//"data" => []
];
}
if (is_array($key) || $key instanceof \ArrayAccess) {
if (isset($header->kid)) {
if (!isset($key[$header->kid])) {
throw new UnexpectedValueException('"kid" invalid, unable to lookup correct key');
}
$key = $key[$header->kid];
} else {
throw new UnexpectedValueException('"kid" empty, unable to lookup correct key');
}
}
// Check the signature
if (!static::verify("$headb64.$bodyb64", $sig, $key, $header->alg)) {
return ["code" => '50001',
"message" => 'Signature verification failed',
//"data" => []
];
}
// Check if the nbf if it is defined. This is the time that the
// token can actually be used. If it's not yet that time, abort.
if (isset($payload->nbf) && $payload->nbf > ($timestamp + static::$leeway)) {
throw new BeforeValidException(
'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf)
);
}
// Check that this token has been created before 'now'. This prevents
// using tokens that have been created for later use (and haven't
// correctly used the nbf claim).
if (isset($payload->iat) && $payload->iat > ($timestamp + static::$leeway)) {
throw new BeforeValidException(
'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat)
);
}
// Check if this token has expired.
if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) {
return [
"code" => '40005',
"msg" => 'Expired token',
//"data" => []
];
}
return $payload;
}
/**
* Converts and signs a PHP object or array into a JWT string.
*
* @param object|array $payload PHP object or array
* @param string $key The secret key.
* If the algorithm used is asymmetric, this is the private key
* @param string $alg The signing algorithm.
* Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
* @param mixed $keyId
* @param array $head An array with header elements to attach
*
* @return string A signed JWT
*
* @uses jsonEncode
* @uses urlsafeB64Encode
*/
public static function encode($payload, $key, $alg = 'HS256', $keyId = null, $head = null)
{
$header = array('typ' => 'JWT', 'alg' => $alg);
if ($keyId !== null) {
$header['kid'] = $keyId;
}
if (isset($head) && is_array($head)) {
$header = array_merge($head, $header);
}
$segments = array();
$segments[] = static::urlsafeB64Encode(static::jsonEncode($header));
$segments[] = static::urlsafeB64Encode(static::jsonEncode($payload));
$signing_input = implode('.', $segments);
$signature = static::sign($signing_input, $key, $alg);
$segments[] = static::urlsafeB64Encode($signature);
return implode('.', $segments);
}
/**
* Sign a string with a given key and algorithm.
*
* @param string $msg The message to sign
* @param string|resource $key The secret key
* @param string $alg The signing algorithm.
* Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
*
* @return string An encrypted message
*
* @throws DomainException Unsupported algorithm was specified
*/
public static function sign($msg, $key, $alg = 'HS256')
{
if (empty(static::$supported_algs[$alg])) {
throw new DomainException('Algorithm not supported');
}
list($function, $algorithm) = static::$supported_algs[$alg];
switch ($function) {
case 'hash_hmac':
return hash_hmac($algorithm, $msg, $key, true);
case 'openssl':
$signature = '';
$success = openssl_sign($msg, $signature, $key, $algorithm);
if (!$success) {
throw new DomainException("OpenSSL unable to sign data");
} else {
return $signature;
}
}
}
/**
* Verify a signature with the message, key and method. Not all methods
* are symmetric, so we must have a separate verify and sign method.
*
* @param string $msg The original message (header and body)
* @param string $signature The original signature
* @param string|resource $key For HS*, a string key works. for RS*, must be a resource of an openssl public key
* @param string $alg The algorithm
*
* @return bool
*
* @throws DomainException Invalid Algorithm or OpenSSL failure
*/
private static function verify($msg, $signature, $key, $alg)
{
if (empty(static::$supported_algs[$alg])) {
throw new DomainException('Algorithm not supported');
}
list($function, $algorithm) = static::$supported_algs[$alg];
switch ($function) {
case 'openssl':
$success = openssl_verify($msg, $signature, $key, $algorithm);
if ($success === 1) {
return true;
} elseif ($success === 0) {
return false;
}
// returns 1 on success, 0 on failure, -1 on error.
throw new DomainException(
'OpenSSL error: ' . openssl_error_string()
);
case 'hash_hmac':
default:
$hash = hash_hmac($algorithm, $msg, $key, true);
if (function_exists('hash_equals')) {
return hash_equals($signature, $hash);
}
$len = min(static::safeStrlen($signature), static::safeStrlen($hash));
$status = 0;
for ($i = 0; $i < $len; $i++) {
$status |= (ord($signature[$i]) ^ ord($hash[$i]));
}
$status |= (static::safeStrlen($signature) ^ static::safeStrlen($hash));
return ($status === 0);
}
}
/**
* Decode a JSON string into a PHP object.
*
* @param string $input JSON string
*
* @return object Object representation of JSON string
*
* @throws DomainException Provided string was invalid JSON
*/
public static function jsonDecode($input)
{
if (version_compare(PHP_VERSION, '5.4.0', '>=') && !(defined('JSON_C_VERSION') && PHP_INT_SIZE > 4)) {
/** In PHP >=5.4.0, json_decode() accepts an options parameter, that allows you
* to specify that large ints (like Steam Transaction IDs) should be treated as
* strings, rather than the PHP default behaviour of converting them to floats.
*/
$obj = json_decode($input, false, 512, JSON_BIGINT_AS_STRING);
} else {
/** Not all servers will support that, however, so for older versions we must
* manually detect large ints in the JSON string and quote them (thus converting
*them to strings) before decoding, hence the preg_replace() call.
*/
$max_int_length = strlen((string)PHP_INT_MAX) - 1;
$json_without_bigints = preg_replace('/:\s*(-?\d{' . $max_int_length . ',})/', ': "$1"', $input);
$obj = json_decode($json_without_bigints);
}
if (function_exists('json_last_error') && $errno = json_last_error()) {
static::handleJsonError($errno);
} elseif ($obj === null && $input !== 'null') {
throw new DomainException('Null result with non-null input');
}
return $obj;
}
/**
* Encode a PHP object into a JSON string.
*
* @param object|array $input A PHP object or array
*
* @return string JSON representation of the PHP object or array
*
* @throws DomainException Provided object could not be encoded to valid JSON
*/
public static function jsonEncode($input)
{
$json = json_encode($input);
if (function_exists('json_last_error') && $errno = json_last_error()) {
static::handleJsonError($errno);
} elseif ($json === 'null' && $input !== null) {
throw new DomainException('Null result with non-null input');
}
return $json;
}
/**
* Decode a string with URL-safe Base64.
*
* @param string $input A Base64 encoded string
*
* @return string A decoded string
*/
public static function urlsafeB64Decode($input)
{
$remainder = strlen($input) % 4;
if ($remainder) {
$padlen = 4 - $remainder;
$input .= str_repeat('=', $padlen);
}
return base64_decode(strtr($input, '-_', '+/'));
}
/**
* Encode a string with URL-safe Base64.
*
* @param string $input The string you want encoded
*
* @return string The base64 encode of what you passed in
*/
public static function urlsafeB64Encode($input)
{
return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
}
/**
* Helper method to create a JSON error.
*
* @param int $errno An error number from json_last_error()
*
* @return void
*/
private static function handleJsonError($errno)
{
$messages = array(
JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON',
JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON',
JSON_ERROR_UTF8 => 'Malformed UTF-8 characters' //PHP >= 5.3.3
);
throw new DomainException(
isset($messages[$errno])
? $messages[$errno]
: 'Unknown JSON error: ' . $errno
);
}
/**
* Get the number of bytes in cryptographic strings.
*
* @param string
*
* @return int
*/
private static function safeStrlen($str)
{
if (function_exists('mb_strlen')) {
return mb_strlen($str, '8bit');
}
return strlen($str);
}
}

@ -0,0 +1,15 @@
<?php
/**
* Created by PhpStorm.
* User: Wind
* Date: 2017/11/2
* Time: 10:54
*/
namespace JWT;
class JWTException extends \UnexpectedValueException
{
}

@ -0,0 +1,28 @@
<?php
/**
* Created by PhpStorm.
* User: Wind
* Date: 2017/11/1
* Time: 17:29
*/
namespace king;
class Tools
{
public static function aes($data, $method = 'encrypt', $key = '', $iv = '')
{
$key = $key ?: 'cTFbUKEMWHzP4yeRWpaXZf98NLY902IkxJ4XOuQIq1c=';
$iv = $iv ?: 'Bqa1wCAKcFwFMsYF';
if (strcasecmp($method, 'encrypt') === 0) {
return base64_encode(openssl_encrypt($data, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $iv));
} elseif (strcasecmp($method, 'decrypt') === 0) {
return openssl_decrypt(base64_decode($data), 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $iv);
} else
return false;
}
public static function uuid()
{
return bin2hex(openssl_random_pseudo_bytes(32));
}
}

@ -0,0 +1,430 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- 由 Microsoft Visio, SVG Export 生成 绘图1.svg Page-1 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="11.6929in" height="8.26772in"
viewBox="0 0 841.89 595.276" xml:space="preserve" color-interpolation-filters="sRGB" class="st14">
<v:documentProperties v:langID="2052" v:metric="true" v:viewMarkup="false">
<v:userDefs>
<v:ud v:nameU="msvNoAutoConnect" v:val="VT0(0):26"/>
</v:userDefs>
</v:documentProperties>
<style type="text/css">
<![CDATA[
.st1 {fill:#7aa69c;stroke:#658a82;stroke-linecap:butt;stroke-width:1.25}
.st2 {fill:#ffffff;font-family:黑体;font-size:0.666664em}
.st3 {fill:#4b5968;stroke:#3e4956;stroke-linecap:butt;stroke-width:1.25}
.st4 {fill:#ffffff;font-family:宋体;font-size:0.666664em}
.st5 {font-size:1em}
.st6 {marker-end:url(#mrkr5-13);stroke:#696969;stroke-linecap:butt;stroke-width:1}
.st7 {fill:#696969;fill-opacity:1;stroke:#696969;stroke-opacity:1;stroke-width:0.28409090909091}
.st8 {fill:#7e7e7e;stroke:#696969;stroke-linecap:butt;stroke-width:1.25}
.st9 {fill:#ffffff;stroke:none;stroke-linecap:butt}
.st10 {fill:#686868;font-family:黑体;font-size:0.666664em}
.st11 {marker-end:url(#mrkr5-54);stroke:#696969;stroke-linecap:butt;stroke-width:1}
.st12 {fill:#ffffff;stroke:none;stroke-linecap:butt;stroke-width:7.2}
.st13 {marker-end:url(#mrkr5-91);stroke:#696969;stroke-linecap:butt;stroke-width:1}
.st14 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
]]>
</style>
<defs id="Markers">
<g id="lend5">
<path d="M 2 1 L 0 0 L 1.98117 -0.993387 C 1.67173 -0.364515 1.67301 0.372641 1.98465 1.00043 " style="stroke:none"/>
</g>
<marker id="mrkr5-13" class="st7" v:arrowType="5" v:arrowSize="2" v:setback="6.16" refX="-6.16" orient="auto"
markerUnits="strokeWidth" overflow="visible">
<use xlink:href="#lend5" transform="scale(-3.52,-3.52) "/>
</marker>
<marker id="mrkr5-54" class="st7" v:arrowType="5" v:arrowSize="2" v:setback="0" refX="-0" orient="auto"
markerUnits="strokeWidth" overflow="visible">
<use xlink:href="#lend5" transform="scale(-3.52,-3.52) "/>
</marker>
<marker id="mrkr5-91" class="st7" v:arrowType="5" v:arrowSize="2" v:setback="5.8" refX="-5.8" orient="auto"
markerUnits="strokeWidth" overflow="visible">
<use xlink:href="#lend5" transform="scale(-3.52,-3.52) "/>
</marker>
</defs>
<g v:mID="0" v:index="1" v:groupContext="foregroundPage">
<v:userDefs>
<v:ud v:nameU="msvThemeOrder" v:val="VT0(0):26"/>
</v:userDefs>
<title>页-1</title>
<v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394"
v:shadowOffsetY="-8.50394"/>
<v:layer v:name="流程图" v:index="0"/>
<v:layer v:name="连接线" v:index="1"/>
<g id="shape1-1" v:mID="1" v:groupContext="shape" v:layerMember="0" transform="translate(276.378,-496.063)">
<title>开始/结束</title>
<desc>开始</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.39370078740157):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.39370078740157):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="581.102" width="70.87" height="28.3465"/>
<path d="M14.17 595.28 L56.69 595.28 A14.1732 14.1732 -180 0 0 56.69 566.93 L14.17 566.93 A14.1732 14.1732 -180 1 0 14.17
595.28 Z" class="st1"/>
<text x="27.43" y="583.5" class="st2" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>开始</text> </g>
<g id="shape3-4" v:mID="3" v:groupContext="shape" v:layerMember="0" transform="translate(276.378,-411.024)">
<title>数据</title>
<desc>Refresh Token</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="574.016" width="47.25" height="42.5197"/>
<path d="M-10.63 595.28 L60.24 595.28 L81.5 552.76 L10.63 552.76 L-10.63 595.28 Z" class="st3"/>
<text x="21.43" y="571.62" class="st4" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>Refresh <tspan
x="25.43" dy="1.2em" class="st5">Token</tspan></text> </g>
<g id="shape5-8" v:mID="5" v:groupContext="shape" v:layerMember="1" transform="translate(304.724,-496.063)">
<title>动态连接线</title>
<path d="M7.09 595.28 C7.09 604.12 7.09 620.32 7.09 631.64" class="st6"/>
</g>
<g id="shape6-14" v:mID="6" v:groupContext="shape" v:layerMember="0" transform="translate(276.378,-325.984)">
<title>判定</title>
<desc>验证通过</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="574.016" width="59.06" height="31.8898"/>
<path d="M0 574.02 L35.43 552.76 L70.87 574.02 L35.43 595.28 L0 574.02 Z" class="st1"/>
<text x="19.43" y="576.42" class="st2" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>验证通过</text> </g>
<g id="shape7-17" v:mID="7" v:groupContext="shape" v:layerMember="1" transform="translate(304.724,-411.024)">
<title>动态连接线.7</title>
<path d="M7.09 595.28 C7.09 604.12 7.09 620.32 7.09 631.64" class="st6"/>
</g>
<g id="shape8-22" v:mID="8" v:groupContext="shape" v:layerMember="0" transform="translate(276.378,-58.1102)">
<title>流程</title>
<desc>发放新的令牌</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="574.016" width="70.87" height="42.5197"/>
<rect x="0" y="552.756" width="70.8661" height="42.5197" class="st8"/>
<text x="11.43" y="576.42" class="st2" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>发放新的令牌</text> </g>
<g id="shape9-25" v:mID="9" v:groupContext="shape" v:layerMember="1" transform="translate(347.244,-340.157)">
<title>动态连接线.9</title>
<desc></desc>
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
<v:textRect cx="21.2598" cy="588.189" width="40" height="17.6036"/>
<path d="M0 588.19 C8.84 588.19 25.04 588.19 36.36 588.19" class="st6"/>
<rect v:rectContext="textBkgnd" x="17.2598" y="583.389" width="7.99997" height="9.59985" class="st9"/>
<text x="17.26" y="590.59" class="st10" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/></text> </g>
<g id="shape10-32" v:mID="10" v:groupContext="shape" v:layerMember="0" transform="translate(389.764,-150.236)">
<title>开始/结束.10</title>
<desc>结束</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.39370078740157):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.39370078740157):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="581.102" width="70.87" height="28.3465"/>
<path d="M14.17 595.28 L56.69 595.28 A14.1732 14.1732 -180 0 0 56.69 566.93 L14.17 566.93 A14.1732 14.1732 -180 1 0 14.17
595.28 Z" class="st1"/>
<text x="27.43" y="583.5" class="st2" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>结束</text> </g>
<g id="shape22-35" v:mID="22" v:groupContext="shape" v:layerMember="0" transform="translate(389.764,-325.984)">
<title>判定.22</title>
<desc>未在黑名单</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="574.016" width="59.06" height="31.8898"/>
<path d="M0 574.02 L35.43 552.76 L70.87 574.02 L35.43 595.28 L0 574.02 Z" class="st1"/>
<text x="15.43" y="576.42" class="st2" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>未在黑名单</text> </g>
<g id="shape56-38" v:mID="56" v:groupContext="shape" v:layerMember="0" transform="translate(276.378,-229.606)">
<title>判定.56</title>
<desc>令牌发放 日期大于 退出日期</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.62992125984252):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="572.598" width="59.06" height="34.0157"/>
<path d="M0 572.6 L35.43 549.92 L70.87 572.6 L35.43 595.28 L0 572.6 Z" class="st1"/>
<text x="19.43" y="565.4" class="st2" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>令牌发放<v:newlineChar/><tspan
x="19.43" dy="1.2em" class="st5">日期大于<v:newlineChar/></tspan><tspan x="19.43" dy="1.2em" class="st5">退出日期</tspan></text> </g>
<g id="shape61-43" v:mID="61" v:groupContext="shape" v:layerMember="0" transform="translate(389.764,-223.937)">
<title>判定.61</title>
<desc>令牌发放 日期大于 密码修改 日期</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.78740157480315):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="566.929" width="59.06" height="42.5197"/>
<path d="M0 566.93 L35.43 538.58 L70.87 566.93 L35.43 595.28 L0 566.93 Z" class="st1"/>
<text x="19.43" y="554.93" class="st2" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>令牌发放<v:newlineChar/><tspan
x="19.43" dy="1.2em" class="st5">日期大于<v:newlineChar/></tspan><tspan x="19.43" dy="1.2em" class="st5">密码修改<v:newlineChar/></tspan><tspan
x="27.43" dy="1.2em" class="st5">日期</tspan></text> </g>
<g id="shape138-49" v:mID="138" v:groupContext="shape" v:layerMember="1" transform="translate(382.677,-245.197)">
<title>动态连接线.138</title>
<path d="M7.09 588.19 C7.09 588.19 7.09 588.19 7.09 588.19" class="st11"/>
</g>
<g id="shape148-55" v:mID="148" v:groupContext="shape" v:layerMember="1" transform="translate(418.11,-325.984)">
<title>动态连接线.148</title>
<desc></desc>
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
<v:textRect cx="7.08661" cy="617.953" width="40" height="17.6036"/>
<path d="M7.09 595.28 C7.09 604.82 7.09 622.38 7.09 634.47" class="st6"/>
<rect v:rectContext="textBkgnd" x="3.08655" y="613.153" width="7.99997" height="9.59985" class="st12"/>
<text x="3.09" y="620.35" class="st10" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/></text> </g>
<g id="shape149-62" v:mID="149" v:groupContext="shape" v:layerMember="1" transform="translate(389.764,-259.37)">
<title>动态连接线.149</title>
<desc></desc>
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
<v:textRect cx="-21.2598" cy="602.362" width="40" height="17.6036"/>
<path d="M0 602.36 C-8.84 602.36 -25.04 602.36 -36.36 602.36" class="st6"/>
<rect v:rectContext="textBkgnd" x="-25.2599" y="597.562" width="7.99997" height="9.59985" class="st9"/>
<text x="-25.26" y="604.76" class="st10" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/></text> </g>
<g id="shape150-69" v:mID="150" v:groupContext="shape" v:layerMember="1" transform="translate(304.724,-229.606)">
<title>动态连接线.150</title>
<desc></desc>
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
<v:textRect cx="7.08661" cy="617.244" width="40" height="17.6036"/>
<path d="M7.09 595.28 C7.09 604.47 7.09 621.35 7.09 633.05" class="st6"/>
<rect v:rectContext="textBkgnd" x="3.08655" y="612.444" width="7.99997" height="9.59985" class="st12"/>
<text x="3.09" y="619.64" class="st10" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/></text> </g>
<g id="shape157-76" v:mID="157" v:groupContext="shape" v:layerMember="1" transform="translate(304.724,-143.15)">
<title>动态连接线.157</title>
<desc></desc>
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
<v:textRect cx="7.08661" cy="616.535" width="40" height="17.6036"/>
<path d="M7.09 595.28 C7.09 604.12 7.09 620.32 7.09 631.64" class="st6"/>
<rect v:rectContext="textBkgnd" x="3.08655" y="611.736" width="7.99997" height="9.59985" class="st12"/>
<text x="3.09" y="618.94" class="st10" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/></text> </g>
<g id="shape156-83" v:mID="156" v:groupContext="shape" v:layerMember="0" transform="translate(276.378,-143.15)">
<title>判定.156</title>
<desc>用户未被禁用</desc>
<v:custProps>
<v:cp v:nameU="Cost" v:lbl="成本" v:prompt="" v:type="7" v:format="@" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="ProcessNumber" v:lbl="进程编号" v:prompt="" v:type="2" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Owner" v:lbl="所有者" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Function" v:lbl="函数" v:prompt="" v:type="0" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0" v:val="VT4()"/>
<v:cp v:nameU="StartDate" v:lbl="开始日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false"
v:ask="false" v:langID="2052" v:cal="0"/>
<v:cp v:nameU="EndDate" v:lbl="结束日期" v:prompt="" v:type="5" v:format="" v:sortKey="" v:invis="false" v:ask="false"
v:langID="2052" v:cal="0"/>
<v:cp v:nameU="Status" v:lbl="状态" v:prompt="" v:type="4" v:format=";未开始;进行中;已完成;已推迟;正在等待输入" v:sortKey=""
v:invis="false" v:ask="false" v:langID="2052" v:cal="0" v:val="VT4()"/>
</v:custProps>
<v:userDefs>
<v:ud v:nameU="visVersion" v:prompt="" v:val="VT0(15):26"/>
<v:ud v:nameU="DefaultWidth" v:prompt="" v:val="VT0(0.98425196850394):24"/>
<v:ud v:nameU="DefaultHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
<v:ud v:nameU="ResizeTxtHeight" v:prompt="" v:val="VT0(0.59055118110236):24"/>
</v:userDefs>
<v:textBlock v:margins="rect(2,2,2,2)" v:tabSpace="42.5197"/>
<v:textRect cx="35.4331" cy="574.016" width="59.06" height="31.8898"/>
<path d="M0 574.02 L35.43 552.76 L70.87 574.02 L35.43 595.28 L0 574.02 Z" class="st1"/>
<text x="11.43" y="576.42" class="st2" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/>用户未被禁用</text> </g>
<g id="shape164-86" v:mID="164" v:groupContext="shape" v:layerMember="1" transform="translate(276.378,-347.244)">
<title>动态连接线.164</title>
<desc></desc>
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
<v:textRect cx="-20.9592" cy="785.816" width="40" height="17.6036"/>
<path d="M0 595.28 C-21.26 595.28 -21.26 642.27 -21.26 676.78 C-21.26 722.41 -21.26 746.21 -21.26 770.86 C-21.26 784.1
-21.26 797.58 -15.91 804.89 C-9.57 813.54 4.28 813.54 24.01 813.54 C48.19 813.54 81.2 813.54 109.18 813.54
C128.17 813.54 144.85 813.54 148.21 798.41 L148.24 798.05" class="st13"/>
<rect v:rectContext="textBkgnd" x="-24.9593" y="781.016" width="7.99997" height="9.59985" class="st9"/>
<text x="-24.96" y="788.22" class="st10" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/></text> </g>
<g id="shape165-94" v:mID="165" v:groupContext="shape" v:layerMember="1" transform="translate(276.378,-252.283)">
<title>动态连接线.165</title>
<desc></desc>
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
<v:textRect cx="11.3216" cy="715.086" width="40" height="17.6036"/>
<path d="M0 595.28 C-21.26 595.28 -21.26 623.34 -21.26 646.33 C-21.26 673.85 -21.26 694.11 -9.77 705.2 C4.11 718.58 34.75
718.58 72.08 718.58 C103.73 718.58 140.2 718.58 147.51 703.34 L147.58 702.99" class="st13"/>
<rect v:rectContext="textBkgnd" x="7.32158" y="710.286" width="7.99997" height="9.59985" class="st12"/>
<text x="7.32" y="717.49" class="st10" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/></text> </g>
<g id="shape166-101" v:mID="166" v:groupContext="shape" v:layerMember="1" transform="translate(460.63,-252.283)">
<title>动态连接线.166</title>
<desc></desc>
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
<v:textRect cx="5.57584" cy="635.664" width="40" height="17.6036"/>
<path d="M0 595.28 C21.26 595.28 21.26 616.51 11.96 629.15 C-0.26 645.76 -28.54 647.51 -34.37 662.91 L-34.43 663.26"
class="st13"/>
<rect v:rectContext="textBkgnd" x="1.57578" y="630.864" width="7.99997" height="9.59985" class="st9"/>
<text x="1.58" y="638.06" class="st10" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/></text> </g>
<g id="shape167-108" v:mID="167" v:groupContext="shape" v:layerMember="1" transform="translate(460.63,-347.244)">
<title>动态连接线.167</title>
<desc></desc>
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
<v:textRect cx="20.8255" cy="688.59" width="40" height="17.6036"/>
<path d="M0 595.28 C21.26 595.28 21.26 631.05 21.26 662.22 C21.26 695.27 21.26 723.15 1.65 734.64 C-10.62 741.82 -30.56
742.59 -34.68 757.82 L-34.72 758.18" class="st13"/>
<rect v:rectContext="textBkgnd" x="16.8255" y="683.791" width="7.99997" height="9.59985" class="st9"/>
<text x="16.83" y="690.99" class="st10" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/></text> </g>
<g id="shape168-115" v:mID="168" v:groupContext="shape" v:layerMember="1" transform="translate(347.244,-171.496)">
<title>动态连接线.168</title>
<desc></desc>
<v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/>
<v:textRect cx="21.2598" cy="602.362" width="40" height="17.6036"/>
<path d="M0 602.36 C8.84 602.36 25.04 602.36 36.36 602.36" class="st6"/>
<rect v:rectContext="textBkgnd" x="17.2598" y="597.562" width="7.99997" height="9.59985" class="st12"/>
<text x="17.26" y="604.76" class="st10" v:langID="2052"><v:paragraph v:horizAlign="1"/><v:tabList/></text> </g>
<g id="shape169-122" v:mID="169" v:groupContext="shape" v:layerMember="1" transform="translate(347.244,-79.3701)">
<title>动态连接线.169</title>
<path d="M0 595.28 C19.49 595.28 49.11 595.28 63.72 581.63 C76.38 569.82 77.78 547.77 77.93 530.57 L77.93 530.21"
class="st13"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 30 KiB

@ -0,0 +1,17 @@
## 认证流程说明
### 流程图
![flow chart](./token.svg)
### 在以下情况需要使 refresh_token 失效:
1. 用户退出登录
2. 用户修改密码
3. 用户被管理员禁用
### 解决策略:
1,2 在操作完成后将refresh_token加入黑名单 >>>>>>>> 在没有Redis的情况下使用 mysql 数据库存储
3 有两种实现方式1) 禁用黑名单 2) 每次都查用户表,由于是对原有程序的扩展,方便起见使用第二和方式
### 认证流程:
1. 检验令牌有效
2. 令牌是否在黑名单外 //查询 refresh_token 表
3. 令牌生成上期是否在用户退出后发放,与令牌发放时间对比 //查询 user 表
4. 检测用户修改密码时间,与令牌发放时间对比 //查询 user 表
5. 检测用户未被禁用 // 查询 user 表
6. 以上条件都满足,发放新的令牌

@ -0,0 +1,40 @@
#一带一路手机接口文档说明
## 接口规范介绍
本接口规范对一带路手机客户端接口操作,相关参数、响应和错误码定义,所有提交及返回接收的变量均使用小写。 目前支持REST APP。
## 公共参数
参数 | 类型 | 必填 | 描述
--- | --- | --- | ---
token | string | 是 | 认证(除登录、刷新接口外)
version | string | 是 | 接口版本,固定: 1.0
## 错误码
错误码 | 描述
--- | ---
20001 | 用户不存在
20002 | 无效的 token
## 接口
### 登录接口
#### 请求地址 :
- http://www.ebr1.com/api.php?login
#### 调用方式:
- HTTP post
#### 接口描述:
- 用户登录成功后返回 Token 与 RefreshToken
#### 请求参数:
字段名称 | 类型 | 必填 | 描述
---|---|---|---
username | string | 是 | 用户名
password | string | 是 | 用户密码
#### 返回示例
```
{
'code':'10000';
'data':{
'token':'sdfsfsddf';
'refresh_token':'sdfsfsdfsf'
}
}
```
Loading…
Cancel
Save