CodeIgniter 4로 블로그 만들기 #10 — Shield 인증 도입
지금까지 우리는 글을 읽는 화면만 만들었습니다. 목록과 상세까지 오면서, 누구나 볼 수 있는 공개 블로그의 골격은 갖춰졌습니다. 이제부터는 글을 쓰는 쪽으로 넘어가야 하는데, 그 전에 반드시 해결해야 할 문제가 하나 있습니다. "누가 쓰는가?" 입니다.
로그인·회원가입·비밀번호 해시·세션 관리 같은 인증(authentication)은 직접 만들면 실수하기 쉽고, 보안상 위험한 코드가 되기도 쉽습니다. 그래서 이번 회차에서는 CodeIgniter가 공식으로 제공하는 인증 라이브러리 Shield를 도입합니다.
이번 글의 목표는 딱 하나입니다. Shield를 설치하고, 인증 기반(설정 파일 + 테이블 + 라우트)을 까는 것까지입니다. 로그인 화면에 따라 네비게이션을 분기하는 건 다음 회차에서 합니다.
준비물 / 목표
- 지금까지 완성된 상태 (posts 마이그레이션·시더·모델·엔티티, 목록/상세 화면).
- 이번 회차에서 하는 일:
codeigniter4/shield의존성 추가php spark shield:setup으로 설정 파일 발행service('auth')->routes()로 login/register/logout 라우트 등록- 인증 테이블(users 등) 마이그레이션
1. Shield 설치
Shield는 Composer 패키지입니다. composer.json의 require에 한 줄을 더합니다.
"require": {
"php": "^8.2",
"codeigniter4/framework": "^4.7",
"codeigniter4/shield": "^1.3"
}
실제로는 명령 한 줄로 받습니다.
composer require codeigniter4/shield
이렇게 하면 composer.lock도 갱신되면서 Shield와 그 의존성(예: codeigniter4/settings)이 vendor/에 들어옵니다. 프레임워크와 마찬가지로 우리 app/ 코드와는 분리된 라이브러리라는 점만 기억하면 됩니다.
2. shield:setup으로 기반 깔기
Shield는 설치만으로는 동작하지 않습니다. 우리 앱의 app/Config/에 **설정 파일을 발행(publish)**하고, 라우트를 등록하는 초기화 단계가 필요합니다. 이걸 한 번에 해 주는 spark 명령이 있습니다.
php spark shield:setup
이 명령이 하는 일은 대략 이렇습니다.
app/Config/Auth.php,app/Config/AuthGroups.php,app/Config/AuthToken.php세 개의 설정 파일을 우리 프로젝트로 복사(발행)합니다.app/Config/Routes.php에 인증 라우트 등록 코드를 추가합니다.app/Config/Autoload.php의 헬퍼 목록에auth,setting을 추가합니다.
여기서 중요한 습관 하나. Shield가 발행한 파일들은 라이브러리가 자동으로 만들어 준 것이므로, 직접 처음부터 작성하지 않습니다. 커리큘럼에서 "발행 + 수정"으로 표현한 이유가 이것입니다. 우리는 발행된 파일을 손으로 새로 짜는 게 아니라, 명령이 만들어 준 뒤 필요한 부분만 조정합니다.
발행된 설정 파일들이 어떤 역할을 하는지 감만 잡고 갑시다.
Auth.php— 가장 핵심. 로그인 방식, 리다이렉트 경로, 세션 설정, 사용할 인증기(authenticators), 검증 규칙 등이 모두 여기 들어 있습니다. (약 500줄로 가장 큰 파일입니다.)AuthGroups.php— 그룹(예:admin,user)과 권한(permission) 정의. 나중에 "관리자만 삭제" 같은 권한 체크(ep15)에서 쓰입니다.AuthToken.php— API 토큰 인증 관련 설정. 이 강좌에서는 세션 인증을 주로 쓰므로 당장은 건드리지 않습니다.
3. 인증 라우트 등록
발행 이후 app/Config/Routes.php 맨 아래에는 다음 한 줄이 들어갑니다.
$routes->get('/', 'Home::index');
$routes->get('about', 'Pages::about');
$routes->get('posts', 'Posts::index');
$routes->get('posts/(:segment)', 'Posts::show/$1');
service('auth')->routes($routes);
service('auth')->routes($routes) 이 한 줄이, 우리가 직접 라우트를 하나하나 등록하지 않아도 login, register, logout, 비밀번호 재설정 등 인증에 필요한 라우트 전부를 한꺼번에 등록해 줍니다. 로그인/회원가입 화면과 컨트롤러도 Shield가 이미 갖고 있어서, 우리는 URL만 열어 주면 바로 동작합니다.
한 가지 배치에 유의할 점이 있습니다. posts/(:segment)는 "posts 뒤에 오는 아무 세그먼트"를 상세 페이지로 잡는 와일드카드 라우트입니다. 인증 라우트(login 등)는 이 패턴과 겹치지 않으므로 문제없지만, 라우트는 위에서부터 순서대로 매칭된다는 점은 앞으로도 계속 신경 써야 합니다.
4. CSRF를 세션 기반으로
발행 과정에서 app/Config/Security.php의 CSRF 보호 방식도 바뀝니다.
public string $csrfProtection = 'session';
기본값은 'cookie'인데 이걸 'session'으로 바꿉니다. 우리는 이미 세션 기반 로그인을 쓸 것이므로, CSRF 토큰도 세션에 두는 편이 자연스럽고 일관됩니다. CSRF 토큰은 다음 회차 이후 글 작성 폼(csrf_field())에서 실제로 쓰게 됩니다.
5. 헬퍼 자동 로드
app/Config/Autoload.php에서는 헬퍼 목록이 이렇게 바뀝니다.
public $helpers = ['auth', 'setting'];
이 덕분에 앞으로 뷰나 컨트롤러 어디서든 auth() 함수(현재 사용자·로그인 여부)와 setting() 함수를 별도 로드 없이 바로 쓸 수 있습니다. 다음 회차 헤더에서 auth()->loggedIn()을 바로 호출할 수 있는 것도 이 설정 덕분입니다.
참고 — 커리큘럼과의 차이. 커리큘럼에는
app/Config/Filters.php에 Shield 필터 별칭을 등록하고BaseController에helper('auth')를 넣는 단계가 적혀 있습니다. 하지만 Shield 1.3에서는 이 두 가지가 각각 Config 레지스트라(라이브러리가 자동으로 필터 별칭session·tokens등을 등록)와 Autoload 헬퍼로 자동 처리됩니다. 그래서 이 강좌에서는Filters.php와BaseController를 직접 손대지 않습니다. 라이브러리 버전에 따라 자동화되는 범위가 다르다는 것도 하나의 배움입니다.
6. 마이그레이션 — 인증 테이블 생성
설정만 발행됐을 뿐 아직 사용자 테이블은 없습니다. Shield는 자체 마이그레이션을 갖고 있으므로, 마이그레이션을 돌려서 테이블을 만들어 줍니다. 이때 App 네임스페이스뿐 아니라 Shield·Settings 네임스페이스의 마이그레이션까지 함께 적용해야 하므로 --all 옵션을 씁니다.
php spark migrate --all
이 명령으로 users, auth_identities, auth_logins, auth_remember_tokens, auth_groups_users, auth_permissions_users, auth_token_logins, 그리고 Settings 라이브러리의 settings 테이블까지 인증 관련 테이블 8종이 생성됩니다. 여기까지 오면 /register로 회원가입, /login으로 로그인이 실제로 동작합니다.
핵심 개념 — 왜 라이브러리를 쓰는가
인증은 "직접 짜면 배우는 게 많다"고 생각하기 쉬운 영역이지만, 실무에서는 정반대입니다. 비밀번호 해시 알고리즘, 세션 고정 공격 방어, 토큰 만료, 재설정 흐름 같은 것들은 틀리면 곧바로 보안 사고가 됩니다. 공식 라이브러리는 이런 검증된 구현을 제공하고, 우리는 설정과 화면 분기에 집중할 수 있습니다.
또 하나, Shield는 "발행형" 라이브러리라는 점이 중요합니다. 설정 파일을 우리 프로젝트로 복사해 주기 때문에, 라이브러리 안을 고치지 않고도 우리 프로젝트에 맞게 세부 설정을 조정할 수 있습니다. 우리 코드와 라이브러리 코드의 경계가 명확해지는 것이죠.
마무리 — 커밋과 태그
이번 회차에서 한 일:
codeigniter4/shield의존성 추가 (composer.json)php spark shield:setup으로Auth.php·AuthGroups.php·AuthToken.php발행Routes.php에service('auth')->routes()등록Autoload.php헬퍼에auth·setting추가,Security.phpCSRF를session으로php spark migrate --all로 인증 테이블 8종 생성
git add .
git commit -m "feat: Shield 인증 도입"
git tag ep10
다음 회차
다음 글에서는 이렇게 깔아 둔 인증 기반을 화면에 연결합니다. 공통 헤더에서 auth()->loggedIn()으로 로그인/비로그인 상태를 분기해 네비게이션을 바꾸고, 앞으로 글쓰기 같은 쓰기 라우트를 담을 session 필터 그룹의 골격을 만듭니다.
이번 회차 요약
- 다루는 파일:
composer.json(수정) /app/Config/Auth.php·AuthGroups.php·AuthToken.php(발행) /app/Config/Routes.php·Autoload.php·Security.php(수정)- 핵심: 인증은 공식 라이브러리 Shield로.
shield:setup이 설정을 발행하고,service('auth')->routes()가 인증 라우트를 등록하며,migrate --all이 users 등 테이블을 만든다. 발행된 파일은 직접 짜지 말고 발행 후 조정한다.
다음: 인증 필터와 현재 사용자 분기
댓글 0
아직 댓글이 없습니다.