cfmgrv4 init...2

This commit is contained in:
최준흠 2024-10-10 15:21:27 +09:00
parent 4b3edf80f0
commit f44a82b46f
24 changed files with 337 additions and 236 deletions

View File

@ -2,6 +2,7 @@
namespace Config;
use App\Filters\AuthFilter;
use CodeIgniter\Config\Filters as BaseFilters;
use CodeIgniter\Filters\Cors;
use CodeIgniter\Filters\CSRF;
@ -12,7 +13,6 @@ use CodeIgniter\Filters\InvalidChars;
use CodeIgniter\Filters\PageCache;
use CodeIgniter\Filters\PerformanceMetrics;
use CodeIgniter\Filters\SecureHeaders;
use App\Filters\AuthFilter;
class Filters extends BaseFilters
{
@ -35,7 +35,7 @@ class Filters extends BaseFilters
'forcehttps' => ForceHTTPS::class,
'pagecache' => PageCache::class,
'performance' => PerformanceMetrics::class,
'authFilter' => AuthFilter::class,
'authFilter' => AuthFilter::class,
];
/**

View File

@ -16,7 +16,7 @@ $routes->group('/user', function ($routes) {
$routes->get('login', 'UserController::login_form');
$routes->post('login', 'UserController::login');
$routes->get('google_login', 'UserController::google_login');
$routes->get('logout', 'UserController::logout', ['filter' => 'authFilter:user']);
$routes->get('logout', 'UserController::logout');
});
$routes->group('cli', ['namespace' => 'App\CLI'], function ($routes) {
$routes->group('cloudflare', ['namespace' => 'App\CLI\Cloudflare'], function ($routes) {

View File

@ -61,15 +61,14 @@ abstract class CloudflareController extends AdminController
$this->sync_process($uid);
$this->message = "{$this->class_name}: 동기화작업을 완료하였습니다.";
$this->getModel()->transCommit();
log_message("notice", $this->message);
$this->session->setFlashdata(SESSION_NAMES['RETURN_MSG'], $this->message);
return redirect()->to($this->session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/");
log_message("notice", __FUNCTION__ . $this->message);
// 이전 URL로 리다이렉트
return redirect()->to($this->popPreviousUrl())->with('error', $this->message);
} catch (\Exception $e) {
//Transaction Rollback
$this->getModel()->transRollback();
log_message("error", $e->getMessage());
$this->session->setFlashdata(SESSION_NAMES['RETURN_MSG'], __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
return redirect()->to($this->session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/");
return redirect()->back()->withInput()->with('error', __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
}
}
@ -82,15 +81,14 @@ abstract class CloudflareController extends AdminController
$this->reload_process($uid);
$this->message = "{$this->class_name}: Reload 작업이 완료되었습니다.";
$this->getModel()->transCommit();
log_message("notice", $this->message);
$this->session->setFlashdata(SESSION_NAMES['RETURN_MSG'], $this->message);
return redirect()->to($this->session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/");
log_message("notice", __FUNCTION__ . $this->message);
// 이전 URL로 리다이렉트
return redirect()->to($this->popPreviousUrl())->with('error', $this->message);
} catch (\Exception $e) {
//Transaction Rollback
$this->getModel()->transRollback();
log_message("error", $e->getMessage());
$this->session->setFlashdata(SESSION_NAMES['RETURN_MSG'], __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
return redirect()->to($this->session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/");
return redirect()->back()->withInput()->with('error', __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
}
}
}

View File

@ -62,6 +62,18 @@ class UserController extends AdminController
}
$formDatas[$field] = implode(DEFAULTS["DELIMITER_ROLE"], $roles);
break;
case 'passwd': //데이터가 있을때면 formData에 넣어줌 : 수정시에는 않넣을수도 있어야하므로
$passwd = $this->request->getVar($field);
if ($passwd) {
$formDatas[$field] = $passwd;
}
break;
case 'confirmpassword':
$confirmpassword = $this->request->getVar($field);
if ($confirmpassword) {
$formDatas[$field] = $confirmpassword;
}
break;
default:
$formDatas = parent::getFormData($field, $formDatas);
break;

View File

@ -13,7 +13,8 @@ abstract class CommonController extends BaseController
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
parent::initController($request, $response, $logger);
$this->session = service('session');
// 세션 서비스 초기화
$this->session = \Config\Services::session();
}
final public function __get($name)
{
@ -30,4 +31,20 @@ abstract class CommonController extends BaseController
{
return $this->_viewDatas;
}
final protected function pushCurrentUrl()
{
$urlStack = $this->session->get('url_stack', []) ?? [];
$urlStack[] = current_url() . ($this->request->getUri()->getQuery() ? "?" . $this->request->getUri()->getQuery() : "");
$this->session->set('url_stack', $urlStack);
}
final protected function popPreviousUrl()
{
$urlStack = $this->session->get('url_stack', []);
if (!empty($urlStack)) {
return array_pop($urlStack);
}
return '/'; // 기본 URL
}
}

View File

@ -17,7 +17,6 @@ abstract class MVController extends CommonController
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
parent::initController($request, $response, $logger);
$this->session = service('session');
$this->class_path = "";
}
abstract protected function getModel(): mixed;
@ -95,7 +94,6 @@ abstract class MVController extends CommonController
try {
helper(['form']);
$this->create_form_process();
$this->session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
$this->forms = ['attributes' => ['method' => "post",], 'hiddens' => []];
return view(
$this->view_path . "create",
@ -103,7 +101,7 @@ abstract class MVController extends CommonController
);
} catch (\Exception $e) {
log_message("error", $e->getMessage());
return redirect()->to($this->session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/")->with(SESSION_NAMES['RETURN_MSG'], $e->getMessage());
return redirect()->back()->with('error', $e->getMessage());
}
}
protected function create_process(): void
@ -119,9 +117,8 @@ abstract class MVController extends CommonController
try {
helper(['form']);
$this->create_process();
$this->message = "{$this->class_name} : 생성작업이 완료되었습니다.";
$this->getModel()->transCommit();
log_message("notice", __FUNCTION__ . $this->message);
$this->message = "{$this->class_name} : 생성작업이 완료되었습니다.";
return view(
$this->view_path . "view",
data: ['viewDatas' => $this->getViewDatas()]
@ -130,9 +127,7 @@ abstract class MVController extends CommonController
//Transaction Rollback
$this->getModel()->transRollback();
log_message("error", $e->getMessage());
$this->session->setFlashdata(SESSION_NAMES['RETURN_MSG'], __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
$this->session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
return redirect()->back()->withInput();
return redirect()->back()->withInput()->with('error', __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
}
}
// 수정
@ -159,7 +154,6 @@ abstract class MVController extends CommonController
try {
helper(['form']);
$this->modify_form_process($uid);
$this->session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
$this->forms = ['attributes' => ['method' => "post",], 'hiddens' => []];
return view(
$this->view_path . "modify",
@ -167,7 +161,7 @@ abstract class MVController extends CommonController
);
} catch (\Exception $e) {
log_message("error", $e->getMessage());
return redirect()->to($this->session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/")->with(SESSION_NAMES['RETURN_MSG'], $e->getMessage());
return redirect()->back()->with('error', $e->getMessage());
}
}
protected function modify_process(string $uid): void
@ -188,9 +182,8 @@ abstract class MVController extends CommonController
try {
helper(['form']);
$this->modify_process($uid);
$this->message = "{$this->class_name} : 생성작업이 완료되었습니다.";
$this->getModel()->transCommit();
log_message("notice", __FUNCTION__ . $this->message);
$this->message = "{$this->class_name} : 수정작업이 완료되었습니다.";
return view(
$this->view_path . "view",
data: ['viewDatas' => $this->getViewDatas()]
@ -199,9 +192,7 @@ abstract class MVController extends CommonController
//Transaction Rollback
$this->getModel()->transRollback();
log_message("error", $e->getMessage());
$this->session->setFlashdata(SESSION_NAMES['RETURN_MSG'], __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
$this->session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
return redirect()->back()->withInput();
return redirect()->back()->withInput()->with('error', __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
}
}
//일괄처리작업
@ -219,17 +210,14 @@ abstract class MVController extends CommonController
$this->modify_process($uid);
}
$this->message = "{$this->class_name} : 일괄처리작업이 완료되었습니다.";
$this->getModel()->transCommit();
log_message("notice", $this->message);
$this->session->setFlashdata(SESSION_NAMES['RETURN_MSG'], $this->message);
return redirect()->to($this->session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/");
log_message("notice", __FUNCTION__ . $this->message);
// 이전 URL로 리다이렉트
return redirect()->to($this->popPreviousUrl())->with('error', $this->message);
} catch (\Exception $e) {
//Transaction Rollback
$this->getModel()->transRollback();
log_message("error", $e->getMessage());
$this->session->setFlashdata(SESSION_NAMES['RETURN_MSG'], __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
$this->session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
return redirect()->back()->withInput();
return redirect()->back()->withInput()->with('error', __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
}
}
//단일필드작업
@ -243,15 +231,14 @@ abstract class MVController extends CommonController
$this->modify_process($uid);
$this->message = "{$this->class_name} : Toggle 수정작업이 완료되었습니다.";
$this->getModel()->transCommit();
log_message("notice", $this->message);
$this->session->setFlashdata(SESSION_NAMES['RETURN_MSG'], $this->message);
return redirect()->to($this->session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/");
log_message("notice", __FUNCTION__ . $this->message);
// 이전 URL로 리다이렉트
return redirect()->to($this->popPreviousUrl())->with('error', $this->message);
} catch (\Exception $e) {
//Transaction Rollback
$this->getModel()->transRollback();
log_message("error", $e->getMessage());
$this->session->setFlashdata(SESSION_NAMES['RETURN_MSG'], __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
return redirect()->back()->withInput();
return redirect()->back()->withInput()->with('error', __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
}
}
//삭제
@ -272,16 +259,14 @@ abstract class MVController extends CommonController
$this->delete_process($uid);
$this->message = "{$this->class_name} : 삭제작업이 완료되었습니다.";
$this->getModel()->transCommit();
log_message("notice", $this->message);
$this->session->setFlashdata(SESSION_NAMES['RETURN_MSG'], $this->message);
return redirect()->to($this->session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/");
log_message("notice", __FUNCTION__ . $this->message);
// 이전 URL로 리다이렉트
return redirect()->to($this->popPreviousUrl())->with('error', $this->message);
} catch (\Exception $e) {
//Transaction Rollback
$this->getModel()->transRollback();
log_message("error", $e->getMessage());
$this->session->setFlashdata(SESSION_NAMES['RETURN_MSG'], __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
$this->session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
return redirect()->back()->withInput();
return redirect()->back()->withInput()->with('error', __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
}
}
// 리스트
@ -361,7 +346,7 @@ abstract class MVController extends CommonController
log_message("debug", $this->getModel()->getLastQuery());
return $entitys;
}
final protected function list_procedure(): string
final protected function list_procedure(): RedirectResponse|string
{
try {
helper(['form']);
@ -373,9 +358,9 @@ abstract class MVController extends CommonController
$this->pagination = $this->list_pagination_process();
//모델 처리
$this->entitys = $this->list_entitys_process();
//setting return_url to session flashdata
// RETURN_URL을 일반 세션 데이터로 저장
$this->session->setFlashdata(SESSION_NAMES['RETURN_URL'], current_url() . ($this->uri->getQuery() ? "?" . $this->uri->getQuery() : ""));
// 현재 URL을 스택에 저장
$this->pushCurrentUrl();
return view(
$this->view_path . "index",
@ -383,8 +368,7 @@ abstract class MVController extends CommonController
);
} catch (\Exception $e) {
log_message("error", $e->getMessage());
return $this->helper->alert($e->getMessage(), "back");
// return redirect()->back()->with(SESSION_NAMES['RETURN_MSG'], $e->getMessage());
return redirect()->back()->with('error', $e->getMessage());
}
}
@ -420,7 +404,7 @@ abstract class MVController extends CommonController
return array($full_path, $file_name);
}
//File Download관련
final protected function download_procedure(string $output_type, $uid = false): DownloadResponse|string
final protected function download_procedure(string $output_type, $uid = false): DownloadResponse|RedirectResponse
{
try {
helper(['form']);
@ -456,7 +440,7 @@ abstract class MVController extends CommonController
return $this->response->download($full_path, null)->setFileName($file_name);
} catch (\Exception $e) {
log_message("error", $e->getMessage());
return $this->helper->alert($e->getMessage(), "back");
return redirect()->back()->with('error', $e->getMessage());
}
}
}

View File

@ -12,7 +12,6 @@ use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Validation\Validation;
use Google\Service\Oauth2;
use Psr\Log\LoggerInterface;
class UserController extends FrontController
@ -89,8 +88,6 @@ class UserController extends FrontController
//구글 로그인 BUTTON용
$google_socket = new GoogleSocket();
$this->google_url = $google_socket->createAuthUrl();
$this->session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
$this->forms = ['attributes' => ['method' => "post",], 'hiddens' => []];
return view(
$this->view_path . "login",
@ -98,7 +95,7 @@ class UserController extends FrontController
);
} catch (\Exception $e) {
log_message("error", $e->getMessage());
return redirect()->to($this->session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/")->with(SESSION_NAMES['RETURN_MSG'], $e->getMessage());
return redirect()->back()->withInput()->with('error', __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
}
}
//로그인처리
@ -111,19 +108,17 @@ class UserController extends FrontController
$this->create_validate($this->action, $this->fields);
$this->formDatas = $this->getFormDatas();
$auth = new LocalAuth();
$auth->setLogin($auth->checkUser($this->formDatas));
$auth->login($auth->checkUser($this->formDatas));
$this->message = "로그인 성공";
$this->getModel()->transCommit();
log_message("notice", $this->message);
$this->session->setFlashdata(SESSION_NAMES['RETURN_MSG'], $this->message);
return redirect()->to($this->session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/");
log_message("notice", __FUNCTION__ . $this->message);
// 이전 URL로 리다이렉트
return redirect()->to($this->popPreviousUrl())->with('message', $this->message);
} catch (\Exception $e) {
//Transaction Rollback
$this->getModel()->transRollback();
log_message("error", $e->getMessage());
$this->session->setFlashdata(SESSION_NAMES['RETURN_MSG'], "로그인 실패하였습니다.\n" . $e->getMessage());
$this->session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
return redirect()->back()->withInput();
return redirect()->back()->withInput()->with('error', __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
}
}
public function google_login(): RedirectResponse|string
@ -137,27 +132,32 @@ class UserController extends FrontController
throw new \Exception("구글 로그인 실패");
}
$auth = new GoogleAuth($access_code);
$auth->setLogin($auth->checkUser());
$auth->login($auth->checkUser());
$this->message = "로그인 성공";
$this->getModel()->transCommit();
log_message("notice", $this->message);
$this->session->setFlashdata(SESSION_NAMES['RETURN_MSG'], $this->message);
return redirect()->to($this->session->getFlashdata(SESSION_NAMES['RETURN_URL']) ?: "/");
log_message("notice", __FUNCTION__ . $this->message);
// 이전 URL로 리다이렉트
return redirect()->to($this->popPreviousUrl())->with('message', $this->message);
} catch (\Exception $e) {
//Transaction Rollback
$this->getModel()->transRollback();
log_message("error", $e->getMessage());
$this->session->setFlashdata(SESSION_NAMES['RETURN_MSG'], "로그인 실패하였습니다.\n" . $e->getMessage());
$this->session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
return redirect()->back()->withInput();
return redirect()->back()->withInput()->with('error', __FUNCTION__ . " 실패하였습니다.\n" . $e->getMessage());
}
}
//로그아웃
public function logout(): RedirectResponse
{
//Session에 Login 정보 삭제
session()->set([SESSION_NAMES['ISLOGIN'] => false]);
session_destroy();
return redirect()->route('/');
try {
$auth = new LocalAuth();
$auth->logout();
// 성공 메시지 설정
$message = "로그아웃 되었습니다.";
// 홈페이지로 리다이렉트
return redirect()->route('/')->with('message', $message);
} catch (\Exception $e) {
log_message("error", $e->getMessage());
return redirect()->back()->with('error', "로그아웃 중 오류가 발생했습니다.");
}
}
}

View File

@ -25,24 +25,14 @@ class AuthFilter implements FilterInterface
*/
public function before(RequestInterface $request, $arguments = null)
{
// 로그인을 했으면
if (session()->get(SESSION_NAMES['ISLOGIN'])) {
$auth = session()->get(SESSION_NAMES['AUTH']);
// 회원 ROLES이 필요ROLE($arguments[0]) 목록에 존재하지 않으면(ACL)
if (!in_array($arguments[0], explode(DEFAULTS['DELIMITER_ROLE'], $auth['role']))) {
return redirect()->to(URLS['LOGIN'])->with(
'return_message',
sprintf(
"%s,%s회원님은 접속에 필요한 권한[%s]이 없습니다. ",
$auth['role'],
$auth['name'],
implode(",", $arguments)
)
);
}
} else {
session()->setFlashdata(SESSION_NAMES['RETURN_URL'], $request->getUri()->getPath() . '?' . $request->getUri()->getQuery());
return redirect()->to(URLS['LOGIN'])->with('return_message', '로그인을하셔야합니다.');
// 로그인 않했으면
if (!session()->has(SESSION_NAMES['ISLOGIN'])) {
return redirect()->to(URLS['LOGIN'])->with('error', '로그인을하셔야합니다.');
}
//User Role 비교 // 회원 ROLES이 필요ROLE($arguments[0]) 목록에 존재하지 않으면(ACL)
$auth = session()->get(SESSION_NAMES['AUTH']);
if (!isset($auth['role']) || !in_array($arguments[0], explode(DEFAULTS['DELIMITER_ROLE'], $auth['role']))) {
return redirect()->back()->with('error', "회원[{$auth['name']}]님은 접속에 필요한 권한이 없습니다. ");
}
}

View File

@ -221,7 +221,7 @@ abstract class CommonHelper
$extras = ["class" => "btn btn-outline btn-primary btn-circle", "target" => "_self", ...$extras];
$action = form_label(
'입력',
"",
$action,
[
"data-src" => current_url() . '/' . $action,
"data-bs-toggle" => "modal",
@ -243,7 +243,7 @@ abstract class CommonHelper
]);
$action = $checkbox . form_label(
$viewDatas['cnt'],
"",
$action,
[
"data-src" => current_url() . '/' . $action . '/' . $viewDatas['entity']->getPK(),
"data-bs-toggle" => "modal",

View File

@ -38,58 +38,22 @@ class GoogleAuth extends MyAuth
return $this->_model;
}
// throw new \Exception(__METHOD__ . "에서 데이터 처리 필요");
// DEBUG - 2023-07-13 12:54:51 --> \Google\Service\Oauth2\Userinfo::__set_state(array(
// 'internal_gapi_mappings' =>
// 'familyName' => 'family_name',
// 'givenName' => 'given_name',
// 'verifiedEmail' => 'verified_email',
// ),
// 'modelData' =>
// array (
// 'verified_email' => true,
// 'given_name' => '이름',
// 'family_name' => '성',
// ),
// 'processed' =>
// array (
// ),
// 'email' => 'twsdfsew342s@gmail.com',
// 'familyName' => '성',
// 'gender' => NULL,
// 'givenName' => '이름',
// 'hd' => NULL,
// 'id' => '103667492432234234236838324',
// 'link' => NULL,
// 'locale' => 'ko',
// 'name' => '성이름',
// 'picture' => 'https://lh3.googleusercontent.com/a/AAcHTteFSgefsdfsdRJBkJA2tBEmg4PQrvI1Ta_5IXu5=s96-c',
// 'verifiedEmail' => true,
// ))
public function checkUser(): UserEntity
{
try {
// Google 서비스 설정
$service = new Oauth2($this->getMySocket());
// 액세스 토큰 유효성 검사 추가
if (!$this->getMySocket()->isAccessTokenValid()) {
$this->getMySocket()->refreshToken($this->getMySocket()->getRefreshToken());
}
$authInfo = $service->userinfo->get();
log_message('debug', var_export($authInfo, true));
$userInfo = $this->getMySocket()->getUserInfo();
//기존 등록된 사용자가 있는지 검사
$this->getModel()->where(UserSNSModel::SITE, $this->_site);
$entity = $this->getModel()->getEntityByID($authInfo['id']);
$entity = $this->getModel()->getEntityByID($userInfo['id']);
if ($entity === null) {
//없다면 새로 등록
$formDatas = [
'site' => $this->_site,
'id' => $authInfo['id'],
'name' => $authInfo['name'],
'email' => $authInfo['email'],
'detail' => json_encode($authInfo),
'id' => $userInfo['id'],
'name' => $userInfo['name'],
'email' => $userInfo['email'],
'detail' => var_export($userInfo, true),
'status' => 'standby',
];
$entity = $this->getModel()->create($formDatas);
@ -98,13 +62,13 @@ class GoogleAuth extends MyAuth
if (
$entity->status !== DEFAULTS['STATUS']
) {
throw new PageNotFoundException("{$this->_site}}의{$authInfo['email']}:{$authInfo['name']}님은 " . $entity->status . "입니다");
throw new PageNotFoundException("{$this->_site}}의{$userInfo['email']}:{$userInfo['name']}님은 " . $entity->status . "입니다");
}
//local db 사용와의 연결 확인
$userModel = model(UserModel::class);
$user_entity = $userModel->getEntityByID($entity->getID());
if ($user_entity === null) {
throw new PageNotFoundException("{$this->_site}{$authInfo['email']}:{$authInfo['name']}님은 아직 사용자 연결이 이루어지지 않았습니다. ");
throw new PageNotFoundException("{$this->_site}{$userInfo['email']}:{$userInfo['name']}님은 아직 사용자 연결이 이루어지지 않았습니다. ");
}
return $user_entity;
} catch (\Google_Service_Exception $e) {

View File

@ -34,6 +34,7 @@ class LocalAuth extends MyAuth
throw new \Exception("사용자ID: {$formDatas['id']}가 존재하지 않습니다.");
}
if (!password_verify($formDatas['passwd'], $entity->passwd)) {
// log_message("error", "암호: {$formDatas['passwd']}, {$entity->passwd}");
throw new \Exception("암호가 맞지 않습니다.");
}
return $entity;

View File

@ -14,7 +14,7 @@ abstract class MyAuth extends CommonLibrary
$this->_session = \Config\Services::session();
}
final public function setLogin(UserEntity $entity): void
final public function login(UserEntity $entity): void
{
$this->_session->set(SESSION_NAMES['ISLOGIN'], true);
$this->_session->set(SESSION_NAMES['AUTH'], [
@ -23,4 +23,32 @@ abstract class MyAuth extends CommonLibrary
'role' => $entity->role
]);
}
final public function logout(): void
{
// 세션 데이터 삭제
$this->_session->remove(SESSION_NAMES['ISLOGIN']);
$this->_session->remove(SESSION_NAMES['AUTH']);
// 모든 세션 데이터 삭제
$this->_session->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->_session->regenerate(true);
}
}

View File

@ -3,47 +3,76 @@
namespace App\Libraries\MySocket;
use CodeIgniter\Config\Services;
use CodeIgniter\Exceptions\ConfigException;
use Google\Client;
use Google\Service\Oauth2;
class GoogleSocket extends Client
class GoogleSocket extends MySocket
{
private $session;
private string $_access_token = "";
private string $_token_name = "access_token";
private string $_token_type = "";
private string $_google_oauth_version = "v3";
public function __construct()
{
parent::__construct();
$this->setClientId(env('socket.google.client.id'));
$this->setClientSecret(env('socket.google.client.key'));
$this->setRedirectUri(base_url(env('socket.google.client.callback_url')));
$this->addScope(Oauth2::USERINFO_EMAIL);
$this->addScope(Oauth2::USERINFO_PROFILE);
// $this->setPrompt('select_account consent');
// $this->setAccessType('offline');
// SSL 검증 비활성화
$this->setHttpClient(new \GuzzleHttp\Client(['verify' => false]));
// 사용자 정의 CA 번들 사용
// $this->setHttpClient(new \GuzzleHttp\Client(['verify' => '/path/to/cacert.pem']));
$this->session = Services::session();
}
public function createAuthUrl(): string
{
$options = http_build_query([
'response_type' => 'code',
'client_id' => env('socket.google.client.id'),
'redirect_uri' => base_url(env('socket.google.client.callback_url')),
'scope' => "https://www.googleapis.com/auth/userinfo.profile openid https://www.googleapis.com/auth/userinfo.email",
'access_type' => 'offline',
'prompt' => 'consent'
]);
//기본적으로 검색할 범위를 지정하고 사용자를 Google OAuth 동의 화면으로 리디렉션합니다
return "https://accounts.google.com/o/oauth2/v2/auth?" . $options;
}
// (object) array(
// 'access_token' => 'sdfsdfsdfsdf',
// 'expires_in' => 3599,
// 'refresh_token' => 'sdfsdf',
// 'scope' => 'https://www.googleapis.com/auth/userinfo.profile openid https://www.googleapis.com/auth/userinfo.email',
// 'token_type' => 'Bearer',
// 'id_token' => 'fadfasdfsadf',
// )
public function setToken(string $access_code): void
{
// 토큰 정보 가져오기
$tokenInfo = $this->fetchAccessTokenWithAuthCode($access_code);
$options = [
'code' => $access_code,
'client_id' => env('socket.google.client.id'),
'client_secret' => env('socket.google.client.key'),
'redirect_uri' => base_url(env('socket.google.client.callback_url')),
'grant_type' => 'authorization_code',
];
$response = $this->post("https://accounts.google.com/o/oauth2/token", $options);
$tokenInfo = json_decode($response->getBody(), true);
if (isset($tokenInfo['error'])) {
throw new ConfigException($tokenInfo['error']);
$message = sprintf(
"Google: %s에서 API 호출 실패: \n--request options--\n%s\n--response--\n%s\n",
__FUNCTION__,
var_export($options, true),
var_export($response, true)
);
log_message("error", $message);
throw new \Exception($message);
}
// dd($tokenInfo);
if (!isset($tokenInfo[$this->_token_name]) || empty($tokenInfo[$this->_token_name])) {
$message = sprintf(
"Google: Token 정보가 없습니다.\n--tokenInfo--\n%s\n",
__FUNCTION__,
var_export($tokenInfo, true)
);
log_message("error", $message);
throw new \Exception($message);
}
//토큰 Type정보 가져오기 getUserInfo()에서 사용
$this->_token_type = $tokenInfo['token_type'];
// 토큰 정보 가져오기
$this->_access_token = $tokenInfo[$this->_token_name];
// Google Service에 접근하기 위해 Access Token 설정
$this->setAccessToken([
'access_token' => $this->_access_token,
'expires_in' => 3600,
'created' => time(),
]);
// 세션에 Token 값 설정
$this->session->set($this->_token_name, $this->_access_token);
}
@ -53,36 +82,59 @@ class GoogleSocket extends Client
return $this->session->get($this->_token_name);
}
public function isAccessTokenValid(): bool
// throw new \Exception(__METHOD__ . "에서 데이터 처리 필요");
// DEBUG - 2023-07-13 12:54:51 --> \Google\Service\Oauth2\Userinfo::__set_state(array(
// 'internal_gapi_mappings' =>
// 'familyName' => 'family_name',
// 'givenName' => 'given_name',
// 'verifiedEmail' => 'verified_email',
// ),
// 'modelData' =>
// array (
// 'verified_email' => true,
// 'given_name' => '이름',
// 'family_name' => '성',
// ),
// 'processed' =>
// array (
// ),
// 'email' => 'twsdfsew342s@gmail.com',
// 'familyName' => '성',
// 'gender' => NULL,
// 'givenName' => '이름',
// 'hd' => NULL,
// 'id' => '103667492432234234236838324',
// 'link' => NULL,
// 'locale' => 'ko',
// 'name' => '성이름',
// 'picture' => 'https://lh3.googleusercontent.com/a/AAcHTteFSgefsdfsdRJBkJA2tBEmg4PQrvI1Ta_5IXu5=s96-c',
// 'verifiedEmail' => true,
// ))
public function getUserInfo(): array
{
// 액세스 토큰이 없으면 유효하지 않음
if (empty($this->getAccessToken())) {
return false;
$options = ["Authorization: {$this->_token_type} {$this->getToken()}"];
$response = $this->get("https://www.googleapis.com/oauth2/{$this->_google_oauth_version}/userinfo", $options);
$userInfo = json_decode($response->getBody(), true);
if (isset($userInfo['error'])) {
$message = sprintf(
"Google: %s에서 API 호출 실패: \n--request options--\n%s\n--response--\n%s\n",
__FUNCTION__,
var_export($options, true),
var_export($response, true)
);
log_message("error", $message);
throw new \Exception($message);
}
// 토큰의 만료 시간 확인
$expirationTime = $this->getTokenExpirationTime();
if ($expirationTime === null) {
return false;
if (isset($userInfo['email']) || empty($tokenInfo['email'])) {
$message = sprintf(
"Google: User 정보가 없습니다.\n--userInfo--\n%s\n",
__FUNCTION__,
var_export($userInfo, true)
);
log_message("error", $message);
throw new \Exception($message);
}
// 현재 시간과 비교하여 유효성 확인
return $expirationTime > time();
}
private function getTokenExpirationTime(): ?int
{
// 토큰 정보 디코딩
$tokenParts = explode('.', $this->getToken());
if (count($tokenParts) !== 3) {
return null;
}
$payload = json_decode(base64_decode($tokenParts[1]), true);
if (!isset($payload['exp'])) {
return null;
}
return $payload['exp'];
// 사용자정보 가져오기
return $userInfo;
}
}

View File

@ -0,0 +1,88 @@
<?php
namespace App\Libraries\MySocket;
use CodeIgniter\Config\Services;
use CodeIgniter\Exceptions\ConfigException;
use Google\Client;
use Google\Service\Oauth2;
class GoogleSocketAPI extends Client
{
private $session;
private string $_access_token = "";
private string $_token_name = "access_token";
public function __construct()
{
parent::__construct();
$this->setClientId(env('socket.google.client.id'));
$this->setClientSecret(env('socket.google.client.key'));
$this->setRedirectUri(base_url(env('socket.google.client.callback_url')));
$this->addScope(Oauth2::USERINFO_EMAIL);
$this->addScope(Oauth2::USERINFO_PROFILE);
// $this->setPrompt('select_account consent');
// $this->setAccessType('offline');
// SSL 검증 비활성화
$this->setHttpClient(new \GuzzleHttp\Client(['verify' => false]));
// 사용자 정의 CA 번들 사용
// $this->setHttpClient(new \GuzzleHttp\Client(['verify' => '/path/to/cacert.pem']));
$this->session = Services::session();
}
public function setToken(string $access_code): void
{
// 토큰 정보 가져오기
$tokenInfo = $this->fetchAccessTokenWithAuthCode($access_code);
if (isset($tokenInfo['error'])) {
throw new ConfigException($tokenInfo['error']);
}
// dd($tokenInfo);
$this->_access_token = $tokenInfo[$this->_token_name];
// Google Service에 접근하기 위해 Access Token 설정
$this->setAccessToken([
'access_token' => $this->_access_token,
'expires_in' => 3600,
'created' => time(),
]);
// 세션에 Token 값 설정
$this->session->set($this->_token_name, $this->_access_token);
}
public function getToken(): string
{
return $this->session->get($this->_token_name);
}
public function isAccessTokenValid(): bool
{
// 액세스 토큰이 없으면 유효하지 않음
if (empty($this->getAccessToken())) {
return false;
}
// 토큰의 만료 시간 확인
$expirationTime = $this->getTokenExpirationTime();
if ($expirationTime === null) {
return false;
}
// 현재 시간과 비교하여 유효성 확인
return $expirationTime > time();
}
private function getTokenExpirationTime(): ?int
{
// 토큰 정보 디코딩
$tokenParts = explode('.', $this->getToken());
if (count($tokenParts) !== 3) {
return null;
}
$payload = json_decode(base64_decode($tokenParts[1]), true);
if (!isset($payload['exp'])) {
return null;
}
return $payload['exp'];
}
}

View File

@ -1,28 +0,0 @@
<?= $this->extend(LAYOUTS[$viewDatas['layout']]['path']) ?>
<?= $this->section('content') ?>
<div class="layout_middle">
<div class="layout_right">
<div id="container" class="content">
<link href="/css/<?= $viewDatas['layout'] ?>/login.css" media="screen" rel="stylesheet" type="text/css" />
<div class="login-container border rounded p-4 shadow">
<?= form_open(current_url(), $viewDatas['forms']['attributes'], $viewDatas['forms']['hiddens']) ?>
<h2 class="text-center mb-4">로그인</h2>
<div class="mb-3">
<label for="userId" class="form-label">아이디</label>
<input type="text" class="form-control" id="userId" name="id" value="<?= set_value('id') ?>" required>
</div>
<div class="mb-3">
<label for="userPassword" class="form-label">비밀번호</label>
<input type="password" class="form-control" id="userPassword" name="passwd" required>
</div>
<div class="d-flex justify-content-between align-items-center">
<button type="submit" class="btn btn-primary">로그인</button>
<?= anchor($viewDatas['google_url'], ICONS['GOOGLE'] . 'Google 로그인', ["class" => "btn btn-danger"]) ?>
<button type="button" class="btn btn-outline-primary">회원가입</button>
</div>
<?= form_close(); ?>
</div>
</div>
</div>
</div>
<?= $this->endSection() ?>

View File

@ -6,7 +6,7 @@
<link href="/css/<?= $viewDatas['layout'] ?>/login.css" media="screen" rel="stylesheet" type="text/css" />
<div class="login-container border rounded p-4 shadow">
<?= form_open(current_url(), $viewDatas['forms']['attributes'], $viewDatas['forms']['hiddens']) ?>
<h2 class="text-center mb-4">로그인</h2>
<h2 class="text-center mb-5">CF-MGR 로그인</h2>
<div class="mb-3">
<label for="userId" class="form-label">아이디</label>
<input type="text" class="form-control" id="userId" name="id" value="<?= set_value('id') ?>" required>
@ -16,7 +16,7 @@
<input type="password" class="form-control" id="userPassword" name="passwd" required>
</div>
<div class="d-flex justify-content-between align-items-center">
<button type="submit" class="btn btn-primary">로그인</button>
<button type="submit" class="btn btn-primary">Login</button>
<?= anchor($viewDatas['google_url'], ICONS['GOOGLE'] . 'Google 로그인', ["class" => "btn btn-danger"]) ?>
<button type="button" class="btn btn-outline-primary">회원가입</button>
</div>
@ -24,5 +24,4 @@
</div>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->endSection() ?>

View File

@ -23,7 +23,8 @@
</head>
<body>
<?= $this->renderSection('content') ?></div>
<?php if ($error = session('error')): ?><?= $viewDatas['helper']->alert($error) ?><?php endif ?>
<?= $this->renderSection('content') ?>
</body>
</html>

View File

@ -23,9 +23,8 @@
</head>
<body>
<div class="middle">
<?= $this->renderSection('content') ?>
</div>
<?php if ($error = session('error')): ?><?= $viewDatas['helper']->alert($error) ?><?php endif ?>
<div class="middle"><?= $this->renderSection('content') ?></div>
</body>
</html>

View File

@ -23,6 +23,7 @@
</head>
<body>
<?php if ($error = session('error')): ?><?= $viewDatas['helper']->alert($error) ?><?php endif ?>
<?= $this->renderSection('content') ?></div>
</body>

View File

@ -1 +0,0 @@
<?= $viewDatas['session']->getFlashdata(SESSION_NAMES['RETURN_MSG']) ? $viewDatas['helper']->alert($viewDatas['session']->getFlashdata(SESSION_NAMES['RETURN_MSG'])) : "" ?></div>

View File

@ -1 +0,0 @@
<?= $viewDatas['session']->getFlashdata(SESSION_NAMES['RETURN_MSG']) ? $viewDatas['helper']->alert($viewDatas['session']->getFlashdata(SESSION_NAMES['RETURN_MSG'])) : "" ?>

View File

@ -8,7 +8,6 @@
margin: 0px;
padding: 0px;
border: 0px;
/* font-size: 15px; */
}
html,

View File

@ -8,5 +8,4 @@
margin: 0px;
padding: 0px;
border: 0px;
/* font-size: 15px; */
}

View File

@ -8,7 +8,6 @@
margin: 0px;
padding: 0px;
border: 0px;
/* font-size: 15px; */
}
html,