Spring Security를 적용하면 매 실행시 마다 임시 사용자에 대한 비밀번호가 콘솔에 출력됩니다. 해당 비밀번호가 더이상 출력되지 않도록 하기 위해서는 아래와 같이 적용하면 더이상 출력되지 않습니다. application.yml spring: autoconfigure: exclude: org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration
웹 개발에서 인증과 인가는 사용자의 신원을 확인하고, 리소스 접근 권한을 제어하는 중요한 부분입니다. 이 과정에서 주로 쿠키, 세션, 그리고 JWT를 많이 사용하며 이는 안정적인 웹을 구축하는데 필수적입니다. 이 세 기술의 차이점과 장단점에 대해 알아보겠습니다. 인증/인가 인증(Authentication) 해당 유저의 신원을 확인하는 행위 주로 아이디와 비밀번호 확인으로 사용자 신원을 검증 인가(Authorization) 인증 완료된 회원이 특정 리소스에 접근할 수 있는 권한이 있는지 확인하는 행위 관리자 페이지의 접속 등... 쿠키(Cookie) 쿠키는 클라이언트 측에 저장되는 작은 데이터 입니다. 브라우저는 서버에서 받은 쿠키를 저장해두었다가, 동일한 서버로 재요청할 때 쿠키를 함께 전송한다. 쿠키의..
CORS(Cross-Origin-Resource Sharing)는 다양한 원천(Origin) 사이에서 자원(Resource)을 공유할 수 있도록 하는 웹 보안 메커니즘입니다. 현대에 클라이언트와 서버를 분리해 개발하면서 많이 사용되므로 필수적인 기술입니다. CORS란 무엇인가? 웹 페이지는 SOP(Same Origin Policy)정책을 따르기에 동일한 출처의 리소스만 공유할 수 있습니다. 하지만 웹 서비스가 커지고 클라이언트와 서버를 분리함으로 다른 출처와의 리소스 공유가 발생했고, 다른 출처와 리소스를 공유할 수 있도록 허용해주는 것을 CORS라고 합니다. Origin이란 무엇인가? Origin은 프로토콜, 도메인 이름, 포트번호를 말하고 오리진이 다르다는 것은 이 3개 중에 하나라도 다른면 다른 오..
DB 설계 시 자식 테이블에 부모의 PK를 소유하고 있고, 부모 삭제 시 여러 가지의 제약조건을 통해 PK의 값을 null로 변경해 주거나, PK를 소유한 자식의 데이터를 삭제 등... 여러 동작을 할 수 있다. 하지만 jpa에서는 자식 데이터를 조회해 값을 수정한 다음 저장하는 방식으로 동작해야 한다. 이에 변경감지에 의한 업데이트, 벌크 업데이트에 대해 알아보자. 변경감지 업데이트 변경감지란 엔티티가 조회 또는 저장시 영속성 컨텍스트의 1차 캐시에 저장이 되고 트랜잭션 전 flush 동작시 1차 캐시에 저장된 값과 현재의 값을 비교해 업데이트 쿼리를 생성 후 실행하는 것을 의미한다. List todos = todoRepository.findAllByProjectAndStatusOrderByEndDat..
프로젝트 내에서 실시간 채팅을 웹 소켓을 이용해 구현했고, 개발 환경에서는 아무 문제 없이 동작했는데 배포 환경에서 websocket connection to failed가 발생했습니다. 해결 방법 /etc/nginx/sites-available/reverse-proxy.conf 파일 수정 proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; location / { proxy_pass http://127.0.0.1:8081; proxy_http_version 1.1; # 추가 proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; p..
프로젝트 중 동일한 게시글을 여러 유저가 동시에 접근했을 때 조회수의 증가값이 유저의 수만큼 나오지 않는 문제가 생겼습니다. 해당 문제의 원인과 해결과정에 대해 공유합니다. 테스트 세팅 어떤 문제가 발생했는지 코드와 JMeter를 통해 보여드리겠습니다. Post 엔티티 public class Post extends BaseEntity{ //... private Long view; public void increaseView() { this.view++; } } PostService @Transactional public PostResponseDto getPost(Long postId) { Post post = postRepository.findById(postId) .orElseThrow(()-> new..