프로그래밍/java, spring

spring 세션에서 email정보, 권한정보 꺼내기

김선국 강사 2023. 1. 21. 15:59
728x90

spring security를 이용하여 회원가입, 로그인을 구성했을때, 어떻게 로그인에 성공한 USER의 email, 권한정보(admin/일반user등)을 세션을 통해 담고, 꺼낼 수 있는지 살펴보자.

 

spring에서 로그인처리는 일반적으로 아래의 코드와 같이 UserDetailsService클래스의 loadByUserName이라는 메소드를 구현하게 된다. user정보가 있는 DB에서 가져온 emai, password정보가 사용자가 입력한 그것과 일치한다면 로그인에 성공하게 된다. 로그인 성공시에 UserDetails객체를 만들어 return하게 되는데, 여기에 email, password, 권한정보 등을 담아서 return을 하게 된다.

@Service
@Transactional
public class AuthorService  implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        Author author = repository.findByEmail(email)
                .orElseThrow(() -> new IllegalArgumentException("가입되지 않은 Email 입니다."));
        return new User(author.getEmail(), author.getPassword(), Arrays.asList(new SimpleGrantedAuthority(author.getRole().toString())));
    }
}

 

이렇게 리턴된 User객체는 Authentication객체에 저장되어, 필요하면 언제든 꺼낼 수 있게 된다. 다만 Authentication객체는 AuthenticationSuccessHandler를 상속받아 구현해야 사용이 가능한데, 매번 상속받을 수 없으므로, 아래코드와 같이 로그인에 성공했을때 1번만 LoginSuccessHandler에서 필요한 값들을 꺼내어 session에 담아 두면 될것이다.

(LoginSuccessHandler관련 내용은 마지막 줄 참고)

public class LoginSuccessHandler implements AuthenticationSuccessHandler {
//    Authentication 객체 안에 로그인 후 인증객체가 담겨 있음
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        HttpSession session = request.getSession();
//         Princilpal을 UserDetails로 변환하여 사용
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        session.setAttribute("email", userDetails.getUsername());
        session.setAttribute("auth", userDetails.getAuthorities());
//        또는 아래와 같이 email정보만 필요하다면, authentication객체에서 바로 name을 꺼내면된다.
//        session.setAttribute("email", authentication.getName());
//        인사말이 필요한 곳에서 아래와 같이 greeting 변수에 담아 사용도 가능하다
        session.setAttribute("greeting", authentication.getName()+"님 반갑습니다.");
        response.sendRedirect("/");
    }
}

 

LoginSuccessHandler가 어떻게 작동하는지 모르는 분은 아래 코드를 참고하면 된다. Bean객체로 만든 SecurityConfig에서 로그인 성공시 LoginSuccessHandler를 호출하도록 만들어둔 코드이다.

 

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return  http
                .csrf().disable()
                .httpBasic().disable()
                .authorizeRequests()
                .antMatchers("/authors/login" ,"/", "/authors/new")
                .permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                    .loginPage("/authors/login")
                    .loginProcessingUrl("/doLogin")
                    .usernameParameter("email")
                    .passwordParameter("password")
                    .successHandler(new LoginSuccessHandler())
                .and()
                .logout()
                .logoutUrl("/doLogout")
                .and().build();
    }
}

 

728x90