로그인폼과 회원가입폼 HTML
더보기
로그인폼과 회원가입폼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>로그인 페이지</title> </head> <body> <h1>로그인 페이지</h1> <hr> <form action="/login" method="POST"> <input type="text" name="username" placeholder="UserName"/><br/> <input type="password" name="password" placeholder="Password"/><br/> <button>로그인</button> </form> <a href = "/joinForm">회원가입을 아직 않으셨나요?</a> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>회원가입 페이지</title> </head> <body> <h1>회원가입 페이지</h1> <form action="/join" method="POST"> <input type="text" name="username" placeholder="UserName"/><br/> <input type="password" name="password" placeholder="Password"/><br/> <input type="email" name="email" placeholder="Email"/><br/> <button>회원가입</button> </form> </body> </html>
[ 회원가입 Contoller ]
@PostMapping("/join") public String join(User user){ System.out.println(user); // 2. 패스워드 암호화를 추가해줌 securityConfig에도 BcryptpasswordEncoder를 @Bean으로 등록 String rawPassword = user.getPassword(); String encPassword = bCryptPasswordEncoder.encode(rawPassword); user.setPassword(encPassword); // 1. userRepository.save(user); // 회원가입 잘됨. 비밀번호 : 1234 => 시큐리티로 로그인을 할수 없음, // :: 패스워드가 암호화가 안되었기 때문 user.setRole("ROLE_USER"); userRepository.save(user); return "redirect:/loginForm"; }
[ USER MODEL ]
package com.cos.security1.model; import lombok.Data; import org.hibernate.annotations.CreationTimestamp; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import java.sql.Timestamp; @Entity @Data public class User { @Id // primary Key @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String username; private String password; private String email; private String role; // ROLE_USEr, ROLE_ADMIN @CreationTimestamp private Timestamp createdate; }
[ USER REPORSITORY - JPA ]
package com.cos.security1.repository; import com.cos.security1.model.User; import org.springframework.data.jpa.repository.JpaRepository; // CRUD 함수를 JPArepository가 들고 있음 // @Repository라는 어노테이션이 없어도 Ioc가 됨 (자동 빈등록) // -> JpaRepository를 상속했기 때문 public interface UserRepository extends JpaRepository<User, Integer> { // findBy규칙 -> username 문법 // seelct * from user where username = #{username} public User findByUsername(String username); }
[ config 수정 ]
밑 두줄 추가.
public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); // /login으로 갈때 스프링 시큐리티가 낚아채지 않도록 http.authorizeRequests() .antMatchers("/user/**").authenticated() .antMatchers("/manager/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_MANAGER')") .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')") .anyRequest().permitAll()// 다른주소는 OK .and() .formLogin() .loginPage("/loginForm") // 로그인안햇을때 403페이지가 뜨는게 아니라 login페이지를 뜨게만들어줌 .loginProcessingUrl("/login") //login 주소가 호출이 되면 시큐리티가 낚아채서 대신 로그인을 진행 .defaultSuccessUrl("/"); // 로그인이 완료되면 이동할 주소 }
[ userDetails를 상속하는 클래스 생성 ]
유저정보를 저장.
package com.cos.security1.config.auth; // 시큐리티가 /login 주소 요청이 오면 낚아채서 로그인을 진행시킴 // 로그인 진행이 완료되면 seisson을 만들어줌 (Security ContextHolder) // 세션에 들어갈 수 있는 정보(오브젝트) > authentication 타입의 객체 // authentication 안에 User정보가 있어야 함. // user 오브젝트 타입 > UserDetails 타입 객체 // Security Session => Authentication => UserDetails(PrincipalDetails) import com.cos.security1.model.User; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import java.util.ArrayList; import java.util.Collection; public class PrincipalDetails implements UserDetails { private User user; // 콤포지션 public PrincipalDetails(User user){ this.user = user; } // 해당 user의 권한을 리턴하는 곳 @Override public Collection<? extends GrantedAuthority> getAuthorities() { Collection<GrantedAuthority> collect = new ArrayList<>(); collect.add(new GrantedAuthority() { @Override public String getAuthority() { return user.getRole(); } }); return collect; } @Override public String getPassword() { return user.getPassword(); } @Override public String getUsername() { return user.getUsername(); } // 계정 만료 @Override public boolean isAccountNonExpired() { return true; } // 계정 잠김 @Override public boolean isAccountNonLocked() { return true; } // 계정 유효기간 @Override public boolean isCredentialsNonExpired() { return true; } // 계정 정지 @Override public boolean isEnabled() { // ex) 휴면계정 // 현재시간 - 로그인시간 => 1년초과하면 return false return true; } }
[ userDetailsService를 상속한 클래스 만들기 ]
이름 그대로 유저의 정보를 저장해주는 서비스
// 시큐리티 설정에서 loginProcessingUrl("/login") // /login 요청이 오면 자동으로 UserDetailsService 타입으로 ioc되어있는 loadUserByUsername가 함수 실행
package com.cos.security1.config.auth; import com.cos.security1.model.User; import com.cos.security1.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; // 시큐리티 설정에서 loginProcessingUrl("/login") // /login 요청이 오면 자동으로 UserDetailsService 타입으로 ioc되어있는 loadUserByUsername가 함수 실행 @Service public class PrincaipalDetailsService implements UserDetailsService{ @Autowired private UserRepository userRepository; // 시큐리티 session > authentication > userDetails(principalDetails) @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // html에 꼭 "username"으로 해야함 (String username)과 매칭이 안됨 // 바꾸고 싶다면 security config에 .usernameParameter("username2") // 그냥 username을 쓰자 ^^ User userEntity = userRepository.findByUsername(username); if(userEntity != null){ return new PrincipalDetails(userEntity); } return null; } }
[ userRepository 에는 유저의 정보를 조회하는 부분 추가 ]
// findBy규칙 -> username 문법 // seelct * from user where username = #{username} public User findByUsername(String username);
'spring' 카테고리의 다른 글
[spring security] OAuth2.0 기본 - 구글 로그인 준비 (0) | 2022.01.17 |
---|---|
[Spring Security] 스프링 시큐리티 3. 권한부여 (0) | 2022.01.16 |
[Spring Security] 스프링 시큐리티 1. 기본설정 (0) | 2022.01.16 |
[스프링부트] vs code 사용하기 메모 (0) | 2021.03.08 |
[스프링] 웹소켓 : 채팅 (0) | 2021.01.29 |
[스프링] 메일발송하기 (0) | 2021.01.25 |
[스프링] REST API / @RequestBody @ResponseBody , HttpMessageConverter (0) | 2021.01.20 |