기록을 합시다.
[Spring] 개인프로젝트-1- 자체 회원가입 구현하기 본문
설정
spring boot 버전 : 3.0.6
dependency 설정
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
annotationProcessor 'org.projectlombok:lombok'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
//spring security
implementation 'org.springframework.boot:spring-boot-starter-security'
//jwt
implementation 'io.jsonwebtoken:jjwt-api:0.11.2'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.2'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.2'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
application.properties 설정
# MariaDB
spring.datasource.url=jdbc:mariadb://localhost:3306/aparttalk
spring.datasource.username=데이터베이스 유저 이름
spring.datasource.password=데이터베이스 유저의 비밀번호
# Hibernate
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDB103Dialect
# Spring dev-tools
livereload.enabled=true
freemarker.cache=false
#thymeleaf
spring.thymeleaf.enabled=true
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
User.java
package com.example.aparttalk.user.model;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Table(name = "user")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String userId;
@Column(nullable = false)
private String email;
@Column(nullable=false)
private String userName;
@Column(nullable=false)
private String password;
@Column
private Long apartId;
@Column(nullable=false)
private Boolean isVerified;
@Column
private String file;
@Column
private String Role;
public Long getId(){
return id;
}
}
컬럼으로는 id, userid, email, username, password, apartId, isVerified, file, Role이 있다.
- id : 유저의 고유 아이디
- userid : 유저가 로그인 할 때 사용할 아이디
- username : 유저가 커뮤니티에서 사용할 닉네임
- email : 유저가 비밀번호 같은 것을 잃어버렸을 때 유용하게 사용할 이메일
- password : 유저가 로그인 할 때 사용할 비밀번호
- apartId : 유저가 소속되어있는 아파트
- isVerified : 유저가 아파트에 소속 되어있는지 아닌지
- file : 유저가 올릴 아파트 고지서(아파트 입주민 인증용)
- Role : 단순히 사용자인지, 아니면 관리자인지
UserRepository.java
package com.example.aparttalk.user.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.aparttalk.user.model.User;
public interface UserRepository extends JpaRepository<User, Long> {}
UserRepositor를 만들어서 JpaRepository를 상속 받도록 했다. 상속받음으로써 User 인스턴스를 DB에 저장하고 등등 하는 CRUD 기능을 이용할 수 있다.
UserService.java
package com.example.aparttalk.user.service;
import com.example.aparttalk.user.dto.UserDTO;
import com.example.aparttalk.user.model.User;
import com.example.aparttalk.user.repository.UserRepository;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private BCryptPasswordEncoder passwordEncoder;
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public UserDTO createUser(UserDTO userDTO){
// 유저 생성 => userId, email, userName,
// password를 받고, isVerified는 False로, apart_id도 아직 할당 못 받음
//password 암호화
String password = userDTO.getPassword();
String encodedPassword = passwordEncoder.encode(password);
//apart_id => 없음, isVerified => False(아직 인증 못 받아서)
userDTO.setPassword(encodedPassword);
userDTO.setIsVerified(Boolean.FALSE);
userDTO.setRole("ROLE_USER");
User user = User.builder()
.userId(userDTO.getUserId())
.email(userDTO.getEmail())
.password(userDTO.getPassword())
.userName(userDTO.getUserName())
.apartId(userDTO.getApartId())
.isVerified(userDTO.getIsVerified())
.Role(userDTO.getRole())
.build();
user = userRepository.save(user);
return UserDTO.builder()
.userId(user.getUserId())
.email(user.getEmail())
.userName(user.getUserName())
.isVerified(user.getIsVerified())
.Role(user.getRole())
.build();
}
public Boolean checkUser(UserDTO userDTO){
User user = userRepository.findByEmail(userDTO.getEmail());
if(user == null){
return Boolean.TRUE;
}else{
return Boolean.FALSE;
}
}
}
UserService라는 클래스를 만들어서 사용자 관련 로직을 처리하도록 했다.
- createUser: UserDTO 객체를 받아와서 새로운 사용자를 생성하도록 했다. 먼저 입력받은 비밀번호를 암호화한 후, User객체를 생성해서 UserRepository를 통해 저장했다. 저장된 사용자 정보를 다시 UserDTO로 변환하여 반환했다.(근데 굳이 반환 안 해도 될 듯..)
UserController.java
package com.example.aparttalk.user.controller;
import com.example.aparttalk.user.dto.UserDTO;
import com.example.aparttalk.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Controller
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/signup")
public void getSignUp(){
}
@PostMapping("/signup")
public void postSignUp(UserDTO userDTO, Model model) {
try{
System.out.println("UserService"+userDTO.getUserName()+userDTO.getUserId()+userDTO.getEmail());
userService.createUser(userDTO);
} catch(Exception e){
System.out.println(e);
}
}
@GetMapping("/id-check")
public void idCheck(@RequestParam UserDTO userDTO, Model model){
if (userService.checkUser(userDTO)){
model.addAttribute("message", "Y");
}else{
model.addAttribute("message", "N");
}
}
}
컨트롤러에서는 회원가입, id-check를 해준다.
- public void getSignUp() : "/signup" URL에 대한 GET 요청이 들어오면 뷰(View)를 반환한다.
- public void postSignUp(UserDTO userDTO, Model model) : "/signup" URL에 대한 POST 요청이 들어오면, UserDTO를 생성하여 `UserService`의 `createUser` 메소드를 호출한다.
- public void idCheck(@RequestParam UserDTO userDTO, Model model) : "/id-check" URL에 대한 GET 요청이 들어오면, UserDTO를 생성하여 `UserService`의 `checkUser` 메소드를 호출한다. 이 때 @RequestParam`어노테이션은 HTTP 요청 파라미터로부터 값을 받아온다.
WebSecurityConfig.java
package com.example.aparttalk.user.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http.csrf().disable()
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/user/**").hasRole("USER")
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/signup").permitAll()
.requestMatchers("/signin").permitAll()
.requestMatchers("/css/**").permitAll()
.anyRequest().authenticated()
);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
참고로, 최근에는 antMatchers가 사라지고, 그 대신에 requestMathcers를 사용한다고 한다.
아마 조금 옛날 포스트들에는 다 antMatchers를 사용하고 있어서 따라 치다가 오류가 나서 뭔가 이상하다고 생각되어 그냥 홈페이지 들어가서 찾아봤다...
결과
잘 된다!!
이제 자바스크립트 상으로 fetch해서 아이디 체크, 이메일 체크 및 input 값들 검증만 해주면 된다. ㅜㅜ
'공부 > Java' 카테고리의 다른 글
[docker] Apache+Spring Boot(jar)+Oracle docker-compose로 띄우기 (0) | 2023.06.21 |
---|---|
[Spring] Hibernate를 사용하여 사용자 모델 및 레포지토리 만들기 (0) | 2023.05.16 |
[Spring] Spring security로 비밀번호 암호화 (0) | 2023.05.15 |
[Spring] Foreign Key 오류 (0) | 2023.05.15 |
[Spring] IntelliJ에서 Auto-Reloading 하기 (0) | 2023.05.13 |
Comments