JPA 37

🚨ERROR - 사용자 인증_500 error 올바르게 처리하기

🌑 문제 발생애플리케이션에서 인증되지 않은(유효하지 않은 토큰이나, 아예 토큰을 넣지 않은 경우) 사용자가 API 요청을 보냈을 때 401 Unauthorized 에러가 발생해야 하지만, 실제로는 500 Internal Server Error가 발생했다. 당장에 문제가 되는 것은 아니지만 상황별로 적절한 오류가 발생해야 프론트와 작업할 때도 문제가 없이 적절히 처리할 수 있을 거 같아서 반드시 해결을 하고 넘어가고 싶었다.  해결을 해봐야 한 걸음 성장할 수 있으니까ㅎㅎ 🌕 해결  -  defaultAuthenticationEntryPointFor 사용.exceptionHandling(exceptionHandling -> exceptionHandling .de..

[개발] - MapStruct를 사용하여 매핑 구현하기

Spring Boot 애플리케이션에서 엔티티(Entity)와 DTO(Data Transfer Object) 간의 데이터를 변환할 때, 수동으로 변환하는 대신 Mapper를 사용하면 코드의 가독성을 높이고 유지보수를 용이하게 할 수 있다.이를 위해 흔히 사용되는 라이브러리가 MapStruct이다.(이전에는 항상 수동으로 하나하나 엔티티와 DTO를 매핑했었는데 이번에 새롭게 MapStruct를 알게 되어 사용해 보게 되었다.) 🩵 MapStruct란? MapStruct는 자바 애플리케이션에서 객체 간의 매핑을 간편하게 해주는 코드 생성기이다. 컴파일 타임에 매핑 코드를 생성하여 런타임 오류를 줄이고, 매우 효율적인 매핑 구현을 제공한다.Spring Boot와의 통합도 쉽게 이루어지며, 주로 엔티티를 DTO..

🚨ERROR - [spring boot] GET 요청 시 406 오류 발생

🏕️ 문제 발생최근 Spring Boot 기반의 웹 애플리케이션에서 GET 요청을 테스트하기 위해 Postman을 사용했다. API 엔드포인트는 특정 사용자의 정보를 반환하는 기능을 가지고 있었고, 요청이 성공적으로 처리되기를 기대했다. 그러나 요청을 전송할 때 HTTP 406 Not Acceptable 오류가 발생했다. 이 오류는 서버가 클라이언트의 요청에 적합한 응답을 제공할 수 없을 때 발생하는 것이다.💦 오류의 원인HTTP 406 오류의 주요 원인은 서버가 요청한 형식으로 응답을 제공할 수 없을 때 발생한다. 클라이언트에서 요청을 보낼 때 Accept 헤더를 통해 원하는 응답 형식을 명시하고, 서버가 이 형식으로 응답하지 않으면 406 오류가 발생한다.  🔑 문제 분석 및 해결 과정문제 해결..

[11강] 네이버 로그인 완료

🤍[네이버 개발자 사이트]에 들어가서 다음과 같이 진행하여 id와 비밀번호를 발급받아 준다. 🤍앞서 진행한 것과 마찬가지로 해당 값을 각각 코드에 넣어준다. # naver OAuth2 설정 spring.security.oauth2.client.registration.naver.client-id=vFzQdx0GIL_gWvfx9i1k spring.security.oauth2.client.registration.naver.client-secret=[비밀번호 값] spring.security.oauth2.client.registration.naver.scope=email,profile spring.security.oauth2.client.registration.naver.client-name=Naver spri..

🤦🏻‍♀️고민하기 - 중복되는 코드 리팩토링 - 피드백 게시판 CRUD

🏕️상황게시판의 형식으로 (개발 관련해서) 웹 사이트의 오류, 개선사항, 에러 발견 등의 사항들을 올릴 수 있도록 개발하는 것이 목표였다.게시글에 대한 권한 부여를 어떻게 구현할 것인지 살짝 고민이 되었지만 spring security를 사용하지 않아도 복잡하거나 어렵지 않게 구현할 수 있을 거 같아 일단은 단편적인 방법으로 구현하기로 했다.기능 개발을 다 하고 보니 여러 메서드들에 공통적으로 사용되는 부분이 있었고, 그걸 보니 최근에 배운 내용이 생각났다. (아래와 같은) 🔽공통적으로 사용되는 부분은 끄집어 내서 따로 정의한다. ⭐리팩토링 전 코드@Servicepublic class feedbackService { @Autowired private feedbackRepository rep..

[java] Optional - Optional의 매핑 메소드

🏕️상황 Optional을 사용해야 하는 상황에서 코드를 좀 더 간결하게 하고자 하는 방법을 찾다가 발견한 것이 Optional의 map 함수였다. map 함수라고 하면 java 컬렉션의 map 함수만 생각이 나서 의아했다... '그 map 함수가 optional에서도 연산을 수행하나...?'라는 생각이 들었다. 알아보니 optional 객체의 map() 함수가 따로 존재했던 것이다!!! 그래서 오늘은 아래의 주제에 대해 알아보려고 한다. Optional의 매핑 메소드 optional의 매핑 메서드는 map() 및 flatMap() 이렇게 두개의 주요 메소드를 포함한다. 이러한 메소드를 사용해서 Optional 안의 값을 변환하거나 매핑할 수 있다. 💚map() 메소드 Optional 안의 값을 변환하려..

[8강] Authentication 객체가 가질 수 있는 2가지 타입

로그인 방식은 2가지가 있다. 일반 로그인 aouth 로그인 > 일반로그인으로 접근하려면 controller에서 @AuthenticationPrincipal PrincipalDetails userDetails > 구글로그인으로 접근하려면 controller에서 @AuthenticationPrincipal OAuth2User oauth => 일반 로그인은 PrincipalDetails 에서 유저 정보를 가지고 오는 것이고, oauth 로그인에서는 OAuth2User에서 유저의 정보를 가지고 오는 것이다. 이처럼 서로 다른 두 로그인 방식에 접근하기 위해서 서로 다른 방식을 사용해야한다, 🗝️해결 기존 PrincipalDetails 클래스는 1) 아래처럼 UserDetails만 구현하는 상태였지만 2) 추가..

[7강] 구글 회원 프로필 정보 받아보기

🏕️상황 현재 상태는 구글로 로그인을 완료한 것까지다. 로그인만 했을 뿐 그 뒤에 어떻게 처리를 할지는 아직 구성하지 않았다. 💦과정 .userInfoEndpoint() OAuth 2.0 로그인 프로세스의 일부로 사용자 정보를 가져오는 데 관련된 설정을 제공한다. 이 메서드는 사용자 정보 엔드포인트(User Info Endpoint)와 관련된 구성을 정의한다. .userInfoEndpoint()는 사용자 정보를 가져오는 방법과 구조를 설정한다. .userService() 사용자 정보를 가져온 후에 해당 정보를 어떻게 처리할지를 정의한다. principalOauth2UserService는 사용자 정보를 처리하기 위한 사용자 정의 서비스 빈(Bean)을 참조한다. 사용자 정보를 가져온 후에, 이 메서드를 사..

[6강] 구글 로그인 준비

1. 해당 사이트에 접속한다. https://console.cloud.google.com/projectcreate?previousPage=%2Fapis%2Fdashboard%3Fhl%3Dko%26project%3Dsrpingboot-outh&organizationId=0&hl=ko Google 클라우드 플랫폼 로그인 Google 클라우드 플랫폼으로 이동 accounts.google.com 2. 프로젝트를 하나 생성한다. 3. User Type을 설정한다. (1단계에서 이메일만 필수적으로 작성해야 해서 작성하고 그 뒤에 적어야 하는 곳들은 모두 skip) 4. 사용자 인증 정보 만들기 여기서 https로 요청했는데 그러면 로컬 프로젝트용으로는 오류가 난다. http로 해야 한다. --------------..

[5강] 메소드 단위로 권한 설정하기 - @Secured

이렇게 핑크 박스의 코드처럼 설정해 주면 이 프로젝트 전역에 권한을 설정해 줄 수 있다. 그런데 이번 강의에서 배운 내용은 하나의 메소드(요청, url) 단위로 권한을 설정해 줄 수 있는 방법에 대해 알아보았다. @Secured @Secured("ROLE_ADMIN") @GetMapping("/info") public @ResponseBody String info() { return "개인정보"; } "/info"에 접근하려면 유저의 Authorities이 ROLE_ADMIN이어야 한다. 이렇게 함수 단위로 접근할 수 있다. @PreAuthorize @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_MANAGER')") @GetMapping("/data") ..