[오늘가챠] 성능 끌어올리기: CompletableFuture를 이용한 병렬 처리
·
◈ Yermi Project/오늘가챠🃏
유저가 사진을 촬영하고 업로드할 때, 백엔드에서는 크게 2가지 무거운 작업이 일어납니다.Cloudinary 서버로 원본 이미지 전송 (수 초 소요)GPS 위경도를 한글 지명으로 변환하는 Reverse Geocoding API 호출 (수 초 소요)이 두 가지 작업을 순차적으로 실행하면 유저는 화면이 멈춘 채로 10초 가까이 기다려야 합니다. 이를 해결하기 위해 자바의 CompletableFuture를 도입한 경험입니다.1. 기존 방식의 문제점 (순차 실행) I/O 바운드 작업들이 직렬로 연결되어 유저 경험(UX)을 심각하게 훼손하고 있었습니다. // 기존의 느린 코드 (직렬 실행)String imageUrl = cloudinaryClient.upload(request.file().getBytes()); /..
[오픈소스] 특수문자를 10개만 아는 강도 검사기를 고치다🔐 [Password-Strength-Tester-and-Cracker]
·
◈ Yermi Project/오픈소스 파헤치기🪐
오랜만에 good first issue를 하나 잡았다. Password Strength Tester and Cracker라는 자바 콘솔 프로젝트인데, 비밀번호 강도를 판정해주는 기능에 버그가 있다는 이슈였다. 문제의 코드는 이거였다.String specialChars = "!@#$%^&*()"; 특수문자를 딱 10개만 인정한다. - _ [ ] { } 같은 건 전부 특수문자 취급을 못 받는다는 뜻이다. 그래서 고치기 전 판정이 이렇게 나온다.비밀번호판정correct-horse-battery1A (23자)MediumP@ssw0rd[]{} (12자)Strong 23자짜리 패스프레이즈는 Medium인데, 사전에 있는 password를 leet로 바꾼 12자짜리는 Strong이다. 그것도 뒤에 붙인 []{}는 인..
[웹 보안] 보안 로직 추가 후 로그인이 즉시 풀리는 현상 (Session Fixation 방어와 invalidate()의 함정)
·
◈ Study/웹 보안(Web Security)🔐
- 보안 로직 추가 후 로그인이 즉시 풀리는 현상최근 로그인 시 보안 강화를 위해 세션 고정(Session Fixation) 공격 방어 로직을 추가하던 중, 로그인이 성공하자마자 풀려버리는(인증이 유지되지 않는) 이슈를 겪었습니다.겉보기엔 올바른 보안 로직 같아 보이지만, HttpSession의 생명주기와 인증 컨텍스트 처리 방식에 대한 오해에서 비롯된 흔한 실수였습니다. 해당 문제의 원인과 해결 방법을 정리하여 공유합니다. 1. 문제 상황 로그인 프로세스 도중, 세션 하이재킹을 방지하기 위해 기존 세션을 파기하고 새로운 세션을 발급하는 아래 코드를 추가했습니다. 그런데 이 코드가 실행된 직후 클라이언트가 비로그인 상태가 되는 현상이 발생했습니다. // 문제의 코드: 세션 고정 공격 방어 로직HttpS..
[백준/BOJ] 2447번: 별 찍기 - 10 - JAVA [자바]
·
◈ Coding Test/백준(BOJ)👨🏻‍💻
- 백준 2447번: 별 찍기 - 10문제재귀적인 패턴으로 별을 찍어 보자. N이 3의 거듭제곱(3, 9, 27, ...)이라고 할 때, 크기 N의 패턴은 N×N 정사각형 모양이다.크기 3의 패턴은 가운데에 공백이 있고, 가운데를 제외한 모든 칸에 별이 하나씩 있는 패턴이다.*** * * ***N이 3보다 클 경우, 크기 N의 패턴은 공백으로 채워진 가운데의 (N/3)×(N/3) 정사각형을 크기 N/3의 패턴으로 둘러싼 형태이다. 예를 들어 크기 27의 패턴은 예제 출력 1과 같다.입력첫째 줄에 N이 주어진다. N은 3의 거듭제곱이다. 즉 어떤 정수 k에 대해 N=3k이며, 이때 1 ≤ k 출력첫째 줄부터 N번째 줄까지 별을 출력한다.import java.io.BufferedReader;import ja..
[JAVA] Reflection 활용하여 객체 필드 복사하기 [원본 객체에서 필드 값을 읽어 대상 객체에 값 설정]
·
◎ Java/Java☕
- Reflection 활용하여 객체 필드 복사하기public class ReflectionExample { public static void copyFields(Object source, Object target) throws Exception { Class sourceClass = source.getClass(); Class targetClass = target.getClass(); Field[] sourceFields = sourceClass.getDeclaredFields(); for (Field sourceField : sourceFields) { try { Field targetField = ..