cfmgrv4 init...2

This commit is contained in:
최준흠 2024-10-09 19:42:40 +09:00
parent cb88715ed4
commit 4b3edf80f0
9 changed files with 280 additions and 48 deletions

View File

@ -36,6 +36,13 @@ $routes->group('admin', ['namespace' => 'App\Controllers\Admin', 'filter' => 'au
$routes->post('batchjob', 'UserController::batcjob');
$routes->get('download/(:alpha)', 'UserController::download/$1');
});
$routes->group('usersns', function ($routes) {
$routes->get('/', 'UserSNSController::index');
$routes->get('delete/(:num)', 'UserSNSController::delete/$1', ['filter' => 'authFilter:master']);
$routes->get('toggle/(:num)/(:any)', 'UserSNSController::toggle/$1/$2', ['filter' => 'authFilter:master']);
$routes->post('batchjob', 'UserSNSController::batcjob', ['filter' => 'authFilter:master']);
$routes->get('download/(:alpha)', 'UserSNSController::download/$1');
});
$routes->group('mapurl', function ($routes) {
$routes->get('/', 'MapurlController::index');
$routes->get('create', 'MapurlController::create_form');

View File

@ -0,0 +1,109 @@
<?php
namespace App\Controllers\Admin;
use App\Helpers\UserSNSHelper;
use App\Models\UserSNSModel;
use CodeIgniter\HTTP\DownloadResponse;
use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Validation\Validation;
use Psr\Log\LoggerInterface;
class UserSNSController extends AdminController
{
private $_model = null;
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
parent::initController($request, $response, $logger);
$this->class_name = "UserSNS";
$this->class_path .= $this->class_name;
$this->title = lang("{$this->class_path}.title");
$this->helper = new UserSNSHelper();
}
protected function getModel(): UserSNSModel
{
if ($this->_model === null) {
$this->_model = new UserSNSModel();
}
return $this->_model;
}
protected function setFormFieldRule($field, Validation $validation, string $action): Validation
{
switch ($field) {
default:
$validation = parent::setFormFieldRule($field, $validation, $action);
break;
}
return $validation;
}
protected function getFormFieldOption(string $field, array $options = []): array
{
switch ($field) {
default:
$options = parent::getFormFieldOption($field, $options);
break;
}
return $options;
}
protected function getFormData(string $field, array $formDatas): array
{
switch ($field) {
default:
$formDatas = parent::getFormData($field, $formDatas);
break;
}
return $formDatas;
}
private function init(string $action): void
{
$this->action = $action;
$this->fields = ['site', 'id', $this->getModel()::TITLE, 'email'];
$this->field_rules = $this->getModel()->getFieldRules($this->action, $this->fields);
$this->filter_fields = ['status'];
$this->field_options = $this->getFormFieldOptions($this->filter_fields);
}
//수정
public function modify_form(string $uid): RedirectResponse|string
{
$this->init('modify');
return $this->modify_form_procedure($uid);
}
public function modify(string $uid): RedirectResponse|string
{
$this->init(__FUNCTION__);
return $this->modify_procedure($uid);
}
//일괄작업
public function batcjob(): RedirectResponse
{
$this->action = __FUNCTION__;
$this->fields = ['status'];
$this->field_rules = $this->getModel()->getFieldRules($this->action, $this->fields);
return $this->batcjob_procedure();
}
// 리스트
public function index(): string
{
$this->action = __FUNCTION__;
$this->fields = ['site', 'id', $this->getModel()::TITLE, 'email', 'status'];
$this->field_rules = $this->getModel()->getFieldRules($this->action, $this->fields);
$this->filter_fields = ['status'];
$this->field_options = $this->getFormFieldOptions($this->filter_fields);
$this->batchjob_fields = ['status'];
return $this->list_procedure();
}
// Download
public function download(string $output_type, $uid = false): DownloadResponse|string
{
$this->action = __FUNCTION__;
$this->fields = ['site', 'id', $this->getModel()::TITLE, 'email', 'status'];
$this->field_rules = $this->getModel()->getFieldRules($this->action, $this->fields);
$this->filter_fields = ['status'];
$this->field_options = $this->getFormFieldOptions($this->filter_fields);
$this->batchjob_fields = ['status'];
return $this->download_procedure($output_type, $uid);
}
}

View File

@ -5,10 +5,11 @@ namespace App\Controllers;
use App\Helpers\UserHelper;
use App\Libraries\MyAuth\GoogleAuth;
use App\Libraries\MyAuth\LocalAuth;
use App\Libraries\MySocket\GoogleSocket;
use App\Models\UserModel;
use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Validation\Validation;
use Google\Service\Oauth2;
@ -70,17 +71,7 @@ class UserController extends FrontController
}
return $formDatas;
}
private function getGoogleAuthUrl()
{
$params = [
'client_id' => env('socket.google.client.id'),
'redirect_uri' => env('socket.google.client.callback_url'),
'response_type' => 'code', // 이 줄을 추가하세요
'scope' => Oauth2::USERINFO_EMAIL . " " . Oauth2::USERINFO_PROFILE,
'state' => env('socket.google.client.token_name'),
];
return env('socket.google.api.uri') . '?' . http_build_query($params);
}
private function init(string $action): void
{
$this->action = $action;
@ -94,8 +85,12 @@ class UserController extends FrontController
try {
helper(['form']);
$this->create_form_process();
//구글 로그인 BUTTON용
$google_socket = new GoogleSocket();
$this->google_url = $google_socket->createAuthUrl();
$this->session->keepFlashdata(SESSION_NAMES['RETURN_URL']);
$this->google_url = $this->getGoogleAuthUrl();
$this->forms = ['attributes' => ['method' => "post",], 'hiddens' => []];
return view(
$this->view_path . "login",
@ -141,7 +136,7 @@ class UserController extends FrontController
if (!$access_code) {
throw new \Exception("구글 로그인 실패");
}
$auth = new GoogleAuth(env('socket.google.client.token_name'), $access_code);
$auth = new GoogleAuth($access_code);
$auth->setLogin($auth->checkUser());
$this->message = "로그인 성공";
$this->getModel()->transCommit();

View File

@ -3,9 +3,9 @@
namespace App\Entities;
use App\Entities\CommonEntity;
use App\Models\SNSUserModel;
use App\Models\UserSNSModel;
class SNSUserEntity extends CommonEntity
class UserSNSEntity extends CommonEntity
{
public function __toString(): string
{
@ -13,17 +13,17 @@ class SNSUserEntity extends CommonEntity
}
public function getTitle(): string
{
return $this->attributes[SNSUserModel::TITLE];
return $this->attributes[UserSNSModel::TITLE];
}
public function setTitle(string $title): void
{
$this->attributes[SNSUserModel::TITLE] = $title;
$this->attributes[UserSNSModel::TITLE] = $title;
}
//Common Function
public function getPK(): int
{
return $this->attributes[SNSUserModel::PK];
return $this->attributes[UserSNSModel::PK];
}
public function getID(): string
{

View File

@ -0,0 +1,36 @@
<?php
namespace App\Helpers;
use App\Models\UserSNSModel;
class UserSNSHelper extends CommonHelper
{
public function __construct()
{
parent::__construct();
}
public function getFieldForm(string $field, mixed $value, array $viewDatas, array $extras = []): string
{
$value = $value ?: DEFAULTS['EMPTY'];
switch ($field) {
case 'id':
case UserSNSModel::TITLE:
$form = form_input($field, $value, $extras);
break;
case 'email':
$form = form_input($field, $value, ["placeholder" => "예)test@example.com", ...$extras]);
break;
case 'detail':
$form = form_textarea($field, $value == DEFAULTS['EMPTY'] ? "@\n*\nm\nwww" : $value, [
'rows' => '20',
...$extras
]);
break;
default:
$form = parent::getFieldForm($field, $value, $viewDatas, $extras);
break;
}
return $form;
} //
}

View File

@ -0,0 +1,19 @@
<?php
return [
'title' => "SNS 계정정보",
'label' => [
'uid' => "번호",
'site' => "사이트",
'id' => "계정",
'name' => "이름",
'email' => "메일",
'detail' => "상세정보",
'status' => "상태",
'updated_at' => "수정일",
'created_at' => "작성일",
],
"STATUS" => [
"use" => "사용",
"unuse" => "사용않함",
],
];

View File

@ -4,7 +4,7 @@ namespace App\Libraries\MyAuth;
use App\Entities\UserEntity;
use App\Libraries\MySocket\GoogleSocket;
use App\Models\SNSUserModel;
use App\Models\UserSNSModel;
use App\Models\UserModel;
use CodeIgniter\Exceptions\PageNotFoundException;
use Google\Service\Oauth2;
@ -13,29 +13,27 @@ class GoogleAuth extends MyAuth
{
private ?GoogleSocket $_mySocket = null;
private string $_site = "GOOGLE";
private ?SNSUserModel $_model = null;
private string $token_code = "";
private ?UserSNSModel $_model = null;
private string $access_code = "";
public function __construct(string $token_code, string $access_code)
public function __construct(string $access_code)
{
parent::__construct();
$this->token_code = $token_code;
$this->access_code = $access_code;
}
public function getMySocket(): GoogleSocket
{
if ($this->_mySocket === null) {
$this->_mySocket = new GoogleSocket($this->token_code);
$this->_mySocket = new GoogleSocket();
$this->_mySocket->setToken($this->access_code);
}
return $this->_mySocket;
}
final protected function getModel(): SNSUserModel
final protected function getModel(): UserSNSModel
{
if ($this->_model === null) {
$this->_model = model(SNSUserModel::class);
$this->_model = model(UserSNSModel::class);
}
return $this->_model;
}
@ -71,12 +69,18 @@ class GoogleAuth extends MyAuth
public function checkUser(): UserEntity
{
try {
//Google 서비스 설정
// 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));
//기존 등록된 사용자가 있는지 검사
$this->getModel()->where(SNSUserModel::SITE, $this->_site);
$this->getModel()->where(UserSNSModel::SITE, $this->_site);
$entity = $this->getModel()->getEntityByID($authInfo['id']);
if ($entity === null) {
//없다면 새로 등록
@ -103,6 +107,9 @@ class GoogleAuth extends MyAuth
throw new PageNotFoundException("{$this->_site}{$authInfo['email']}:{$authInfo['name']}님은 아직 사용자 연결이 이루어지지 않았습니다. ");
}
return $user_entity;
} catch (\Google_Service_Exception $e) {
log_message('error', '구글 서비스 예외: ' . $e->getMessage());
throw new PageNotFoundException("구글 로그인 중 오류가 발생했습니다. 다시 시도해 주세요.");
} catch (\Exception $e) {
log_message('error', $e->getMessage());
throw new PageNotFoundException("관리자에게 문의하시기 바랍니다.<BR>{$e->getMessage()}");

View File

@ -10,17 +10,23 @@ use Google\Service\Oauth2;
class GoogleSocket extends Client
{
private $session;
private string $token_code;
public function __construct(string $token_code)
private string $_access_token = "";
private string $_token_name = "access_token";
public function __construct()
{
parent::__construct();
$this->setAuthConfig(env('socket.google.api.config_file'));
$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();
$this->token_code = $token_code;
}
public function setToken(string $access_code): void
@ -30,15 +36,53 @@ class GoogleSocket extends Client
if (isset($tokenInfo['error'])) {
throw new ConfigException($tokenInfo['error']);
}
$token = $tokenInfo[$this->token_code];
// dd($tokenInfo);
$this->_access_token = $tokenInfo[$this->_token_name];
// Google Service에 접근하기 위해 Access Token 설정
$this->setAccessToken($token);
$this->setAccessToken([
'access_token' => $this->_access_token,
'expires_in' => 3600,
'created' => time(),
]);
// 세션에 Token 값 설정
$this->session->set($this->token_code, $token);
$this->session->set($this->_token_name, $this->_access_token);
}
public function getToken(): ?string
public function getToken(): string
{
return $this->session->get($this->token_code);
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

@ -2,18 +2,18 @@
namespace App\Models;
use App\Entities\SNSUSerEntity;
use App\Entities\UserSNSEntity;
use App\Models\CommonModel;
class SNSUserModel extends CommonModel
class UserSNSModel extends CommonModel
{
const TABLE = "sns_users";
const TABLE = "user_sns";
const PK = "uid";
const TITLE = "name";
const SITE = "site";
protected $table = self::TABLE;
protected $primaryKey = self::PK;
protected $returnType = SNSUSerEntity::class;
protected $returnType = UserSNSEntity::class;
protected $allowedFields = [
"site",
"id",
@ -43,7 +43,10 @@ class SNSUserModel extends CommonModel
$rule = "required|trim|string";
break;
case "email":
$rule = "if_exist|trim|valid_email";
$rule = "required|trim|valid_email";
break;
case "detail":
$rule = "required|trim|string";
break;
default:
$rule = parent::getFieldRule($action, $field);
@ -51,25 +54,37 @@ class SNSUserModel extends CommonModel
}
return $rule;
}
public function getEntityByPK(string $uid): null|SNSUSerEntity
protected function convertEntityData(string $field, array $formDatas): mixed
{
switch ($field) {
case "detail": //content등 textarea를 사용한 Field
$value = htmlentities($formDatas[$field], ENT_QUOTES);
break;
default:
$value = parent::convertEntityData($field, $formDatas);
break;
}
return $value;
}
public function getEntityByPK(string $uid): null|UserSNSEntity
{
$this->where($this->getPKField(), intval($uid));
return $this->getEntity();
}
public function getEntityByID(string $id): null|SNSUSerEntity
public function getEntityByID(string $id): null|UserSNSEntity
{
$this->where('id', $id);
return $this->getEntity();
}
//create용
public function create(array $formDatas = []): SNSUSerEntity
public function create(array $formDatas = []): UserSNSEntity
{
return $this->create_process(new SNSUSerEntity(), $formDatas);
return $this->create_process(new UserSNSEntity(), $formDatas);
}
//modify용
public function modify(SNSUSerEntity $entity, array $formDatas): SNSUSerEntity
public function modify(UserSNSEntity $entity, array $formDatas): UserSNSEntity
{
return $this->modify_process($entity, $formDatas);
}