feat: update auth and security flow

This commit is contained in:
taekyoungc
2026-04-08 00:23:21 +09:00
parent b5eed31b94
commit 06fedc866a
7 changed files with 75 additions and 35 deletions

View File

@@ -7,17 +7,19 @@ use CodeIgniter\Config\BaseConfig;
/**
* 로그인·2차 인증(TOTP) 관련 설정
*
* .env 예:
* auth.requireTotp = true
* auth.totpIssuer = "쓰레기봉투 물류시스템"
* .env 의 auth.requireTotp 가 Config 기본값보다 우선합니다. 끄려면 반드시 false 로 두세요.
* 예:
* auth.requireTotp = false
* auth.requireTotp = true # 운영에서 2FA 켤 때
* auth.totpIssuer = "종량제 시스템"
*/
class Auth extends BaseConfig
{
/** 운영·스테이징 true 권장. 로컬 개발 시 false 로 1단계만 로그인 가능 */
public bool $requireTotp = true;
/** false 이면 로그인 시 TOTP·등록 유도 없음. 운영에서 켤 때 .env 에 auth.requireTotp = true */
public bool $requireTotp = false;
/** 인증 앱에 표시되는 발급자(issuer) */
public string $totpIssuer = '쓰레기봉투 물류시스템';
public string $totpIssuer = '종량제 시스템';
/** TOTP 연속 실패 시 세션 종료 전 허용 횟수 */
public int $totpMaxAttempts = 5;

View File

@@ -27,8 +27,40 @@ class Encryption extends BaseConfig
public function __construct()
{
parent::__construct();
$hex = (string) env('encryption.key', '');
$hex = trim((string) env('encryption.key', ''));
if (
(str_starts_with($hex, "'") && str_ends_with($hex, "'"))
|| (str_starts_with($hex, '"') && str_ends_with($hex, '"'))
) {
$hex = substr($hex, 1, -1);
}
$this->key = (strlen($hex) === 64 && ctype_xdigit($hex)) ? hex2bin($hex) : '';
$prev = trim((string) env('encryption.previousKeys', ''));
if ($prev !== '') {
$parsed = [];
$parts = array_map('trim', explode(',', $prev));
foreach ($parts as $part) {
if ($part === '') {
continue;
}
if (str_starts_with($part, 'hex2bin:')) {
$part = substr($part, 8);
}
if (
(str_starts_with($part, "'") && str_ends_with($part, "'"))
|| (str_starts_with($part, '"') && str_ends_with($part, '"'))
) {
$part = substr($part, 1, -1);
}
if (strlen($part) === 64 && ctype_xdigit($part)) {
$parsed[] = 'hex2bin:' . $part;
}
}
if (! empty($parsed)) {
$this->previousKeys = $parsed;
}
}
}
/**