Back-End/React.js, 스프링 부트, AWS로 배우는 웹 개발 101

[React.js, 스프링 부트, AWS로 배우는 웹 개발 101][인증 백엔드 통합] - User Layer 구현

얄루몬 2022. 6. 22. 02:32

본 포스팅은 'React.js, 스프링 부트, AWS로 배우는 웹 개발 101 - 김다정'님의 책을 보고 작성되었습니다.


목차
1. UserEntity 구현
2. UserRepository 구현
3. UserService 구현
4. UserDTO
5. UserController 구현

스프링 시큐리티를 사용해서 인증과 인가를 구현하는 방법과 사용자 관리를 하는 방법을 실제 구현을 통해 알아보도록 하자.

1. UserEntity 구현

package com.example.demo.model;


import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;

@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = "email")})
public class UserEntity {

    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name="system-uuid", strategy = "uuid")
    private String id; //사용자들에게 고유하게 부여되는 id

    @Column(nullable = false)
    private String username;

    @Column(nullable = false)
    private String email;

    @Column(nullable = false)
    private String password;
}

사용자 엔티티를 생성

2. UserRepository 구현

package com.example.demo.persistence;


import com.example.demo.model.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<UserEntity, String> {
    UserEntity findByEmail(String email);
    Boolean existsByEmail(String email);
    UserEntity findByEmailAndPassword(String email, String password);

}

UserEntity 사용을 위한 UserRepository 작성

3. UserService 구현

package com.example.demo.service;

import com.example.demo.model.UserEntity;
import com.example.demo.persistence.UserRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class UserService {

    @Autowired
    private UserRepository userRepository;

    //UserRepository를 이용해 사용자 생성
    public UserEntity create(final UserEntity userEntity){
        if(userEntity == null || userEntity.getEmail() == null){
            throw new RuntimeException("Invalid arguments");
        }

        //만약 이메일이 있는 경우라면? RuntimeException을 던진다.
        final String email = userEntity.getEmail();
        if(userRepository.existsByEmail(email)){
            log.warn("Email already exist");
            throw new RuntimeException("Email already exist");
        }

        return userRepository.save(userEntity);

    }
    //로그인 시 인증에 사용할 메서드
    public UserEntity getByCredentials(final String email, final String password){
        return userRepository.findByEmailAndPassword(email, password);
    }
}
  • 데이터베이스에 저장된 사용자를 가져올 때 사용한다.
  • 작성한 UserRepository를 이용해서 사용자를 생성하고 로그인 시 인증에 사용할 메서드를 작성해준다.

4. UserDTO

package com.example.demo.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;


@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserDTO {
    private String token;
    private String email;
    private String username;
    private String password;
    private String id;
}

 

  • 사용자 서비스를 통해서 현재 사용자를 가져오는 기능과 레지스터 기능을 구현하는 Controller를 구현하기에 앞서 UserDTO를 먼저 구현한다.

5. UserController 구현

package com.example.demo.controller;


import com.example.demo.dto.ResponseDTO;
import com.example.demo.dto.UserDTO;
import com.example.demo.model.UserEntity;
import com.example.demo.service.UserService;
import org.apache.catalina.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/auth")
@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping("/signup")
    public ResponseEntity<?> registerUser(@RequestBody UserDTO userDTO) {
        try{
            //요청을 이용해서 저장할 사용자 만들기
            UserEntity user = UserEntity.builder()
                    .email(userDTO.getEmail())
                    .username(userDTO.getUsername())
                    .password(userDTO.getPassword())
                    .build();

            //서비스를 사용해 레포지토리에 사용자 저장
            UserEntity registerUser = userService.create(user);
            UserDTO responseUserDTO = UserDTO.builder()
                    .email(registerUser.getEmail())
                    .username(registerUser.getUsername())
                    .id(registerUser.getId())
                    .build();

            return ResponseEntity.ok().body(responseUserDTO);
        } catch (Exception e){
            ResponseDTO responseDTO = ResponseDTO.builder()
                    .error(e.getMessage())
                    .build();
            return ResponseEntity.badRequest().body(responseDTO);
        }
    }

    @PostMapping("signin")
    public ResponseEntity<?> authenticate(@RequestBody UserDTO userDTO){
        UserEntity user = userService.getByCredentials(
                userDTO.getEmail(), userDTO.getPassword());
        if(user != null){
            final UserDTO responseUserDTO = UserDTO.builder()
                    .email(user.getEmail())
                    .id(user.getId())
                    .build();
            return ResponseEntity.ok().body(responseUserDTO);
        } else {
            ResponseDTO responseDTO = ResponseDTO.builder()
                    .error("Login Failed")
                    .build();
            return ResponseEntity.badRequest().body(responseDTO);
        }

    }
}
  • 사용자 서비스를 이용해서 현재 사용자를 가져오는 기능과 레지스터 기능을 구현

정리 쇼

https://snepbnt.tistory.com/312

 

[Spring ] Spring 의 주요 구조에 대한 간단한 개념

Spring 을 공부하면서, Model, Repository, Controller 등 스프링에서 사용하는 구조들에 대해서 어떻게 하면 쉽게 이해를 할 수 있을까 생각을 해보았다. 1. Model Model 은 DAO 라고 생각하면 된다. Data Aecces..

snepbnt.tistory.com

스프링 구조를 조금 더 찬찬히 알아볼 것

https://transferhwang.tistory.com/106

 

[Spring] 스프링 MVC 프레임워크 설계 구조

1. 웹 프로그래밍을 구축하기 위한 설계 모델 위의 그림과 같이 브라우저(클라이언트)에서 요청을 서버로 보내면 WAS(웹 어플리케이션 서버)에서 처리를 하게 됩니다. 이때 관련 정보를 DB(데이터

transferhwang.tistory.com

참고로 Entity가 Model 패키지에 있는 이유는 프로젝트 규모가 작기에 둘을 합쳐 사용했기 때문입니다.

스프링 계층구조에 대해서 조금 더 공부하자