
PHP 프레임워크 – Symfony – 6 – 보안
안녕하세요, 열정 넘치는 개발자 여러분 😊
오늘은 Symfony 프레임워크의 보안(Security) 기능에 대해 낱낱이 파헤쳐보는 시간을 가져볼게요!
웹 애플리케이션을 만든다는 건 마치 성을 짓는 것과 같죠.
아무리 멋진 성을 지었다 해도, 문이 열려 있으면 도둑이 들 수도 있어요!
그래서! Symfony는 강력한 보안 기능들을 제공하고 있답니다.
Symfony의 보안 기능 개요
Symfony는 **보안(Security)**을 프레임워크의 핵심 요소로 삼고 있어요.
아래와 같은 다양한 보안 도구들을 제공하죠:
- 인증(Authentication)
- 인가(Authorization)
- 사용자 역할(Role)
- 암호화(Password Encoding)
- CSRF 보호
- HTTPS 강제
- 접근 제어(Expression & Voter)
- 사용자 세션 관리
이 기능들을 조화롭게 사용하면 철통같은 보안 성을 완성할 수 있어요 🔐
1. 사용자 인증(Authentication)
사용자 로그인 흐름
Symfony는 보안을 위해 security.yaml
설정 파일을 사용해요.
간단한 폼 로그인 방식은 아래처럼 설정할 수 있어요:
# config/packages/security.yaml
security:
firewalls:
main:
form_login:
login_path: login
check_path: login
logout:
path: logout
target: /
🧾 form_login
은 사용자의 아이디와 비밀번호를 받아 인증하고,
logout
은 사용자가 로그아웃할 수 있도록 도와줍니다.
2. 사용자 인가(Authorization)
인증이 **”누구세요?”**라면, 인가는 “당신이 이걸 할 자격이 있나요?” 라는 질문이에요.
Role 기반 인가
if ($this->isGranted('ROLE_ADMIN')) {
// 관리자만 접근 가능한 기능
}
Symfony는 사용자의 역할(Role)을 확인해서 접근 권한을 분기할 수 있어요.
👮 마치 회사 출입증처럼, “관리자만 들어갈 수 있는 방” 같은 기능을 만들어주는 거죠!
3. 사용자 역할 관리
Symfony의 역할은 다음과 같이 정의할 수 있어요:
역할 | 설명 |
---|---|
ROLE_USER |
일반 사용자 |
ROLE_ADMIN |
관리자 권한 |
ROLE_SUPER_ADMIN |
최상위 권한 |
사용자 클래스(User
엔티티)에 getRoles()
메서드를 구현하면, 권한을 직접 설정할 수 있어요.
public function getRoles(): array
{
return ['ROLE_USER'];
}
4. 비밀번호 암호화 (Password Hashing)
Symfony는 비밀번호를 평문으로 저장하지 않도록 강제하고 있어요.
사용자 비밀번호는 반드시 해시화해야 합니다!
$password = $passwordHasher->hashPassword($user, $plaintextPassword);
🚨 절대 금지!
$user->setPassword($_POST['password']); // ❌ 이런 방식은 위험해요!
💡 Symfony 5.3 이상부터는 password_hasher
서비스를 활용하는 방식으로 구성합니다.
5. CSRF 보호
**CSRF (Cross-Site Request Forgery)**는 사용자의 요청을 위조하는 해커의 대표적인 수법이에요.
Symfony는 csrf_token
을 통해 이를 방지합니다.
폼에 CSRF 토큰 포함하기
$builder
->add('submit', SubmitType::class)
->getForm();
자동으로 CSRF 토큰이 포함되며,
유효하지 않으면 요청 자체가 거절돼요!
⚠️ “진짜 당신이 요청한 게 맞아요?” 를 확인하는 도장 찍기 시스템이죠!
6. HTTPS 강제
보안의 기본은 통신 자체를 암호화하는 거예요.
Symfony는 .htaccess
나 Nginx 설정 또는 security.yaml
을 통해 HTTPS를 강제할 수 있어요.
access_control:
- { path: ^/admin, roles: ROLE_ADMIN, requires_channel: https }
🚨 민감한 데이터가 오가는 경로는 반드시 HTTPS를 사용하세요!
7. 접근 제어 (Access Control)
Symfony는 경로마다 다른 접근 권한을 부여할 수 있어요.
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/profile, roles: ROLE_USER }
🔐 로그인하지 않은 사용자가 /admin
을 열려고 하면? 자동으로 로그인 페이지로 리다이렉트!
또는 컨트롤러 메서드에서도 직접 제어 가능해요:
$this->denyAccessUnlessGranted('ROLE_USER');
8. Voter 사용
복잡한 권한 로직이 필요한 경우, Voter 클래스를 만들어 세부 인가 로직을 구현할 수 있어요.
// src/Security/PostVoter.php
class PostVoter extends Voter
{
protected function supports(string $attribute, $subject)
{
return in_array($attribute, ['EDIT', 'DELETE']) && $subject instanceof Post;
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token)
{
$user = $token->getUser();
if (!$user instanceof User) {
return false;
}
return $subject->getAuthor() === $user;
}
}
이제 isGranted('EDIT', $post)
식으로 사용할 수 있어요!
📦 비유하자면, Voter는 경비원이 출입증을 확인하고 출입 허가 여부를 판단하는 역할이에요.
9. 세션과 Remember Me
로그인 상태 유지를 위한 세션(Session) 기능도 기본 제공되며,
remember_me
설정을 통해 브라우저를 꺼도 로그인 유지가 가능해요.
firewalls:
main:
remember_me:
secret: '%kernel.secret%'
lifetime: 604800 # 일주일
주의해야 할 보안 체크리스트 ✅
항목 | 설명 |
---|---|
평문 비밀번호 금지 | 반드시 passwordHasher 로 해시 저장 |
CSRF 토큰 필수 | 모든 폼 요청엔 CSRF 보호 적용 |
경로 권한 명시 | 모든 URL은 access_control에서 명확히 제한 |
관리자만 가능한 로직 분리 | ROLE_ADMIN 조건문을 걸어두세요 |
HTTPS 필수 | 인증/결제 페이지는 HTTPS 강제 적용 |
오류 메시지 노출 주의 | 로그인 실패 등 상세 메시지 제한 필요 |
마무리하며 😊
Symfony의 보안 기능은 단순히 로그인/로그아웃 기능만 있는 것이 아니라,
웹 애플리케이션 전반의 안전성을 보장하는 방패 같은 존재랍니다.
- 사용자 인증 → “누구세요?”
- 사용자 인가 → “그걸 해도 되세요?”
- CSRF/암호화/세션 → “정보를 안전하게 다루고 있나요?”
이 세 가지 질문에 **“YES!”**라고 자신 있게 대답할 수 있도록,
Symfony 보안 기능을 꼼꼼하게 설계하고 설정하는 습관을 들이세요!
그럼 다음 시간에는 실전 프로젝트에서 이 보안 기능들을 어떻게 적용하는지,
실제 코드 예제와 함께 안내해드릴게요!
오늘도 안전하고 멋진 코딩 되세요 🔐💻