Project

[stock] 회원 관리 - 컨트롤러 구현

sangyunpark 2023. 9. 21. 21:56

컨트롤러 구현

package com.example.stock.controller;

import com.example.stock.entity.MemberEntity;
import com.example.stock.model.Auth;
import com.example.stock.security.TokenProvider;
import com.example.stock.service.MemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
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;

@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthController {

    private final MemberService memberService;
    private final TokenProvider tokenProvider;

    @PostMapping("/signup")
    public ResponseEntity<?> signup(@RequestBody Auth.SignUp request){
        // 회원가입 api

        MemberEntity result = memberService.register(request);

        return ResponseEntity.ok(result);
    }

    @PostMapping("/signin")
    public ResponseEntity<?> sigin(@RequestBody Auth.SingIn request){
        // 로그인 api
        
        // 아이디 패스워드 인증
        MemberEntity member = memberService.authenticate(request);

		// 토큰 생성
        String token = tokenProvider.generateToken(member.getUsername(), member.getRoles());

        // 토큰 반환
        return ResponseEntity.ok(token);
    }
}

회원가입시

아이디가 존재하는지 확인한 후(service코드)

존재하지 않을때 회원가입

 

로그인시

아이디, 비밀번호 일치 여부 확인 후

일치할 경우 토큰생성

 

MemberService

package com.example.stock.service;

import com.example.stock.entity.MemberEntity;
import com.example.stock.model.Auth;
import com.example.stock.repository.MemberRepository;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

@Slf4j
@Service
@AllArgsConstructor
public class MemberService implements UserDetailsService { // Spring security를 사용하기 위해 UserDetailsService 구현

    private final PasswordEncoder passwordEncoder; // Bean으로 정의
    private final MemberRepository memberRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
       return memberRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("couldn't find username")); // orElseThrow로 인해 Optional이 벗겨진다.
    }

    public MemberEntity register(Auth.SignUp member){ // 회원 가입한

        boolean exists = memberRepository.existsByUsername(member.getUsername()); // 아이디가 중복되었는가?

        if(exists){ // 중복이 되지 않은 경우
            throw new RuntimeException("이미 사용중인 아이디 입니다.");
        }

        // 비밀번호 암호화 - passwordEncoder
        member.setPassowrd(passwordEncoder.encode(member.getPassowrd()));
        return memberRepository.save(member.toEntity());
    }

    public MemberEntity authenticate(Auth.SingIn member){ // 패스워드 인증 작업

        MemberEntity user = memberRepository.findByUsername(member.getUsername())
                .orElseThrow(() -> new RuntimeException("존재하지 않는 ID 입니다."));
        // memberEntity의 비밀번호는 Encoding된 비밀번호가 들어있다.

        if(!passwordEncoder.matches(member.getPassword(), user.getPassword())){
            throw new RuntimeException("비밀번호가 일치하지 않습니다.");
        }

        return user;
    }
}