해결된 질문
작성
·
266
0
안녕하세요! 로그인과 로그인 유지에 대해 질문이 있습니다!!
강의에서는 이메일과 닉네임으로 모두 로그인이 가능하게 되어있는데
로그인을 할 때 이메일로만 로그인이 가능하도록 하면서 로그인을 했을 때 타임리프에서 #authentication.name으로 닉네임을 가져올 수 있는 방법이 있을까요??
아래와 같이 UserAccount에서 username 자리에 account.getNickname()를 넣어주어야 #authentication.name 에 닉네임이 들어갈텐데..
@Getter
public class UserAccount extends User {
private Account account;
public UserAccount(Account account) {
super(account.getNickname(), account.getPassword(), List.of(new SimpleGrantedAuthority("ROLE_USER")));
this.account = account;
}
}
이메일로만 로그인이 가능하도록 하려면 loadUserByUsername 메서드에서 이메일로 찾지 못한 경우 닉네임으로 유저를 찾도록 하는 코드를 지워야 하고, 그렇게 되면 RememberMe 를 통한 로그인 유지에서 jsessionid를 지운 경우 Remember-me 쿠키에 담긴 username이 닉네임이므로 loadUserByUsername 메서드에서 account를 찾을 수 없게 됩니다.
@Transactional(readOnly = true)
@Override
public UserDetails loadUserByUsername(String emailOrNickname) throws UsernameNotFoundException {
Account account = accountRepository.findByEmail(emailOrNickname);
if(account == null){
account = accountRepository.findByNickname(emailOrNickname);
}
if(account == null){
throw new UsernameNotFoundException(emailOrNickname);
}
return new UserAccount(account);
}
이러한 경우 어떻게 해야 User클래스의 username에 닉네임을 넣었을 때, 이메일로만 로그인이 가능하도록 하면서 로그인 유지 기능을 정상적으로 동작시킬 수 있을지 궁금합니다..!!
답변 4
1
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService); // 이메일로 로그인하는 UserDetails 구현체
}
SecurityConfig에 이 설정을 추가해 보시겠어요? 스프링 시큐리티가 사용할 기본 AuthManager에 이메일로만 로그인하는 UserDetailsService를 설정하는 코드입니다.
1
로그인을 할 때 이메일로만 로그인이 가능하도록 하면서 로그인을 했을 때 타임리프에서 #authentication.name으로 닉네임을 가져올 수 있는 방법이 있을까요??
> 네 그건 말씀하신대로 이메일로 Account 조회해서 User의 username에 Account의 닉네임을 넣어주면 됩니다.
두번째 질문에 대한건, 그럼 RememberMe 필터가 사용할 UserDetailsService를 새로 하나 더 만들어서 필터에 설정해줘야겠네요. 그 UserDetailsService는 닉네임으로 유저를 조회하는 코드가 될겠네요.
http.rememberMe()
.userDetailsService(userDetailsService)
.tokenRepository(tokenRepository());
즉 여기서 참조할 userDetailsSerivce를 다른걸로 바꿔야죠. RememberMeUserDetailsService같은걸 만들어서요.
0
0
답변 감사합니다!!
말씀하신대로 구현을 해보니, 아이디와 이메일 모두 로그인이 안되는 현상이 발생했습니다.
사용자 정보를 찾아오지 못하는 것 같은데
UserDetailsService가 2개이기 때문에 다른 처리를 해줘야 하는건지 궁금합니다..!
- RememberMeUserDetailsService
@Service
@RequiredArgsConstructor
public class RememberMeUserDetailsService implements UserDetailsService {
private final AccountRepository accountRepository;
@Transactional(readOnly = true)
@Override
public UserDetails loadUserByUsername(String nickname) throws UsernameNotFoundException {
Account byNickname = accountRepository.findByNickname(nickname);
if (byNickname == null) {
throw new UsernameNotFoundException(nickname);
}
return new UserAccount(byNickname);
}
}
http.rememberMe()
.userDetailsService(rememberMeUserDetailsService)
.tokenRepository(tokenRepository());
- AccountService
@Transactional(readOnly = true)
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
Account account = accountRepository.findByEmail(email);
if(account == null){
throw new UsernameNotFoundException(email);
}
return new UserAccount(account); // User 를 확장한 UserAccount 클래스에 유저 정보와 권한을 삽입하여 반환
}