cfmgrv4 init...1

This commit is contained in:
최준흠 2024-10-06 17:02:41 +09:00
parent 2bbea6a4b0
commit 904e79a7b6
10 changed files with 175 additions and 283 deletions

View File

@ -6,15 +6,14 @@ use App\Controllers\BaseController;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
use App\Traits\AuthTrait;
abstract class CommonController extends BaseController
{
use AuthTrait;
private $_viewDatas = [];
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
parent::initController($request, $response, $logger);
$this->session = service('session');
helper("common");
}
final public function __get($name)

View File

@ -18,7 +18,7 @@ abstract class MVController extends CommonController
{
parent::initController($request, $response, $logger);
helper('common');
$this->session = $this->session_AuthTrait();
$this->session = service('session');
}
abstract protected function getModel(): mixed;
//Field별 Form Rule용
@ -89,7 +89,9 @@ abstract class MVController extends CommonController
));
}
}
protected function create_form_process(): void {}
protected function create_form_process(): void
{
}
final protected function create_form_procedure(): RedirectResponse|string
{
try {
@ -265,7 +267,6 @@ abstract class MVController extends CommonController
$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();
}
}
@ -331,8 +332,8 @@ abstract class MVController extends CommonController
private function list_pagination_process($pager_group = 'default', int $segment = 0, $template = 'default_full'): string
{
//Page, Per_page필요부분
$this->page = (int)$this->request->getVar('page') ?: 1;
$this->per_page = (int)$this->request->getVar('per_page') ?: intval(getenv("mvc.default.list.per_page"));
$this->page = (int) $this->request->getVar('page') ?: 1;
$this->per_page = (int) $this->request->getVar('per_page') ?: intval(getenv("mvc.default.list.per_page"));
//줄수 처리용
$page_options = array("" => "줄수선택");
for ($i = $this->per_page; $i <= $this->total_count; $i += $this->per_page) {
@ -390,7 +391,9 @@ abstract class MVController extends CommonController
//모델 처리
$this->entitys = $this->list_entitys_process();
//setting return_url to session flashdata
$this->session->setFlashdata(SESSION_NAMES['RETURN_URL'], current_url() . $this->uri->getQuery() ? "?" . $this->uri->getQuery() : "");
// RETURN_URL을 일반 세션 데이터로 저장
$this->session->setFlashdata(SESSION_NAMES['RETURN_URL'], current_url() . ($this->uri->getQuery() ? "?" . $this->uri->getQuery() : ""));
return view(
$this->view_path . "/index",
['viewDatas' => $this->getViewDatas()]
@ -398,7 +401,7 @@ abstract class MVController extends CommonController
} catch (\Exception $e) {
log_message("error", $e->getMessage());
return alert_CommonHelper($e->getMessage(), "back");
// return redirect()->back()->with('return_message', $e->getMessage());
// return redirect()->back()->with(SESSION_NAMES['RETURN_MSG'], $e->getMessage());
}
}

View File

@ -2,14 +2,16 @@
namespace App\Controllers;
use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Validation\Validation;
use Psr\Log\LoggerInterface;
use CodeIgniter\Validation\Validation;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\RedirectResponse;
use App\Models\UserModel;
use App\Libraries\MyAuth\LocalAuth;
use App\Libraries\MyAuth\GoogleAuth;
class UserController extends FrontController
{
private $_model = null;
@ -80,40 +82,41 @@ class UserController extends FrontController
return $this->create_form_procedure();
}
//로그인처리
protected function create_process(): void
{
// $this->create_validate($this->action, $this->fields);
$this->formDatas = $this->getFormDatas();
if (!isset($this->formDatas['id']) || !$this->formDatas['id']) {
throw new \Exception("사용자ID를 입력해주세요!");
}
if (!isset($this->formDatas['passwd']) || !$this->formDatas['passwd']) {
throw new \Exception("암호를 입력해주세요!");
}
$entity = $this->getModel()->getEntityByID($this->formDatas['id']);
if (is_null($entity) || !isset($entity->passwd)) {
throw new \Exception("사용자ID: {$this->formDatas['id']}가 존재하지 않습니다.");
}
if (password_verify($this->formDatas['passwd'], $entity->passwd)) {
//Session에 Login 정보전달
$this->session->set([
SESSION_NAMES['AUTH'] => [
'uid' => $entity->getPK(),
'name' => $entity->getTitle(),
'email' => $entity->email,
'role' => $entity->role
],
SESSION_NAMES['ISLOGIN'] => true
]);
$this->message = "로그인 성공";
} else {
throw new \Exception("로그인 실패");
}
}
public function create(): RedirectResponse|string
{
$this->init(__FUNCTION__);
return $this->create_procedure();
$this->init('login');
//Transaction Start
$this->getModel()->transStart();
try {
$site = $this->request->getVar('site');
switch ($site) {
case 'local':
$this->create_validate($this->action, $this->fields);
$this->formDatas = $this->getFormDatas();
$auth = new LocalAuth();
$entity = $auth->checkUser($this->formDatas);
break;
case 'google':
$auth = new GoogleAuth();
$entity = $auth->checkUser();
break;
default:
throw new \Exception("{$site}는 아직 지원하지 않는 사이트입니다.");
}
$auth->setLogin($entity);
$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']) ?: "/");
} 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();
}
}
//로그아웃
public function logout(): RedirectResponse

View File

@ -1,24 +1,4 @@
<?php
//로그인체크 한후 권한체크
function isRole_CommonHelper(array $userRoles, $categoryEntity, $roleField = 'isaccess')
{
return in_array($categoryEntity->getRole($roleField), $userRoles);
}
function getValueByKey_CommonHelper($key, array $attributes)
{
$options = array();
$replace_attributes = array();
foreach ($attributes as $idx => $value) {
if ($idx == $key) {
$replace_attributes[$idx] = $value;
} else {
array_push($options, $value);
}
}
return array($replace_attributes, $options);
}
function getRandomString_CommonHelper($length = 10, $characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
{
return substr(str_shuffle($characters), 0, $length);
@ -149,80 +129,6 @@ function alert_CommonHelper(string $msg, $url = null)
return "<script type=\"text/javascript\">{$msg}</script>";
} //
// STATUS가 use가 아닐때 option을 disabled되게 하기위함 (override form_dropdown)
function form_dropdown_test($data = '', $options = [], $selected = [], $extra = ''): string
{
$defaults = [];
if (is_array($data)) {
if (isset($data['selected'])) {
$selected = $data['selected'];
unset($data['selected']); // select tags don't have a selected attribute
}
if (isset($data['options'])) {
$options = $data['options'];
unset($data['options']); // select tags don't use an options attribute
}
} else {
$defaults = ['name' => $data];
}
if (!is_array($selected)) {
$selected = [$selected];
}
if (!is_array($options)) {
$options = [$options];
}
// If no selected state was submitted we will attempt to set it automatically
if (empty($selected)) {
if (is_array($data)) {
if (isset($data['name'], $_POST[$data['name']])) {
$selected = [$_POST[$data['name']]];
}
} elseif (isset($_POST[$data])) {
$selected = [$_POST[$data]];
}
}
// Standardize selected as strings, like the option keys will be
foreach ($selected as $key => $item) {
$selected[$key] = (string) $item;
}
$extra = stringify_attributes($extra);
$multiple = (count($selected) > 1 && stripos($extra, 'multiple') === false) ? ' multiple="multiple"' : '';
$form = '<select ' . rtrim(parse_form_attributes($data, $defaults)) . $extra . $multiple . ">\n";
foreach ($options as $key => $val) {
// Keys should always be strings for strict comparison
$key = (string) $key;
if (is_array($val)) {
if (empty($val)) {
continue;
}
$form .= '<optgroup label="' . $key . "\">\n";
foreach ($val as $optgroupKey => $optgroupVal) {
// Keys should always be strings for strict comparison
$optgroupKey = (string) $optgroupKey;
$sel = in_array($optgroupKey, $selected, true) ? ' selected="selected"' : '';
$form .= '<option value="' . $optgroupKey . '"' . $sel . '>' . $optgroupVal . "</option>\n";
}
$form .= "</optgroup>\n";
} else {
$form .= '<option value="' . $key . '"'
. (in_array($key, $selected, true) ? ' selected="selected"' : '') . '>'
. $val . "</option>\n";
}
}
return $form . "</select>\n";
}
function getListButtonLabel_CommonHelper(string $action, string $label, array $viewDatas, array $extras = []): string
{
switch ($viewDatas['action_form']) {

View File

@ -2,7 +2,10 @@
namespace App\Libraries\MyAuth;
use App\Libraries\MySocket\Web\GoogleSocket;
use \Google\Service\Oauth2;
use App\Models\UserModel;
use App\Models\SNSUserModel;
use App\Libraries\MySocket\GoogleSocket;
use App\Entities\UserEntity;
use App\Entities\SNSUserEntity;
@ -10,6 +13,7 @@ class GoogleAuth extends MyAuth
{
private $_mySocket = null;
private $_site = "GOOGLE";
private $_model = null;
public function __construct()
{
parent::__construct();
@ -18,7 +22,8 @@ class GoogleAuth extends MyAuth
public function getMySocket(): GoogleSocket
{
if ($this->_mySocket === null) {
$this->_mySocket = new GoogleSocket(getenv('yamap.host.url'));
$this->_mySocket = new GoogleSocket();
$this->_mySocket->setAccessToken();
}
return $this->_mySocket;
}
@ -28,83 +33,87 @@ class GoogleAuth extends MyAuth
$button = "";
if (!$this->getMySocket()->getAccessToken()) {
$button = anchor(
$this->getMySocket()->getClient()->createAuthUrl(),
getenv("socket.google.api.url"),
ICONS['GOOGLE'],
["target" => "_self"]
);
}
return $button;
}
public function execute(): UserEntity
final protected function getModel(): SNSUSerModel
{
return new UserEntity();
// try {
// //Google 접근 권한 설정.
// $this->getMySocket()->setAccessToken();
// //Google 서비스 설정
// //$service = new \Google\Service\Oauth2($this->getMySocket());
// $service = new \Google\Service\Oauth2($this->getMySocket());
// $result = $service->userinfo->get();
// log_message("debug", var_export($result, true));
// // throw new \Exception(__METHOD__ . "에서 데이터 처리 필요");
// // DEBUG - 2023-07-13 12:54:51 --> \Google\Service\Oauth2\Userinfo::__set_state(array(
// // 'internal_gapi_mappings' =>
// // array (
// // '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,
// // ))
// //조건에 해당하는 이미 등록된 사용자가 있는지 검사
// $snsEntity = null;
// try {
// $snsEntity = $this->getUserSNSModel()->asObject(SNSUSerEntity::class)->where(
// array("site" => $this->_site, "id" => $result['id'])
// )->first();
// } catch (\Exception $e) {
// $snsEntity = new SNSUSerEntity([
// 'site' => $this->_site,
// 'id' => $result['id'],
// 'name' => $result['name'],
// 'email' => $result['email'],
// 'detail' => json_encode($result),
// 'status' => 'standby',
// ]);
// $snsEntity = $this->getUserSNSModel()->create($snsEntity);
// }
// //상태가 use(승인완료)가 아니라면
// if ($snsEntity->status !== DEFAULTS['STATUS']) {
// throw new \Exception("{$this->_site}}의{$result['email']}:{$result['name']}님은 " . $snsEntity->status . "입니다");
// }
// //user_id가 연결되어있지 않았다면
// if (!$snsEntity->getID()) {
// throw new \Exception("{$this->_site}의{$result['email']}:{$result['name']}님은 아직 사용자 지정이 되지 않았습니다. ");
// }
// //인증된 사용자 정보를 가져온후 로그인처리
// $entity = $this->getUserModel()->getEntityByID($snsEntity->getID());
// return $this->setSession_process($entity);;
// } catch (\Exception $e) {
// throw new \Exception("관리자에게 문의하시기 바랍니다.<BR>{$e->getMessage()}");
// }
if ($this->_model === null) {
$this->_model = new SNSUserModel();
}
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());
$authInfo = $service->userinfo->get();
log_message("debug", var_export($authInfo, true));
//기존 등록된 사용자가 있는지 검사
$this->getModel()->where(SNSUserModel::SITE, $this->_site);
$entity = $this->getModel()->getEntityByID($authInfo['id']);
if ($entity === null) {
//없다면 새로 등록
$formDatas = [
'site' => $this->_site,
'id' => $authInfo['id'],
'name' => $authInfo['name'],
'email' => $authInfo['email'],
'detail' => json_encode($authInfo),
'status' => 'standby',
];
$entity = $this->getModel()->create($formDatas);
}
//상태가 use(승인완료)가 아니라면
if (
$entity->status !== DEFAULTS['STATUS']
) {
throw new \Exception("{$this->_site}}의{$authInfo['email']}:{$authInfo['name']}님은 " . $entity->status . "입니다");
}
//local db 사용와의 연결 확인
$userModel = new UserModel();
$userEntity = $userModel->getEntityByID($entity->getID());
if ($userEntity === null) {
throw new \Exception("{$this->_site}{$authInfo['email']}:{$authInfo['name']}님은 아직 사용자 연결이 이루어지지 않았습니다. ");
}
return $userEntity;
} catch (\Exception $e) {
throw new \Exception("관리자에게 문의하시기 바랍니다.<BR>{$e->getMessage()}");
}
}
}

View File

@ -3,31 +3,44 @@
namespace App\Libraries\MyAuth;
use App\Entities\UserEntity;
use App\Models\UserModel;
class LocalAuth extends MyAuth
{
private $_model = null;
public function __construct()
{
parent::__construct();
}
public function getAuthButton()
public function getAuthButton(): string
{
return "";
}
public function execute(): UserEntity
final protected function getModel(): UserModel
{
return new UserEntity();
// $formDatas = $this->getFormDatas();
// if (!isset($formDatas['id']) || !$formDatas['id'] || !isset($formDatas['passwd']) || !$formDatas['passwd']) {
// throw new \Exception("ID 나 암호의 값이 없습니다.");
// }
// $entity = $this->getUserModel()->getEntity(['id' => $formDatas['id'], 'status' => DEFAULTS['STATUS']]);
// if (!password_verify($formDatas['passwd'], $entity->passwd)) {
// throw new \Exception("암호가 맞지않습니다.");
// }
// //Session에 인증정보 설정
// return $this->setSession_process($entity);;
if ($this->_model === null) {
$this->_model = new UserModel();
}
return $this->_model;
}
public function checkUser(array $formDatas): UserEntity
{
if (!isset($formDatas['id']) || !$formDatas['id']) {
throw new \Exception("사용자ID를 입력해주세요!");
}
if (!isset($formDatas['passwd']) || !$formDatas['passwd']) {
throw new \Exception("암호를 입력해주세요!");
}
$entity = $this->getModel()->getEntityByID($formDatas['id']);
if (is_null($entity) || !isset($entity->passwd)) {
throw new \Exception("사용자ID: {$formDatas['id']}가 존재하지 않습니다.");
}
if (!password_verify($formDatas['passwd'], $entity->passwd)) {
throw new \Exception("암호가 맞지 않습니다.");
}
return $entity;
}
}

View File

@ -3,39 +3,19 @@
namespace App\Libraries\MyAuth;
use App\Entities\UserEntity;
use App\Models\UserModel;
use App\Models\SNSUserModel;
use App\Libraries\CommonLibrary;
// 참고:https://github.com/SyntaxPhoenix/iloclient
abstract class MyAuth
abstract class MyAuth extends CommonLibrary
{
private $_userModel = null;
private $_snsUserModel = null;
protected $_session = null;
private $_session = null;
protected function __construct()
{
$this->_session = \Config\Services::session();
}
abstract public function getAuthButton();
abstract public function execute(): UserEntity;
final protected function getUserModel(): UserModel
{
if (is_null($this->_userModel)) {
$this->_userModel = new UserModel();
}
return $this->_userModel;
}
final protected function getUserSNSModel(): SNSUSerModel
{
if (is_null($this->_snsUserModel)) {
$this->_snsUserModel = new SNSUserModel();
}
return $this->_snsUserModel;
}
protected function setSession_process(UserEntity $entity): UserEntity
final public function setLogin(UserEntity $entity): void
{
$this->_session->set(SESSION_NAMES['ISLOGIN'], true);
$this->_session->set(SESSION_NAMES['AUTH'], [
@ -43,6 +23,5 @@ abstract class MyAuth
'name' => $entity->getTitle(),
'role' => $entity->role
]);
return $entity;
}
}

View File

@ -10,10 +10,12 @@ class SNSUserModel extends CommonModel
const TABLE = "sns_users";
const PK = "uid";
const TITLE = "name";
const SITE = "site";
protected $table = self::TABLE;
protected $primaryKey = self::PK;
protected $returnType = SNSUSerEntity::class;
protected $allowedFields = [
"site",
"id",
"name",
"email",
@ -37,6 +39,9 @@ class SNSUserModel extends CommonModel
case $this->getTitleField():
$rule = "required|trim|string";
break;
case "site":
$rule = "required|trim|string";
break;
case "email":
$rule = "if_exist|trim|valid_email";
break;

View File

@ -1,25 +0,0 @@
<?php
namespace App\Traits;
use CodeIgniter\Session\Session;
trait AuthTrait
{
final protected function session_AuthTrait(): Session
{
$session = \Config\Services::session();
$session->set('currentRoles', [DEFAULTS["ROLE"]]);
if ($session->get(SESSION_NAMES['ISLOGIN'])) {
$session->set(SESSION_NAMES['ISLOGIN'], true);
$session->set(
'currentRoles',
explode(
DEFAULTS['DELIMITER_ROLE'],
$session->get(SESSION_NAMES['AUTH'])['role']
)
);
}
return $session;
}
}

View File

@ -13,12 +13,12 @@
<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="button" class="btn btn-outline-primary">회원가입</button>
<button type="button" class="btn btn-primary">
<button type="submit" class="btn btn-primary" name="site" value="local">로그인</button>
<button type="submit" class="btn btn-danger" name="site" value="google">
<img src="https://www.google.com/favicon.ico" alt="Google" width="20" height="20" class="me-2">
Google 로그인
</button>
<button type="button" class="btn btn-outline-primary">회원가입</button>
</div>
<?= form_close(); ?>
</div>