Tiny Star

🏕️내일배움캠프/📂나만의 항해 블로그 백엔드 서버 만들기(23.06.12)

개인과제 - 나만의 항해 블로그 백엔드 서버 만들기 Lv2

청크 2023. 7. 12. 20:25

스파르타 코딩클럽_내일 배움 캠프 spring 트랙 6기

[프로젝트] 나만의 항해 블로그 백엔드 서버 만들기 Lv2

2023.06.19 ~ 2023.06.29

<프로젝트 정보>

개발도구 : IntelliJ

프로그래밍 언어 : Java

데이터베이스 : MySQL

프레임워크 : Spring

저장소 : GitHub

기타서비스 : Postman

 

<프로젝트 내용>

1. 회원 가입 API

      · username, password를 Client에서 전달받기

      · username은 최소 4자 이상, 10자 이하이며 알파벳 소문자(a~z), 숫자(0~9)로 구성되어야 한다.

      · password는 최소 8자 이상, 15자 이하이며 알파벳 대소문자(a~z, A~Z), 숫자(0~9)로 구성되어야 한다.

      · DB에 중복된 username이 없다면 회원을 저장하고 Client 로 성공했다는 메시지, 상태코드 반환하기

      · 참고자료

            https://mangkyu.tistory.com/174

            https://ko.wikipedia.org/wiki/정규_표현식

            https://bamdule.tistory.com/35

2. 로그인 API

      · username, password를 Client에서 전달받기

      · DB에서 username을 사용하여 저장된 회원의 유무를 확인하고 있다면 password 비교하기

      · 로그인 성공 시, 로그인에 성공한 유저의 정보와 JWT를 활용하여 토큰을 발급하고, 발급한 토큰을 Header에 추가하고 성공했다는 메시지, 상태코드

         와 함께 Client에 반환하기

 

[내가 작성한 코드]

지난 Lv1에서 비밀번호 기능 구현은 하지 못한채로 과제 제출을 했다.

Lv2에서 비밀번호 기능 구현까지 완료.

 

[UserController]

package com.sparta.blogapi.controller;

import com.sparta.blogapi.dto.LoginRequestDto;
import com.sparta.blogapi.dto.SignupRequestDto;
import com.sparta.blogapi.dto.UserResponseDto;
import com.sparta.blogapi.service.UserService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;

@Slf4j
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor  //생성자 주입으로 userService에 대한 생성자를 생성하지 않아도 됨
public class UserController {

    private final UserService userService;


//    1. 회원 가입 API
    @PostMapping("/user/signup")
    public UserResponseDto signup(@RequestBody SignupRequestDto requestDto,HttpServletResponse res){
        return userService.signup(requestDto,res);
    }



//2. 로그인 API
    @PostMapping("/user/login")
    public UserResponseDto login(@RequestBody LoginRequestDto requestDto, HttpServletResponse res) throws IOException {

        return userService.login(requestDto,res);
    }
}

[UserService]

package com.sparta.blogapi.service;


import com.sparta.blogapi.dto.LoginRequestDto;
import com.sparta.blogapi.dto.SignupRequestDto;
import com.sparta.blogapi.dto.UserResponseDto;
import com.sparta.blogapi.entity.User;
import com.sparta.blogapi.jwt.JwtUtil;
import com.sparta.blogapi.repository.UserRepository;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.IOException;
import java.util.Optional;

@Service //Service 사용
@RequiredArgsConstructor //생성자 주입으로 데이터베이스에 대한 생성자를 생성하지 않아도 됨
@RequestMapping("/api")
public class UserService {

    private final UserRepository userRepository; // userRepository 주입
    private final PasswordEncoder passwordEncoder; //비밀번호 암호화 인터페이스
    private final JwtUtil jwtUtil;

    //    1. 회원 가입 API
    public UserResponseDto signup(SignupRequestDto requestDto,HttpServletResponse res) {
        // username, password를 Client에서 전달받기
        String username = requestDto.getUsername();
        String password = passwordEncoder.encode(requestDto.getPassword());

        // 유저 중복확인
        Optional<User> checkUsername = userRepository.findByUsername(username);
        if (checkUsername.isPresent()) { // isPresent()는 Optional 객체가 비어있지 않은 경우에 true를 반환하고, 값이 존재하지 않는 경우에 false를 반환
            //중복된 유저네임이 존재 할 경우 예외처리
            throw new IllegalArgumentException("중복된 사용자가 존재합니다.");
        }

        // 유저 등록
        userRepository.save(new User(username,password));

        UserResponseDto userResponseDto = new UserResponseDto("회원가입이 완료되었습니다.", 200);
        //    - DB에 중복된 username 이 없다면 회원을 저장하고 Client 로 성공했다는 메시지, 상태코드 반환하기
        return userResponseDto;
    }


    //    2. 로그인 API
    @Transactional(readOnly = true)
    public UserResponseDto login(LoginRequestDto requestDto, HttpServletResponse res) throws IOException {
        //    - username, password를 Client에서 전달받기
        String username = requestDto.getUsername();
        String password = requestDto.getPassword();
        //username 확인
        //    - DB에서 username을 사용하여 저장된 회원의 유무를 확인하고 있다면 password 비교하기
        User user = userRepository.findByUsername(username).orElseThrow(
                ()-> new IllegalArgumentException("회원가입 된 사용자가 없습니다."));

        //password 확인
        if (!user.getPassword().equals(password)) {
            throw new IllegalArgumentException("비밀번호가 일치하지 않습니다.");
        }

        //로그인에 성공한 유저의 정보와 JWT를 활용하여 토큰을 발급
        //JWT Token 생성 및 쿠키에 저장
        String token = jwtUtil.createToken(user.getUsername());

        //Response 객체에 추가,
        jwtUtil.addJwtToCookie(token, res);

        // 로그인 성공
        UserResponseDto userResponseDto = new UserResponseDto("로그인에 성공하였습니다.",HttpServletResponse.SC_OK);
        return userResponseDto;
    }



}

 

https://github.com/hyunkyounglee1209/Spring_Lv2.git

 

GitHub - hyunkyounglee1209/Spring_Lv2: 스프링 주특기 숙련 _ 나만의 항해 블로그 백엔드 서버 만들기

스프링 주특기 숙련 _ 나만의 항해 블로그 백엔드 서버 만들기. Contribute to hyunkyounglee1209/Spring_Lv2 development by creating an account on GitHub.

github.com