trafficmonitor/app/Services/Auth/AuthService.php

153 lines
4.1 KiB
PHP

<?php
namespace App\Services\Auth;
use App\Entities\UserEntity;
use App\Helpers\AuthHelper;
use App\Models\CommonModel;
use App\Services\CommonService;
use CodeIgniter\Session\Session;
// 참고:https://github.com/SyntaxPhoenix/iloclient
abstract class AuthService extends CommonService
{
private ?Session $_session = null;
private $url_stack_name = "url_stack";
protected function __construct(CommonModel $model)
{
parent::__construct($model);
$this->addClassPaths('Auth');
}
abstract public function login(mixed $dto): UserEntity;
final public function getHelper(): AuthHelper
{
if ($this->helperInstance === null) {
$this->helperInstance = new AuthHelper();
$this->helperInstance->setAttributes([
'pk_field' => $this->model->getPKField(),
'title_field' => $this->model->getTitleField(),
'table' => $this->model->getTable(),
'useAutoIncrement' => $this->model->useAutoIncrement(),
'class_path' => $this->getClassPaths(false)
]);
}
return $this->helperInstance;
}
//Index,FieldForm관련
final public function getSession(): Session
{
if ($this->_session === null) {
$this->_session = \Config\Services::session();
}
return $this->_session;
}
private function getAuthInfo(string $key = ""): array|string|null
{
$authInfo = $this->getSession()->get(SESSION_NAMES['AUTH']);
if ($key) {
return $authInfo[$key] ?? null;
}
return $authInfo;
}
public function getFormFields(): array
{
return ['id', 'passwd'];
}
final public function getUID(): string|null
{
return $this->getAuthInfo('uid');
}
final public function getID(): string|null
{
return $this->getAuthInfo('id');
}
final public function getName(): string|null
{
return $this->getAuthInfo('name');
}
/**
* 현재 로그인된 사용자의 역할을 배열 형태로 반환합니다.
* UserEntity::getRole()의 반환 타입과 일치시킵니다.
* @return array|null
*/
final public function getRole(): array|null // <-- 타입 힌트를 array|null로 변경
{
// getAuthInfo는 UserEntity에서 배열을 받아옵니다.
return $this->getAuthInfo('role');
}
final public function isLoggedIn(): bool
{
return $this->getSession()->has(SESSION_NAMES['ISLOGIN']);
}
/**
* 사용자가 필요한 접근 권한($roles)을 가지고 있는지 확인합니다.
* @param array $roles 요구되는 권한 목록
* @return bool
*/
final public function isAccessRole(array $roles): bool
{
// (1) getRole()의 반환 타입이 이제 배열이므로 바로 받습니다.
$userRoles = $this->getRole();
// 역할 정보 자체가 없거나 빈 배열인 경우 접근 불가
if (empty($userRoles) || !is_array($userRoles)) {
return false;
}
// (2) 문자열 explode() 대신 array_intersect를 사용하여 배열 간의 공통점을 찾습니다.
// 교집합이 없으면 false
return !empty(array_intersect($userRoles, $roles));
}
final public function pushCurrentUrl(string $url): void
{
$this->getSession()->set($this->url_stack_name, $url);
}
final public function popPreviousUrl(): string
{
$url = $this->getSession()->get($this->url_stack_name) ?? "";
if (!empty($url)) {
$this->pushCurrentUrl("");
return $url;
}
return '/'; // 기본 URL
}
final protected function login_process(UserEntity $entity): UserEntity
{
$this->getSession()->set(SESSION_NAMES['ISLOGIN'], true);
$this->getSession()->set(SESSION_NAMES['AUTH'], [
'uid' => $entity->getPK(),
'id' => $entity->getID(),
'name' => $entity->getTitle(),
'role' => $entity->getRole()
]);
return $entity;
}
final public function logout(): void
{
// 세션 데이터 삭제
$this->getSession()->remove(SESSION_NAMES['ISLOGIN']);
$this->getSession()->remove(SESSION_NAMES['AUTH']);
// 모든 세션 데이터 삭제
$this->getSession()->destroy();
// 세션 쿠키 삭제
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(
session_name(),
'',
time() - 42000,
$params["path"],
$params["domain"],
$params["secure"],
$params["httponly"]
);
}
// 세션 재생성
session_start();
$this->getSession()->regenerate(true);
}
}