PHP 프레임워크 – Symfony – 6 – 보안

PHP 프레임워크 - Symfony - 6 - 보안
PHP 프레임워크 – Symfony – 6 – 보안

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 보안 기능을 꼼꼼하게 설계하고 설정하는 습관을 들이세요!

그럼 다음 시간에는 실전 프로젝트에서 이 보안 기능들을 어떻게 적용하는지,
실제 코드 예제와 함께 안내해드릴게요!

오늘도 안전하고 멋진 코딩 되세요 🔐💻

답글 남기기