본문 바로가기

spring

[ Spring Boot 3 + Spring Security 6 + OAuth2.0 + JWT ] 마이그레이션과 같이 진행되는 OAuth2 로그인/회원가입 2

 

컨트롤러 ㄱ

이건 OAuth와 관련없이 그냥  Spring Boot 3 + Spring Security 6 + JWT 로 하는 로그인 인증/인가다.

package com.oauth.clientserver.controller;

import com.oauth.clientserver.controller.dto.LoginRequest;
import com.oauth.clientserver.repository.UserRepository;
import com.oauth.clientserver.repository.entity.UserEntity;
import com.oauth.clientserver.response.LoginResponse;
import com.oauth.clientserver.response.MapResponse;
import com.oauth.clientserver.service.ResponseService;
import com.oauth.clientserver.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;


@CrossOrigin(origins = "http://about:blank")
@RestController
@RequiredArgsConstructor
public class Oauth2LoginController {

    private final UserRepository userRepository;
    private final UserService userService;
    private final PasswordEncoder passwordEncoder;
    private final ResponseService responseService;

    final Log logger = LogFactory.getLog(getClass());


    @PostMapping("/user/login")
    @Operation(summary = "Login", description = "Login")
    public MapResponse<String> LoginAuth (@RequestBody LoginRequest userInfo, HttpServletRequest request) throws Exception {
        HttpSession session = request.getSession();
        String getEmail = userInfo.getEmail();
        String encodingPassword = userInfo.getPassword();

        UserEntity userEntity = userRepository.findByEmail(getEmail);
        String encodePw = userEntity.getPassword();

        if (passwordEncoder.matches(encodingPassword, encodePw)) {
            session.setAttribute("member", userInfo);
            String token = userService.login(userEntity.getEmail());

            String refreshToken = userService.refreshToken(userEntity.getName());

            LoginResponse loginResponse = new LoginResponse();
            Map<String, String> tokenMap = loginResponse.loginSuccess(token, refreshToken);

            return responseService.getMapResponse(tokenMap);
        }

        throw new Exception();

    }
}

 

이 부분은 OAuth로 로그인하지 않고 일반적인 로그인의 경우를 대비해서 만든 컨트롤러다.

OAuth를 통해 로그인/회원가입하는 경우 토큰은 프론트영역에서 로컬스토리지같은 데다 저장해서 관리하고 db에 리프레시토큰만 넣는다든가 그런식으로 관리하면 될 거 같고 내 애플리케이션 자체 로그인의 경우엔 내가 자체적으로 JWT를 발급해 주려고 한다.

OAuth를 공부하면서 젤 헷갈렸던 게 OAuth로 발급받은 인증코드로 토큰 발급 해주면 되는 거 아닌가..??했는데

그게 아니었던 것..같다 오어슨 ㄴ걍 내 구글계정 가져오는 권한 허락일 뿐이고

그 계정 가져다가 써드파티에서 쓰는 것과, 써드파티 이용자 토큰 관련해서는 자체적으로 인증/인가 해줘야한다..

처음엔 오어스가 다 해주는 거 아냐? 했는데 아니었음 ㅎ

아무튼,

이 컨트롤러의 기능은

body값에 로그인 정보를 POST하면 response에는 토큰 발급을 해주는 것이다.

토큰 + 내가 설정한 리스폰스 내용도 포함해서 !

컨트롤러의 핵심은 다른 것도 중요하지만 리스폰스ㅋㅋ같기도..예외처리랑...

아! 맞다 

이거는 지우길..프론트 테스트때문에 넣었던 거; ㅎ

이메일은 진짜 내 구글 아이디라 가리고,, 패스워드는 1편에 내가 하드코딩ㅋ했던 비번 1234를 넣어줬다.

그러면 이렇게 줌.

내가 노린 게 딱 저거다.

성공했다는 걸 알리는 코드, 메세지랑 body에 담기는 내용!

저게 왜 중요하냐? 이게 프론트에서 저 code 200을 가져다가 또 조건으로 쓸 수 있기도 하고,,아무튼 쓸모가 있더라고,,

프론트에서 api를 가져다 쓸 때 중요한 Response의 템플릿을 정해놓고 통일화 해서 내려주고 Exception을 관리해서 일괄적인 공통을 만들어 관리하는 게 정말 중요하다는 걸 실제 프로젝트 때 느꼈다 백엔드 개발자들이 자기 스타일대로 response를 만들면 프론트 입장에선 이사람 response 다르고 저사람 다르고 하니까 혼란이 오고 코드도 통일성 있게 컴포넌트 관리 못하고? 아무튼 코드량이 또 늘어나게 됨 

걍 같은 거면 통일해! 

이게 맞는듯

저런 데서 역량 차이도 느껴지기도 하고 ㅋㅋ 아무튼 난 저렇게 했땅.

아무튼 코드로 가면

주석을 보는 게 편할듯

잘 보이겠지..?

대충 db에 있는 값 비교해서 맞으면 토큰발급이 끝임.

토큰을 그냥 대충 두개 덜렁 내보내도 되지만 아까 말했듯이 통일성 있게 하기 위해 한번 더 감싸주긴 함.

그러면 로그인 인증까지 끝~!

너무 간단하네..

그리고 저런 방식이 맞는지..보장은 못한다..왜냐면 난 개판으로 개발했으니까...ㅎ..

관련 엔티티, 레포지토리, 리스폰스 관련된 클래스들은 3편에 깃헙이랑 같이 올리겟음