전체 글 131

Access Token과 Refresh Token을 어떻게 전달하고 클라이언트는 어디에 저장할까?

서버와 클라이언트 각각의 입장에서 적어보겠습니다! [서버] 각 토큰을 어떻게 전달해야 할까?Response Body{ "accessToken": "access_token_here", "refreshToken": "refresh_token_here"}장점 :- 간단하고 구현이 쉬움- 클라이언트 측에서 유연하게 처리 가능 단점 :- 토큰이 노출될 가능성이 높음 (ex. 웹 콘솔 로그에 토큰이 남을 수 있음)- CSRF 공격에 취약 HeaderHTTP/1.1 200 OKContent-Type: application/jsonAuthorization: Bearer access_token_hereRefresh-Token: refresh_token_here장점 : - response body를 깨끗하게 유지 가능..

authenticate에서 발생하는 '자격 증명에 실패하였습니다' 문제 해결

프로젝트 중 로그인 구현을 맡았다. 로그인은 이메일과 비밀번호를 입력하는 방식으로 구현했다.자격 증명에 실패하였습니다. 라는 에러가 발생했다.  디버깅을 해보니 이슈가 발생한 부분은 다음과 같았다.Authentication authentication = authenticationManagerBuilder.getObject().authenticate(usernamePasswordAuthenticationToken); UsernamePasswordAuthenticationToken으로 생성한 토큰을 넘겨 권한 인증을 받는 부분이다. 디버깅 모드에서 메서드 내부 동작 흐름을 따라가다보니 retrieveUser()에서 UserDetails를 사용하는 모습을 확인할 수 있었다. 커스텀으로 만든 userDetail..

JPA Auditing으로 생성일/수정일 자동 갱신 (+date format이 동작하지 않는 문제 해결)

JPA Auditing이란?보통 엔티티는 해당 데이터의 생성 시간과 수정 시간을 포함한다. 그래서 매번 DB를 insert, update 할 때 날짜 데이터를 등록/수정하는 코드가 들어간다. 하지만, 이런 단순한 코드가 모든 서비스 메서드에포함된다고 생각하면 귀찮고 코드가 지저분해진다.그래서 쓰는 것이 JPA Auditing이다. `BaseTimeEntity.java`BaseTimeEntity 클래스는 이를 상속하는 엔티티의 상위 클래스가 되어 created, updated를 자동으로 관리하는 역할을 한다.@Getter@MappedSuperclass@EntityListeners(AuditingEntityListener.class)public abstract class BaseTimeEntity { @Co..

[싸피에서 뭐했니?] #final관통PJT

안녕하세요~!! 11기 최민주 기자입니다 👋드디어 1학기의 피날레인 관통 프로젝트가 끝났습니다! 오늘은 관통 프로젝트를 회고해보려 합니다 😇 관통 프로젝트란?관통 프로젝트는 말 그대로 1학기를 관통하는, 1학기에 배운 것을 총동원하여 진행하는 프로젝트를 의미합니다. 어떤 프로젝트를 진행했나요?이번 관통 프로젝트에서는 비기능에 중점을 둔 프로젝트를 진행하였습니다. 특히, 동시성 처리를 깊게 파고 들어 시스템의 안정성을 높이는데 주력했습니다. 동시성 처리는 애플리케이션 내에서 동시에 실행되는 여러 스레드 또는 프로세스를 관리하는 프로세스를 말합니다.이를 통해 애플리케이션이 여러 요청 또는 작업을 동시에 처리할 수 있으며, 사용자 경험을 향상시키는 것을 목표로 했습니다. 주요 구현 내용- 멀티스레딩  - ..

redis 분산락으로 동시성 제어하기

분산락이란?분산 락은 분산 환경에서 여러 대의 서버와 여러 DB간의 동시성을 관리하는데 사용된다. 일반적으로 분산 환경이 아니라면 비관적 락 등을 이용하여 동시성을 제어할 수 있지만, 여러 대의 DB가 존재하는 분산 DB 환경에서는 동시성 문제를 해결할 수 없다.분산 DB에서 비관적 락으로 동시성 문제를 해결할 수 없는 이유네트워크 파티션 문제두 노드 사이의 네트워크 연결이 끊긴다.한 노드에서 데이터의 락을 설정했지만, 연결이 끊어진 노드에서는 이 락의 정보를 알 수 없다.결과적으로 두 노드에서 동시에 동일한 데이터를 변경할 수 있다.데이터 복제본과 일관성의 문제한 노드에서 데이터를 업데이트하고 락을 해제한 후, 변경 사항을 다른 노드에 복제한다.복제하는 동안, 다른 사용자가 이전 버전의 데이터를 다른 ..

#4. 간식과 함께하는 SSAFY TOGETHER 🍪🍵

안녕하세요~!! 11기 최민주 기자입니다 👋지난 5월 초, SSAFY 과정 중에 에너지를 채우고 학습에 집중하도록 싸피투게더 스낵이 제공되었습니다! SSAFY TOGETHER란?SSAFY에서 함께 성장하고 나아가기 위한 캠페인 해당 캠페인을 통해 SSAFY 교육생들은 단순한 학습을 넘어, 지역 사회와 함께 성장하고 상생할 수 있는 기회를 얻고 있습니다! 취지 및 배경SSAFY TOGETHER는,지역 경제 활성화에 일조하고, 청년창업 혹은 중소기업이 생산하는 먹거리 제품을 교육생에게 배부함으로써 교육생들이 청년 및 지역 상생과 협력의 의미를 깨닫고 이에 동참하도록 하는 것입니다. SSAFY 캠퍼스가 위치한 지역에 사업장을 둔 청년 혹은 중소기업이면서, 삼성 주축 '스마트공장 지원사업'에 참여한 기업의 제..

Database Locking(Optimistic Lock, Pessimistic Lock)으로 동시성 제어하기

잠금 (Locking)잠금은 데이터가 읽힌 후 사용될 때까지 데이터가 변경되는 것을 방지하기 위한 조치이다.잠금 전략으로는 여러 트랜잭션 간 충돌이 드물다고 가정하는 낙관적 잠금, 여러 트랜잭션 간 충돌이 자주 발생할 것이라고 가정하는 비관적 잠금이 있다.낙관적 잠금 (Optimistic Lock)낙관적 잠금은 아래와 같이 @Version 어노테이션을 통해 처리할 수 있다.JPA에서는 별도의 옵션을 사용하지 않아도 Entity에 @Version이 적용된 필드만 있으면 낙관적 잠금이 적용된다. (=암시적 잠금)@Entitypublic class Coupon { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long coup..

카테고리 없음 2024.05.19

synchronized 키워드를 사용하여 임계 영역 지정하기

synchronized 키워드 사용java에서 한 자원에 synchronized 키워드를 붙이면, 멀티 스레드 환경에서 단일 스레드만이 해당 자원에 접근 가능하도록 보장한다.그렇다면 publishCoupon() 메서드에 synchronized 키워드를 붙임으로써, 동시에 들어오는 요청들을 순차적으로 처리할 수 있지 않을까?CouponService.java@Transactional public synchronized void publishCoupon(long couponId) { Coupon coupon = couponRepository.findById(couponId) .orElseThrow(() -> new RuntimeException("존재하지 않는 쿠폰..

동시성 문제 발생 확인

상황쿠폰이 10개 있는 상황이고, 30명의 사용자가 쿠폰 발급을 원하는 상황이다.여기서 중요한건 선착순으로 요청 순서에 따라 티켓을 발급하되, 준비된 수량만큼만 발생하는 것이다.원하는 상황만 살펴볼 수 있도록 상황을 최대한 간소화하여, 데이터베이스 테이블은 Coupon, Reservation 만 존재한다.Coupon 엔티티를 살펴보자.Coupon 엔티티는 생성자에서 쿠폰의 수량을 받는다. 예약 수량은 0으로 초기화한다.회원이 쿠폰을 예약할 때마다 예약 수량을 1씩 증가시키고, 예약 수량이 쿠폰 수량과 같거나 커지면 예약 불가 예외를 발생시킨다.public class Coupon { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) priv..