스프링 부트 백엔드 개발 강좌, 스프링 시큐리티로 로그인 로그아웃, 회원 가입 구현, 로그아웃 메서드 추가하기

이번 강좌에서는 현대 웹 애플리케이션에서 사용자가 애플리케이션에 접근할 수 있도록 하기 위한 인증(Authentication) 및 인가(Authorization) 기능을 다룰 것입니다. 특히 스프링 부트스프링 시큐리티를 활용하여 사용자 로그인, 로그아웃, 회원 가입 기능을 구현합니다. 이 과정은 실제 웹 서비스에서 자주 사용되는 기본적인 기능들을 포함하여, 보안이 얼마나 중요한지를 이해하는 데에도 큰 도움이 될 것입니다.

목차

  1. 스프링 부트 개요
  2. 스프링 시큐리티 소개
  3. 프로젝트 설정
  4. 회원 가입 구현
  5. 로그인 및 로그아웃 구현
  6. 로그아웃 메서드 추가하기
  7. 강좌 요약

1. 스프링 부트 개요

스프링 부트는 스프링 프레임워크의 확장으로써, 신속한 개발을 가능하게 하기 위해 설계되었습니다. 복잡한 설정 없이 애플리케이션을 손쉽게 시작할 수 있도록 도와주며, 스프링 부트 공식 사이트에서 제공하는 스타터 패키지를 통해 필요한 라이브러리를 간편하게 추가할 수 있습니다.

왜 스프링 부트를 사용할까요? 스프링 부트의 가장 큰 장점 중 하나는 의존성 관리입니다. 다양한 라이브러리를 포함하고 있는 pom.xml 파일을 구성하기만 하면 필요에 따라 필요한 의존성을 자동으로 다운로드 받을 수 있습니다. 간단하게 설정하고 여러분의 아이디어를 구현하는 데 집중하세요.

2. 스프링 시큐리티 소개

스프링 시큐리티는 애플리케이션의 인증 및 인가를 담당하는 강력한 프레임워크입니다. 스프링 시큐리티를 사용하면 다음과 같은 기능들을 손쉽게 구현할 수 있습니다:

  • 사용자 인증: 아이디와 비밀번호를 통한 로그인 기능
  • 인증된 사용자에 대한 권한 부여
  • CSRF 방지
  • 세션 관리

스프링 시큐리티는 그 자체로도 매우 강력하지만, 스프링 부트와 통합하여 더 많은 장점을 누릴 수 있습니다. 빠르고 간편하게 설정할 수 있으며, 보안 문제를 더 쉽게 관리할 수 있습니다.

3. 프로젝트 설정

스프링 부트를 사용하여 새로운 웹 애플리케이션을 생성합니다. 아래 단계에 따라 프로젝트를 설정하세요.

3.1. 스프링 이니셜라이저 이용하기

스프링 이니셜라이저(start.spring.io)를 사용하여 새로운 스프링 부트 프로젝트를 생성할 수 있습니다. 다음 의존성을 선택하세요:

  • Spring Web
  • Spring Security
  • Spring Data JPA
  • H2 Database

3.2. 프로젝트 코드 구조

프로젝트를 생성한 후, 다음과 같은 기본 코드 구조를 유지합니다:

src
├── main
│   ├── java
│   │   └── com
│   │       └── example
│   │           └── demo
│   │               ├── DemoApplication.java
│   │               ├── config
│   │               │   └── SecurityConfig.java
│   │               ├── controller
│   │               │   └── UserController.java
│   │               ├── model
│   │               │   └── User.java
│   │               └── repository
│   │                   └── UserRepository.java
│   └── resources
│       ├── application.properties
│       └── templates
└── test

4. 회원 가입 구현

회원 가입 기능을 구현하기 위해 User 모델과 UserRepository를 정의한 후, 회원 가입을 처리할 UserController를 만들어보겠습니다.

4.1. User 모델 정의


package com.example.demo.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String username;
    private String password;

    // Getter와 Setter 생략
}

4.2. UserRepository 인터페이스 구현


package com.example.demo.repository;

import com.example.demo.model.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository {
    User findByUsername(String username);
}

4.3. UserController 구현


package com.example.demo.controller;

import com.example.demo.model.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.validation.Valid;

@Controller
@RequestMapping("/signup")
public class UserController {
    @Autowired
    private UserRepository userRepository;

    @GetMapping
    public String showSignupForm() {
        return "signup"; // signup.html
    }

    @PostMapping
    public String registerUser(@Valid User user) {
        userRepository.save(user);
        return "redirect:/login"; // 가입 후 로그인 페이지로 리다이렉트
    }
}

4.4. 회원 가입 HTML 폼 생성

resources/templates/signup.html 파일을 생성하고 다음과 같이 작성합니다.






    
    회원 가입


    

회원 가입



5. 로그인 및 로그아웃 구현

이제 사용자가 로그인할 수 있도록 스프링 시큐리티를 설정합니다. 인증 로직을 처리하고, 로그인 후 리다이렉션할 대상을 설정합니다.

5.1. SecurityConfig 클래스 설정


package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/signup").permitAll() // 회원 가입 페이지는 모두 접근 가능
                .anyRequest().authenticated() // 그 외 요청은 인증 필요
            .and()
                .formLogin()
                .loginPage("/login") // 사용자 정의 로그인 페이지
                .permitAll()
            .and()
                .logout()
                .permitAll();
    }

    @Autowired
    protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

5.2. 로그인 페이지 생성

resources/templates/login.html 파일을 생성하여 사용자 정의 로그인 페이지를 추가합니다.






    
    로그인


    

로그인



6. 로그아웃 메서드 추가하기

로그아웃 기능은 스프링 시큐리티에서 기본적으로 제공되지만, 추가적인 커스터마이징이 필요할 수 있습니다. 로그아웃 시킬 URL과 로그아웃 후 리다이렉션할 URL을 설정합니다.

6.1. 로그아웃 URL 설정


@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .logout()
                .logoutUrl("/logout") // 로그아웃 URL
                .logoutSuccessUrl("/login?logout") // 로그아웃 성공 시 리다이렉트할 URL
                .invalidateHttpSession(true) // 세션 무효화
                .clearAuthentication(true); // 인증 정보 지우기
    }
}

6.2. 로그아웃 버튼 추가

로그인을 한 후에는 로그아웃 버튼을 추가하여 쉽게 로그아웃할 수 있도록 합시다. resources/templates/index.html에서 다음과 같이 추가합니다.



    

환영합니다!