아직 와이어프레임이나 주요기능이 정해지지가 않아서 31일에 진행한 유스콘을 살짝 봤습니다.

클린아키텍쳐와 자바와 코틀린에 대해 설명한 부분을 봤는데

클린 아키텍쳐 부분은 지금 당장 적용이 가능할 것 같아 팀원들에게 함께 보자고 했습니다.

일부분은 당장 적용하기로 했습니다.

다행히 좋은 팀원들을 만나게 되어서 실전 프로젝트에 대한 걱정 하나는 놓게 되었습니다. 

디자이너분도 열정이 넘치셔서 좋습니다. 

 

저녁 8시에 디자이너님이 오신다고 하셔서 그전까지 실전 프로젝트 그라운드 룰을 정하고 백엔드 끼리 따로 회의를 해서 예외 처리와 응답 방식에 대한 컨벤션을 정했습니다. 

 

아이디어에 대한 회의는 하루종일 계속 되었습니다. 

저녁 회의를 통해 각자의 아이디어를 공유하고 투표를 통해 하나를 정했습니다.

저희팀은 디자이너 포함 총 6명으로 백엔드 3명, 프론트엔드 2명입니다. 

 

다들 잘하는 분들이고 아이디어도 많고 하고싶은것도 많은 열정피플들이라 의견조율하는데 오래걸리긴 했지만

결국 결론을 냈고 기획을 했습니다.

 

실전 6주동안 좋은 프로젝트가 나오길 바라면서 최선을 다하도록 하겠습니다. 

잘했음.

오늘은 카카오로그인을 스프링으로 구현하고 프론트와 연결해서 잘 작동하는 것을 확인했습니다. 생각보다 여러가지 시행착오를 많이 겪었지만 결국에는 해냈습니다. 이제 예외처리만 하고 자려고합니다. 

 

하루종일 왜 안되지하다가 오 되네?로 바뀌었습니다.

 

역시 낮잠이 최고야.

 

카카오 로그인 Postman

카카오 로그인 스프링으로 구현하기

코드 자체는 강의에서 온 거라 그냥 복붙 수준이긴 했습니다만 카카오 디벨로퍼 설정이라던지 프론트와의 연결을 위한 redirect uri 등 설정해주어야 할 것들이 많이 있었습니다. 코드는 아래와 같습니다.

 

KakaoService



@Slf4j
@RequiredArgsConstructor
@Service
public class KakaoService {

    private final PasswordEncoder passwordEncoder;
    private final MemberRepository memberRepository;
    private final JwtUtil jwtUtil;

    @Value("${kakao.client.id}")
    private String kakaoClientId;

    @Value("${kakao.redirect.uri}")
    private String kakaoRedirectUri;

    public Response kakaoLogin(String code, HttpServletResponse response) throws JsonProcessingException {
        // 1. "인가 코드"로 "액세스 토큰" 요청
        String accessToken = getToken(code);
        // 2. 토큰으로 카카오 API 호출 : "액세스 토큰"으로 "카카오 사용자 정보" 가져오기
        SocialMemberInfo kakaoMemberInfo = getKakaoMemberInfo(accessToken);
        // 3. 필요시에 회원가입
        Member kakaoMember = registerKakaoMemberIfNeeded(kakaoMemberInfo);

        // 4. JWT 토큰 반환
        String createToken =  jwtUtil.createAccessToken(kakaoMember.getName());
        response.addHeader(JwtUtil.AUTHORIZATION_ACCESS, createToken);
        return new Response(200, "로그인 성공", createToken);
    }

    // 1. "인가 코드"로 "액세스 토큰" 요청
    private String getToken(String code) throws JsonProcessingException {
        // HTTP Header 생성
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

        // HTTP Body 생성
        MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
        body.add("grant_type", "authorization_code");
        body.add("client_id", kakaoClientId);
        body.add("redirect_uri", kakaoRedirectUri);
        body.add("code", code);

        // HTTP 요청 보내기
        HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest =
                new HttpEntity<>(body, headers);
        RestTemplate rt = new RestTemplate();
        ResponseEntity<String> response = rt.exchange(
                "https://kauth.kakao.com/oauth/token",
                HttpMethod.POST,
                kakaoTokenRequest,
                String.class
        );

        // HTTP 응답 (JSON) -> 액세스 토큰 파싱
        String responseBody = response.getBody();
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = objectMapper.readTree(responseBody);
        return jsonNode.get("access_token").asText();
    }

    // 2. 토큰으로 카카오 API 호출 : "액세스 토큰"으로 "카카오 사용자 정보" 가져오기
    private SocialMemberInfo getKakaoMemberInfo(String accessToken) throws JsonProcessingException {
        // HTTP Header 생성
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Bearer " + accessToken);
        headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

        // HTTP 요청 보내기
        HttpEntity<MultiValueMap<String, String>> kakaoMemberInfoRequest = new HttpEntity<>(headers);
        RestTemplate rt = new RestTemplate();
        ResponseEntity<String> response = rt.exchange(
                "https://kapi.kakao.com/v2/user/me",
                HttpMethod.POST,
                kakaoMemberInfoRequest,
                String.class
        );

        String responseBody = response.getBody();
        System.out.println(responseBody);
        System.out.println(response);
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = objectMapper.readTree(responseBody);
        String id = jsonNode.get("id").asText();
        String name = jsonNode.get("properties")
                .get("nickname").asText();
        String email = jsonNode.get("kakao_account")
                .get("email").asText();

        return new SocialMemberInfo(id, email, name);
    }

   
    

}

 

그리고 컨트롤러는 아래와 같습니다.

 

@GetMapping("/login/kakao")
public Response<?> kakaoLogin(@RequestParam String code
      , HttpServletResponse response)
      throws JsonProcessingException {

   return kakaoService.kakaoLogin(code, response);
}

 

@RequestParam 으로 받아주면 Url에 ?으로 요청을 하게 됩니다. 

 

 

 

프론트랑 연결하기 (맥북)

프론트의 로컬 서버인 localhost:3000을 직접 리액트와 node.js를 다운받아서 사용했습니다.

 

프론트의 깃헙을 포크해서 제 맥북에서 돌렸습니다.

프론트의 코드를 실행하기 전에 다음과 같이 yarn 을 설치해주었습니다.

 

sudo yarn install
yarn start

위의 명령어를 입력해주고

localhost:3000을 띄워서 연결을 확인합니다.

 

카카오 로그인 버튼에 링크를 걸어줬습니다.

 

 

 

 

클린코딩

객체지향 생활체조라는 걸 배웠습니다.

https://hudi.blog/thoughtworks-anthology-object-calisthenics/

 

이유와 솔루션으로 정리하는 객체지향 생활체조 원칙

객체지향 생활체조 원칙 소트웍스 앤솔러지 표지 "어떤 멍청이라도 컴퓨터가 이해할 수 있는 코드는 작성할 수 있다. 좋은 프로그래머는 사람이 이해할 수 있는 코드를 작성한다. (Any fool can write

hudi.blog

 

배울게 너무 많습니다.

튜토리얼은 계속되고있습니다. 

 

 

예외처리

https://escapefromcoding.tistory.com/699

 

Spring에서 예외 처리하기

안녕하세요, oooo 백성규선임입니다. 스프링을 사용하면서 예외처리는 무엇이고 어떻게하는 것인지 공부하면서 조금 더 효율적으로 관리하는 방법에 대해 공유하고자 합니다. 이번 시간에 자바

escapefromcoding.tistory.com

 

자바에 대한 이해가 너무나 부족해서 해매고 있는 요즘입니다.

자바의정석으로는 알수없는 스프링의 세계에요. 이제는 그냥 되는대로 그때그때 에러와 에러를 에러와 함께 스프링과 자바에 대한 부족함을 극복하고 있습니다. 

BeanCreationException

BeanCreationException

위의 사진처럼 에러가 떴습니다. 저는 kakao 로그인을 구현 하려고 했습니다.  지난 주차에서 다른 조원분이 하신 코드를 그대로 가져왔는데 에러가 떴습니다. 어차피 사용자 정보를 User가 아니고 Member로 저장한 거 밖에 다른 게 없다고 생각했기 때문입니다. 그런데!!!! 왜 자꾸 저렇게 에러가 뜨는지 모르겠었어요.

 

구글 해보니 Bean을 제대로 설정해주지 않아서, 제대로 주입해주지 않아서 생긴 문제라고 했습니다.

@Component, @Service, @Controller같은 Bean 등록이 안되있어서 그렇다고 하더라고요. 그런데 확인 결과 해당 어노테이션들은 잘 붙어있었습니다. 

 

 

해결

저희팀에는 숙련된 조교분이 계십니다. 

저희반자체에 컴공 전공하신 분들이 절반이 넘는다고 합니다. 

사전스터디가 첫 코딩이었던 (그게 벌써 3개월도 전입니다....) 저와 같은 비전공자 노베이스 분들께는 그저 빛입니다. 

 

제가 하루종일 고민하고 찾아봐도 모르겠었는데 설마 이거겠어 했던게 이거였습니다.

팀원분이 바로 보고 application.properites에  등록했어요? 라고 문제를 찾아내셨습니다.

 

application.properties에 등록해주면 됩니다.

encryptor와 kakao 관련해서 properties를 추가했고 @value로 보안관련 키값들을 저장해놨습니다.

그걸 사용하려면 application.properties에

 

spring.profiles.include=

에 값을 넣어주어야합니다.

 

저희는 applicaiton.properties파일에 아래와 같이 파일들이 들어있기 때문에

아직 커밋을 안해서 빨갛습니다.

spring.profiles.include= dev, kakao, encryptor

 

라고 써줘야 해당 값들을 불러와서 쓸 수 있었습니다. 

 

BeanCreationException에서 아래 자료도 참고하면 좋을듯합니다.

https://www.baeldung.com/spring-beancreationexception

 

카카오 로그인 accesstoken 받기

1. Oauth에 클라이언트가 Authorization code 요청

2. Oauth가 redirect uri를 통해 클라이언트에 Authorization code 부여

3. 클라이언트가 Authorization code 를 서버에 전달

4. 서버가 Authorization code를 Oauth에 보내서 Acess token 요청

5. OAuth가 Acesstoken을 서버에 부여

6. 서버는 클라이언트에 Acess token을 전달

 

위와 같은 과정을 거쳐 소셜 로그인을 하게됩니다.

 

저는 카카오 로그인을 맡았는데

프론트에 accesstoken을 발급받아서 백에 전달하는 식으로 진행을 할 거라

프론트분들과 보조를 맞춰야해서 아직 서버 연결은 못해봤지만 코드는 완성했고 멀쩡히 실행은 됩니다. 

 

곧 실전 주차 6주짜리 프로젝트

 

다음주부터 실전 주차인데

아이디어들은 많습니다. 개발자분들은 기획은 관심없고 기술 구현에만 관심이 있으신듯한데 경영학도 출신인 저는 기획이 잘 되야 만드는 보람이 있을 것 같습니다.

 

오늘 떠오른 아이디어는 소개팅앱입니다.

매칭되면 만나기 전에 화상 채팅해서 괜한 발걸음 할 필요 없는 그런 소개팅 앱을 구상해봤습니다.

 

적당히 자격조건을 걸어서 회원 가입 자격도 주고요. 

카카오로그인

이거 쉽지 않네요.

기존에 다른 조원분들이 하셨던 코드를 참조하는데 이해가 안되서 한참을 들여다봅니다. 내일까지 완성해보려고 해요. 

검색 기능도 좀 해보면 좋을 듯 해서 찾아보려구요.

 

크리스마스 기념 뮤지컬 관람

엄밀히 말하면 며칠 남았지만 그래도 세월이 빠르다는 점은 부정할 수 없는 사실입니다. 

처음으로 백앤드 프론트앤드가 함께 협업을 했고 결과물을 만들어냈습니다.

 

 

TIL 첫 미니프로젝트 회고 221222

https://github.com/faulty337/CatsAndDogs-BE GitHub - faulty337/CatsAndDogs-BE Contribute to faulty337/CatsAndDogs-BE development by creating an account on GitHub. github.com ReadMe 정리 아무도 안하시니까 제가 이번 주중이나 올해가 가

pizzathedeveloper.tistory.com

 

 

또 이번주차 새로운 프로젝트를 시작했습니다.

 

 

TIL 클론 코딩 기획하기 221223

세세한 것들까지 다 정해서 하느라 기획을 하루종일 했습니다. 9 to 9 full 로 기획하고 나왔습니다. 재주상회라는 사이트를 클론하기로 했습니다. 콘텐츠그룹 재주상회 콘텐츠그룹 재주상회는 미

pizzathedeveloper.tistory.com

 

깃헙을 이용해서 협업도 합니다.

 

 

TIL 깃헙 활용해서 협업하기 (Feat. mapStruct) 221224

이번 주차에서는 팀원들과의 논의 끝에 깃헙을 더 많이 활용해서 협업을 하기로 했습니다. 그래서 다음과 같이 진행이 됩니다. 1. 깃헙에서 이슈 만들기 2. 로컬에서 feature/#이슈번호 브랜치를 만

pizzathedeveloper.tistory.com

 

마케팅 포인트로 이 부트캠프는 프로젝트를 4개 한다였는데 사실은 1개라고 합니다. 1주짜리는 포트폴리오가 될 수 없고 마지막에 하는 6주짜리 프로젝트 하나에 영혼을 갈아넣어 취업용 프로젝트를 만들어야 한다고 합니다. 잘 모르는 비전공자한테는 다소 당황스럽습니다. 근데 뭐 이것도 말하기 나름이겠지요.

 

이번주차랑 지난주차는 잠시 쉬어가면서 실전주차 프로젝트를 위한 연습입니다. 

 

이제 끝까지 고수하던 긴 손톱을 제거하고 개발자 면접용 손톱으로 바꾸고 취업을 준비해야겠네요.

다시 취준생이 된 것은 스트레스지만 새로운 것을 도전한다는 것은 언제나 신나는 일입니다.

 

 

이번 주차에서는 팀원들과의 논의 끝에 깃헙을 더 많이 활용해서 협업을 하기로 했습니다. 그래서 다음과 같이 진행이 됩니다.

 

1. 깃헙에서 이슈 만들기
2. 로컬에서 feature/#이슈번호 브랜치를 만들어서 작업하기
3. 푸시하기
4. 해당 이슈에 PR 날리기

 

1. 깃헙에서 이슈 만들기

깃헙 이슈

 

2. 로컬에서 feature/#이슈번호 브랜치에서 작업

feature/#7 브랜치를 생성해서 작업

 

3. 푸시하기

 

4. 해당 이슈에 PR 날리기

PR

 

 

오늘은 깃헙이슈를 사용해서 작업을 마쳤습니다. 생각보다 체계적이여서 좋습니다. Mapper도 처음 써봤습니다.

예외처리에 대해서도 이야기를 나누고 왠만하면 자바에 있는 기본 예외 처리를 쓰기로 했습니다.

 

 

Mapper

@Component
public class ProductMapper {

    public static ProductDetailResponse toResponse(Product product){
        return ProductDetailResponse.builder()
                .productId(product.getProductId())
                .name(product.getName())
                .price(product.getPrice())
                .caption(product.getCaption())
                .bigThumbnailImgUrl(product.getBigThumbnailImgUrl())
                .detailImgUrl(product.getDetailImgUrl())
                .build();
    }
}

 

매퍼는 팀원분의 코드를 좀 빌려왔습니다. Mapstruct이란 게 있어서 @Mapper 어노테이션을 쓰면 쉽다고 하는데 하루종일보는데 너무 피곤해서 못하겠어서 2시간 낮잠자고 나니까 머리가 맑아져서 금방 기능 완성했습니다.

 

컨디션 안좋을 땐 낮잠을 자는게 최고인듯 합니다. 

 

 

오늘은 크리스마스이브여서 10시전에 퇴근했습니다. 

 

세세한 것들까지 다 정해서 하느라 기획을 하루종일 했습니다. 9 to 9 full 로 기획하고 나왔습니다. 

재주상회라는 사이트를 클론하기로 했습니다.

 

장바구니 기능 만들기

 

 

콘텐츠그룹 재주상회

콘텐츠그룹 재주상회는 미디어, 브랜딩과 디자인, 상품개발, 공간개발과 관리 등의 사업 영역을 운영합니다.

iiinjeju.com

왠지 근데 이거 무료툴로 만든거 같기도한데

 

이번에는 지난 주차와 다르게

모든 도메인을 기술만 나눠서 파트를 분배하였습니다.

자바 컨벤션도 정하고 이것저것 정하고 응답 컨벤션, 커밋 등등....

또 이렇게 새로운 팀원들과 함께하니 배우는 것들이 많아서 좋습니다.

제가 미쳐 알지 못한(아마 대부분의 모든 지식들)것들에 대해 어떤식으로 활용하고 왜 쓰는지에 대한 대화를 나누었습니다.

에러 처리에 대해서도 왜 굳이 customexception을 만들어야하는지에 대해서도 논의를 했는데 저는 당연히 개발자 쓰기 편하라고 하는거 아닌가였는데 새로운 관점으로 생각하게 되었습니다.

 

협업에 대해서 알아가는 과정이 나름 신선하고 재미있습니다.

 

 

https://github.com/faulty337/CatsAndDogs-BE

 

GitHub - faulty337/CatsAndDogs-BE

Contribute to faulty337/CatsAndDogs-BE development by creating an account on GitHub.

github.com

ReadMe 정리 아무도 안하시니까 제가 이번 주중이나 올해가 가기전에 하도록 할게요.

좋은 팀원들과 좋은 경험이었습니다.

+ Recent posts