feat: 자동 로그인 구현

This commit is contained in:
2021-11-08 04:18:36 +09:00
parent fccc973c8b
commit a35d8bc608
7 changed files with 467 additions and 114 deletions
+2 -2
View File
@@ -77,12 +77,12 @@ ENGINE=Aria;
CREATE TABLE `login_token` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`user_id` INT(11) NOT NULL,
`base_token` INT(11) NOT NULL,
`base_token` VARCHAR(20) NOT NULL COLLATE 'utf8mb4_general_ci',
`reg_ip` VARCHAR(40) NOT NULL COLLATE 'utf8mb4_general_ci',
`reg_date` DATETIME NOT NULL,
`expire_date` DATETIME NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `by_token` (`user_id`, `base_token`),
UNIQUE INDEX `by_token` (`base_token`),
INDEX `by_date` (`user_id`, `expire_date`)
)
COLLATE='utf8mb4_general_ci'
+116 -2
View File
@@ -11,9 +11,12 @@ import { unwrap_any } from '../util/unwrap_any';
import { sha512 } from 'js-sha512';
import { unwrap } from '../util/unwrap';
import { InvalidResponse } from '../defs';
import internal from 'stream';
import { delay } from '../util/delay';
type LoginResponse = {
result: true,
nextToken: [number, string] | undefined,
} | {
result: false,
reqOTP: boolean,
@@ -29,6 +32,19 @@ type OTPResponse = {
reason: string,
}
type AutoLoginNonceResponse = {
result: true,
loginNonce: string,
} | InvalidResponse;
type AutoLoginResponse = {
result: true,
nextToken: [number, string] | undefined,
} | {
result: false,
silent: boolean,
reason: string,
}
declare global {
interface Window {
getOAuthToken: (mode: string, scope_list: string[]) => void;
@@ -41,6 +57,92 @@ declare const kakao_oauth_redirect_uri: string;
let oauthMode: string | null = null;
const TOKEN_VERSION = 1;
const LOGIN_TOKEN_KEY = 'sammo_login_token';
function regNextToken(tokenInfo: [number, string]) {
localStorage.setItem(LOGIN_TOKEN_KEY, JSON.stringify([TOKEN_VERSION, tokenInfo, Date.now()]));
}
function getToken(): [number, string] | undefined {
const trialToken = localStorage.getItem(LOGIN_TOKEN_KEY);
if (!trialToken) {
return;
}
const tokenItems = JSON.parse(trialToken);
if (tokenItems[0] != TOKEN_VERSION) {
console.log(tokenItems);
resetToken();
return;
}
const [, token,] = tokenItems;
return token;
}
function resetToken(){
localStorage.removeItem(LOGIN_TOKEN_KEY);
}
async function tryAutoLogin() {
try {
const tokenInfo = getToken();
if (!tokenInfo) {
return;
}
const [tokenID, token] = tokenInfo;
const result = await axios.post<AutoLoginNonceResponse>('api.php', {
path: ["Login", "ReqNonce"]
});
if(!result){
//api 에러.
return;
}
if(!result.data.result){
resetToken();
return;
}
const nonce = result.data.loginNonce;
const hashedToken = sha512(token + nonce);
const _loginResult = await axios.post<AutoLoginResponse>('api.php', {
path: ["Login", "LoginByToken"],
args: {
'hashedToken':hashedToken,
'token_id':tokenID,
}
});
if(!_loginResult){
return;
}
const loginResult = _loginResult.data;
if(!loginResult.result){
if(!loginResult.silent){
alert(loginResult.reason);
}
console.error(loginResult.reason);
return;
}
if(loginResult.nextToken){
regNextToken(loginResult.nextToken);
}
window.location.href = "./";
}
catch(e){
console.error(e);
return;
}
}
function getOAuthToken(mode: string, scope_list?: string[] | string) {
if (mode === undefined) {
mode = 'login';
@@ -115,6 +217,9 @@ async function doLoginUsingOAuth() {
}
if (result.result) {
if (result.nextToken) {
regNextToken(result.nextToken);
}
window.location.href = "./";
return;
}
@@ -156,9 +261,16 @@ function postOAuthResult(mode: string) {
window.postOAuthResult = postOAuthResult;
$(function ($) {
$(async function ($) {
setAxiosXMLHttpRequest();
//로그인 먼저 해볼 것
if(getToken()){
void tryAutoLogin();
await delay(100);
}
type LoginFormType = {
username: string,
password: string,
@@ -215,6 +327,9 @@ $(function ($) {
if (result.result) {
if (result.nextToken) {
regNextToken(result.nextToken);
}
window.location.href = "./";
return;
}
@@ -276,7 +391,6 @@ $(function ($) {
getOAuthToken('login', ['account_email', 'talk_message']);
})
//TODO: 모바일에서 크기 비례 지도 다시 띄우기?
/*
if (document.body.clientWidth < 700) {
+118 -80
View File
@@ -1,28 +1,30 @@
<?php
namespace sammo;
require(__DIR__.'/../vendor/autoload.php');
require(__DIR__ . '/../vendor/autoload.php');
require('lib.join.php');
//TODO: KakaoOauth를 API로 정식으로 이동
WebUtil::requireAJAX();
use \kakao\Kakao_REST_API_Helper as Kakao_REST_API_Helper;
$RootDB = RootDB::db();
$session = Session::getInstance();
if($session->isLoggedIn()){
if ($session->isLoggedIn()) {
$session->logout();
}
$canLogin = RootDB::db()->queryFirstField('SELECT `LOGIN` FROM `system` WHERE `NO` = 1');
if($canLogin != 'Y'){
if ($canLogin != 'Y') {
Json::die([
'result'=>false,
'reqOTP'=>false,
'reason'=>'현재는 로그인이 금지되어있습니다!',
'noRetry'=>true
'result' => false,
'reqOTP' => false,
'reason' => '현재는 로그인이 금지되어있습니다!',
'noRetry' => true
]);
}
@@ -35,84 +37,84 @@ $refresh_token_expires = $session->refresh_token_expires;
$email = $session->kaccount_email;
if(!$access_token || !$expires){
if (!$access_token || !$expires) {
Json::die([
'result'=>false,
'reqOTP'=>false,
'reason'=>'카카오로그인이 이루어지지 않았습니다.'
'result' => false,
'reqOTP' => false,
'reason' => '카카오로그인이 이루어지지 않았습니다.'
]);
}
//TODO: join과 login의 동작이 비슷하다. helper class로 묶자.
$restAPI = new Kakao_REST_API_Helper($access_token);
if($expires < $now && (!$refresh_token || ($refresh_token_expires < $now))){
if ($expires < $now && (!$refresh_token || ($refresh_token_expires < $now))) {
Json::die([
'result'=>false,
'reqOTP'=>false,
'reason'=>'로그인 토큰 만료.'.$refresh_token_expires.' 다시 카카오로그인을 수행해주세요.'
'result' => false,
'reqOTP' => false,
'reason' => '로그인 토큰 만료.' . $refresh_token_expires . ' 다시 카카오로그인을 수행해주세요.'
]);
}
if($expires < $now){
if ($expires < $now) {
$session->kaccount_email = null;
$email = null;
$result = $restAPI->refresh_access_token($refresh_token);
if(!isset($refresh_token)){
if (!isset($refresh_token)) {
Json::die([
'result'=>false,
'reqOTP'=>false,
'reason'=>'카카오 로그인 과정 중 추가 갱신 절차를 실패했습니다'
'result' => false,
'reqOTP' => false,
'reason' => '카카오 로그인 과정 중 추가 갱신 절차를 실패했습니다'
]);
}
$access_token = $result['access_token'];
$expires = TimeUtil::nowAddSeconds($result['expires_in']);
if(isset($result['refresh_token'])){
if (isset($result['refresh_token'])) {
$refresh_token = Util::array_get($result['refresh_token']);
$refresh_token_expires = TimeUtil::nowAddSeconds($result['refresh_token_expires_in']);
}
}
if(!$email){
if (!$email) {
$me = $restAPI->meWithEmail();
$me['code'] = Util::array_get($me['code'], 0);
if ($me['code']< 0) {
if ($me['code'] < 0) {
Json::die([
'result'=>false,
'reqOTP'=>false,
'reason'=>'카카오로그인이 정상적으로 수행되지 않았습니다.'
'result' => false,
'reqOTP' => false,
'reason' => '카카오로그인이 정상적으로 수행되지 않았습니다.'
]);
}
$kakao_account = $me['kakao_account']??null;
$kakao_account = $me['kakao_account'] ?? null;
if (!$kakao_account) {
Json::die([
'result'=>false,
'reqOTP'=>false,
'reason'=>'카카오 로그인 정보를 제대로 받아오지 못했습니다.'
'result' => false,
'reqOTP' => false,
'reason' => '카카오 로그인 정보를 제대로 받아오지 못했습니다.'
]);
}
if(!($kakao_account['has_email']??false)){
if (!($kakao_account['has_email'] ?? false)) {
Json::die([
'result'=>false,
'reqOTP'=>false,
'reason'=>'이메일 정보 공유를 허가해 주셔야 합니다.',
'result' => false,
'reqOTP' => false,
'reason' => '이메일 정보 공유를 허가해 주셔야 합니다.',
]);
}
$validEmail = $kakao_account['is_email_valid']??false;
$verifiedEmail = $kakao_account['is_email_verified']??false;
$validEmail = $kakao_account['is_email_valid'] ?? false;
$verifiedEmail = $kakao_account['is_email_verified'] ?? false;
if(!$validEmail || !$verifiedEmail){
if (!$validEmail || !$verifiedEmail) {
$restAPI->unlink();
Json::die([
'result'=>false,
'reqOTP'=>false,
'reason'=>'카카오 계정 이메일이 아직 인증되지 않았습니다',
'result' => false,
'reqOTP' => false,
'reason' => '카카오 계정 이메일이 아직 인증되지 않았습니다',
]);
}
@@ -122,86 +124,122 @@ if(!$email){
$userInfo = $RootDB->queryFirstRow(
'SELECT `no`, `id`, `name`, `grade`, `delete_after`, `acl`, oauth_info, token_valid_until from member where email=%s',$email);
'SELECT `no`, `id`, `name`, `grade`, `delete_after`, `acl`, oauth_info, token_valid_until from member where email=%s',
$email
);
if(!$userInfo){
if (!$userInfo) {
$restAPI->unlink();
$session->access_token = null;
Json::die([
'result'=>false,
'reqOTP'=>false,
'reason'=>'카카오로그인에 해당하는 계정이 없습니다. 재 가입을 시도해주세요.',
'aux'=>$session->tmpx,
'result' => false,
'reqOTP' => false,
'reason' => '카카오로그인에 해당하는 계정이 없습니다. 재 가입을 시도해주세요.',
'aux' => $session->tmpx,
]);
}
if($userInfo['delete_after']){
if($userInfo['delete_after'] < $now){
if ($userInfo['delete_after']) {
if ($userInfo['delete_after'] < $now) {
$restAPI->unlink();
$session->access_token = null;
$RootDB->delete('member', 'no=%i', $userInfo['no']);
Json::die([
'result'=>false,
'reqOTP'=>false,
'reason'=>"기간 만기로 삭제되었습니다. 재 가입을 시도해주세요.",
'result' => false,
'reqOTP' => false,
'reason' => "기간 만기로 삭제되었습니다. 재 가입을 시도해주세요.",
]);
}
else{
} else {
$restAPI->unlink();
$session->access_token = null;
Json::die([
'result'=>false,
'reqOTP'=>false,
'reason'=>"삭제 요청된 계정입니다.[{$userInfo['delete_after']}]"
'result' => false,
'reqOTP' => false,
'reason' => "삭제 요청된 계정입니다.[{$userInfo['delete_after']}]"
]);
}
}
$oauthInfo = Json::decode($userInfo['oauth_info'])??[];
$oauthInfo = Json::decode($userInfo['oauth_info']) ?? [];
$oauthInfo['accessToken'] = $access_token;
$oauthInfo['accessTokenValidUntil'] = $expires;
if($refresh_token){
if ($refresh_token) {
$oauthInfo['refreshToken'] = $refresh_token;
$oauthInfo['refreshTokenValidUntil'] = $refresh_token_expires;
}
RootDB::db()->update('member', [
'oauth_info'=>Json::encode($oauthInfo)
'oauth_info' => Json::encode($oauthInfo)
], 'no=%i', $userInfo['no']);
$tokenValidUntil = $userInfo['token_valid_until'];
if(!$tokenValidUntil || $tokenValidUntil < $now){
if(!createOTPbyUserNO($userInfo['no'])){
if (!$tokenValidUntil || $tokenValidUntil < $now) {
if (!createOTPbyUserNO($userInfo['no'])) {
Json::die([
'result'=>false,
'reqOTP'=>false,
'reason'=>'인증 코드를 보내는데 실패했습니다.'
'result' => false,
'reqOTP' => false,
'reason' => '인증 코드를 보내는데 실패했습니다.'
]);
}
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], true, $userInfo['token_valid_until'], Json::decode($userInfo['acl']??'{}'));
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], true, $userInfo['token_valid_until'], null, Json::decode($userInfo['acl'] ?? '{}'));
Json::die([
'result'=>false,
'reqOTP'=>true,
'reason'=>'인증 코드를 입력해주세요.'
'result' => false,
'reqOTP' => true,
'reason' => '인증 코드를 입력해주세요.'
]);
}
$RootDB->insert('member_log',[
'member_no'=>$userInfo['no'],
'action_type'=>'login',
'action'=>Json::encode([
'ip'=>Util::get_client_ip(true),
'type'=>'kakao'
$RootDB->insert('member_log', [
'member_no' => $userInfo['no'],
'action_type' => 'login',
'action' => Json::encode([
'ip' => Util::get_client_ip(true),
'type' => 'kakao'
])
]);
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], false, $userInfo['token_valid_until'], Json::decode($userInfo['acl']??'{}'));
//TODO: 이동하면서 이부분 정리
$nowDate = TimeUtil::now();
$RootDB->delete(
'login_token',
'user_id = %i AND expire_date < %s',
$userID,
$nowDate
);
$RootDB->query(
'DELETE invalid FROM login_token AS invalid
JOIN
( SELECT id
FROM login_token
WHERE user_id = %i
ORDER BY id DESC
LIMIT 8,1
) AS valid
ON invalid.id < valid.id WHERE user_id = %i',
$userID,
$userID
);
$token = Util::randomStr(20);
$RootDB->insert('login_token', [
'user_id' => $userInfo['no'],
'base_token' => $token,
'reg_ip' => Util::get_client_ip(true),
'reg_date' => $nowDate,
'expire_date' => TimeUtil::nowAddDays(7)
]);
$tokenID = $RootDB->insertId();
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], false, $userInfo['token_valid_until'], $tokenID, Json::decode($userInfo['acl'] ?? '{}'));
Json::die([
'result'=>true,
'reqOTP'=>false,
'reason'=>'로그인 되었습니다.'
]);
'result' => true,
'reqOTP' => false,
'nextToken' => [$tokenID, $token],
'reason' => '로그인 되었습니다.'
]);
+49 -12
View File
@@ -2,6 +2,7 @@
namespace sammo\API\Login;
use DateTime;
use sammo\Session;
use DateTimeInterface;
use sammo\BaseAPI;
@@ -34,6 +35,47 @@ class LoginByID extends \sammo\BaseAPI
return BaseAPI::NO_SESSION;
}
public function scrubToken(int $userID)
{
$RootDB = RootDB::db();
$nowDate = TimeUtil::now();
$RootDB->delete(
'login_token',
'user_id = %i AND expire_date < %s',
$userID,
$nowDate
);
$RootDB->query(
'DELETE invalid FROM login_token AS invalid
JOIN
( SELECT id
FROM login_token
WHERE user_id = %i
ORDER BY id DESC
LIMIT 8,1
) AS valid
ON invalid.id < valid.id WHERE user_id = %i',
$userID,
$userID
);
}
public function addToken(int $userID)
{
$RootDB = RootDB::db();
$nowDate = TimeUtil::now();
$token = Util::randomStr(20);
$RootDB->insert('login_token', [
'user_id' => $userID,
'base_token' => $token,
'reg_ip' => Util::get_client_ip(true),
'reg_date' => $nowDate,
'expire_date' => TimeUtil::nowAddDays(7)
]);
$tokenID = $RootDB->insertId();
return [$tokenID, $token];
}
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$RootDB = RootDB::db();
@@ -82,16 +124,6 @@ class LoginByID extends \sammo\BaseAPI
}
}
$RootDB->insert('member_log', [
'member_no' => $userInfo['no'],
'action_type' => 'login',
'action' => Json::encode([
'ip' => Util::get_client_ip(true),
'type' => 'plain'
])
]);
$RootDB->insert('member_log', [
'member_no' => $userInfo['no'],
'action_type' => 'login',
@@ -104,7 +136,7 @@ class LoginByID extends \sammo\BaseAPI
if ($userInfo['oauth_type'] == 'KAKAO') {
$oauthFailResult = KakaoUtil::kakaoOAuthCheck($userInfo);
if ($oauthFailResult !== null) {
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], true, $userInfo['token_valid_until'], Json::decode($userInfo['acl'] ?? '{}'));
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], true, $userInfo['token_valid_until'], null, Json::decode($userInfo['acl'] ?? '{}'));
[$oauthReqOTP, $oauthFailReason] = $oauthFailResult;
return [
'result' => false,
@@ -114,11 +146,16 @@ class LoginByID extends \sammo\BaseAPI
}
}
$this->scrubToken($userInfo['no']);
$nextToken = $this->addToken($userInfo['no']);
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], false, $userInfo['token_valid_until'], $nextToken[0], Json::decode($userInfo['acl'] ?? '{}'));
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], false, $userInfo['token_valid_until'], Json::decode($userInfo['acl'] ?? '{}'));
return [
'result' => true,
'reqOTP' => false,
'nextToken' => $nextToken,
'reason' => '로그인 되었습니다.'
];
}
+129 -8
View File
@@ -12,18 +12,139 @@ use sammo\TimeUtil;
use sammo\Util;
use sammo\Validator;
class LoginByToken extends \sammo\BaseAPI{
class LoginByToken extends LoginByID
{
public function getRequiredSessionMode(): int {
return \sammo\BaseAPI::NO_SESSION;
public function getRequiredSessionMode(): int
{
return \sammo\BaseAPI::NO_SESSION; //XXX: Token 때문에 엄밀히는 NO_SESSION이 아님
}
public function validateArgs(): ?string {
public function validateArgs(): ?string
{
$v = new Validator($this->args);
$v
->rule('required', [
'token_id',
'hashedToken'
]);
if (!$v->validate()) {
return $v->errorStr();
}
return null;
}
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag) {
return '미구현';
}
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
{
$loginNonce = $session->loginNonce ?? null;
$loginNonceExpired = $session->loginNonceExpired ?? null;
if (!is_string($loginNonce) || !is_string($loginNonceExpired)) {
return '자동 로그인: 절차 오류';
}
}
$RootDB = RootDB::db();
if ($session->isLoggedIn()) {
$session->logout();
}
$token_id = $this->args['token_id'];
$token_info = $RootDB->queryFirstRow('SELECT * FROM login_token WHERE id = %i', $token_id);
if (!$token_info) {
return [
'result' => false,
'silent' => true,
'reason' => 'failed'
];
}
$hashedToken = $this->args['hashedToken'];
$tokenAnswer = hash('sha512', "{$token_info['base_token']}{$loginNonce}");
if (strtolower($hashedToken) != strtolower($tokenAnswer)) {
return [
'result' => false,
'silent' => true,
'reason' => 'failed'
];
}
$userInfo = $RootDB->queryFirstRow(
'SELECT `no`, `id`, `name`, `grade`, `delete_after`, `acl`, oauth_id, oauth_type, oauth_info, token_valid_until ' .
'from member where NO = %i',
$token_info['user_id']
);
if(!$userInfo){
return '자동 로그인: 올바른 계정이 아닙니다.';
}
$canLogin = $RootDB->queryFirstField('SELECT `LOGIN` FROM `system` WHERE `NO` = 1');
if ($canLogin != 'Y' && $userInfo['grade'] < 5) {
return '자동 로그인: 현재는 로그인이 금지되어있습니다!';
}
$nowDate = TimeUtil::now();
if ($userInfo['delete_after']) {
if ($userInfo['delete_after'] < $nowDate) {
$RootDB->delete('member', 'no=%i', $userInfo['no']);
return [
'result' => false,
'silent' => true,
'reason' => "기간 만기"
];
} else {
return [
'result' => false,
'silent' => true,
'reason' => "삭제 요청된 계정[{$userInfo['delete_after']}]"
];
}
}
$RootDB->insert('member_log', [
'member_no' => $userInfo['no'],
'action_type' => 'login',
'action' => Json::encode([
'ip' => Util::get_client_ip(true),
'type' => 'auto'
])
]);
if ($userInfo['oauth_type'] == 'KAKAO') {
$oauthFailResult = KakaoUtil::kakaoOAuthCheck($userInfo);
if ($oauthFailResult !== null) {
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], true, $userInfo['token_valid_until'], null, Json::decode($userInfo['acl'] ?? '{}'));
[$oauthReqOTP, $oauthFailReason] = $oauthFailResult;
$RootDB->delete(
'login_token',
'id = %i', $token_id
);
return $oauthFailReason;
}
}
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], false, $userInfo['token_valid_until'], $token_id, Json::decode($userInfo['acl'] ?? '{}'));
$this->scrubToken($userInfo['no']);
$nextDate = TimeUtil::nowAddDays(2);
if($nextDate < $token_info['expire_date']){
return [
'result' => true,
'silent' => true,
'reason' => 'success'
];
}
$RootDB->delete(
'login_token',
'id = %i', $token_id
);
$nextToken = $this->addToken($token_id);
return [
'result' => true,
'silent' => true,
'nextToken' => $nextToken,
'reason' => 'success'
];
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php
namespace sammo\API\Login;
use sammo\Session;
use DateTimeInterface;
use sammo\BaseAPI;
use sammo\Json;
use sammo\KakaoUtil;
use sammo\RootDB;
use sammo\TimeUtil;
use sammo\Util;
use sammo\Validator;
class ReqNonce extends BaseAPI{
public function getRequiredSessionMode(): int {
return \sammo\BaseAPI::NO_SESSION;
}
public function validateArgs(): ?string
{
return null;
}
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag) {
$loginNonce = Util::randomStr(16);
$loginNonceExpired = TimeUtil::nowAddSeconds(2);
$session->loginNonce = $loginNonce;
$session->loginNonceExpired = $loginNonceExpired;
return [
'result'=>true,
'loginNonce'=>$loginNonce,
];
}
}
+16 -10
View File
@@ -10,8 +10,9 @@ namespace sammo;
* @property string $ip IP
* @property bool $reqOTP 인증 코드 필요
* @property array $acl 권한
* @property int|null $tokenID 토큰ID
* @property string $tokenValidUntil 로그인 토큰 길이
*
*
* @property int $generalID 장수 번호 (게임 로그인 필요)
* @property string $generalName 장수 이름 (게임 로그인 필요)
*/
@@ -35,7 +36,7 @@ class Session
const GAME_KEY_GENERAL_ID = '_g_no';
const GAME_KEY_GENERAL_NAME = '_g_name';
const GAME_KEY_EXPECTED_DEADTIME = '_g_deadtime';
private $writeClosed = false;
private $sessionID = null;
@@ -170,7 +171,7 @@ class Session
return Util::array_get($_SESSION[$name]);
}
public function login(int $userID, string $userName, int $grade, bool $reqOTP, ?string $tokenValidUntil, array $acl): Session
public function login(int $userID, string $userName, int $grade, bool $reqOTP, ?string $tokenValidUntil, ?int $tokenID, array $acl): Session
{
$this->set('userID', $userID);
$this->set('userName', $userName);
@@ -180,6 +181,7 @@ class Session
$this->set('acl', $acl);
$this->set('reqOTP', $reqOTP);
$this->set('tokenValidUntil', $tokenValidUntil);
$this->set('tokenID', $tokenID);
return $this;
}
@@ -197,7 +199,11 @@ class Session
if (class_exists('\\sammo\\UniqueConst')) {
$this->logoutGame();
}
if($this->tokenID??null){
RootDB::db()->delete('login_token', 'id = %i', $this->tokenID);
}
$this->set('userID', null);
$this->set('userName', null);
$this->set('userGrade', null);
@@ -261,7 +267,7 @@ class Session
}
return $this;
}
$turnterm = $gameStor->turnterm;
$isUnited = $gameStor->isunited != 0;
@@ -319,7 +325,7 @@ class Session
} else {
$obj = self::getInstance();
}
return $obj->userGrade;
}
@@ -335,12 +341,12 @@ class Session
} else {
$obj = self::getInstance();
}
return $obj->userID;
}
/**
*
*
*/
public static function getGeneralID(bool $requireLogin = false, string $exitPath = '..')
{
@@ -349,7 +355,7 @@ class Session
} else {
$obj = self::getInstance();
}
return $obj->generalID??0;
}
@@ -367,7 +373,7 @@ class Session
return false;
}
}
if ($this->userID) {
return true;
} else {