TIL(Today I Learned) 53

TIL - 로그인 후 Jwt 토큰으로 회원 정보를 가져올 때 NULL

Todo 프로젝트에서 구현했던 로그인 부분을 그대로 가져와 NewsFeed 프로젝트에 반영했다.로그인 후 정상적으로 Jwt 토큰을 발급하는 것까지 확인이 되었는데 Jwt 토큰으로 다른 인증이 필요한 작업들을 하기 위해 사용자 정보를 가져올 때 사용자 정보가 null로 출력되었다. https://jwt.io/를 통해 access token의 정보도 발급한 정보 그대로 확인할 수 있었다. 디버그 모드로 확인하면 UsernamePasswordAuthenticationToken의 반환 값까지는 정상적으로 확인되는데 SecurityContextHolder.getContext().authentication에 값을 넣으면 null이 됐다. 디버그 모드로 내부까지 차근차근 살펴봤지만 뭐가 문제인지 알 수 없었다.이전 ..

TIL - Swagger ui에서 Json 데이터와 첨부 파일 업로드 시도

Json 데이터와 첨부 파일을 같이 서버로 전송받는 테스트를 하기 위해서 Controller를 다음과 같이 작성하였다.@RequestPart : "multipart/form-data" 요청의 일부를 메서드 인수와 연결하는 데 사용할 수 있는 주석@PostMapping(consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])fun createTodo( @Valid @RequestPart(value = "request") createTodoRequest: CreateTodoRequest, @RequestPart(value = "file", required = false) file: MultipartFile) { println("********** createT..

ESLint - missing in props validation

props를 전달할 때 다음과 같이 빨간 줄로  ESLint 에러가 뜨는 경우가 있다. 하지만 정상적으로 동작하고 데이터도 잘 출력되는 상황이다.해결방법으로 많이 검색되는 것은 .eslintrc.cjs에서 rules에 "react/prop-types": "off"를 추가하는 것이다."rules": { "react/prop-types": "off"} off 설정을 하면 빨간 줄은 사라지지만 그러면 ESLint를 사용하는 의미가 없어지는 것 같다.경고 메시지 우측 react/prop-types를 누르면 다음 링크로 이동할 수 있는데 이 규칙을 사용하는 이유와 규칙에 대한 예를 확인할 수 있다.https://github.com/jsx-eslint/eslint-plugin-react/blob/master/do..

TIL - Redis에 대해 알아보기(+ 명령어)

Redis(Remote Dictionary Server)키-값 구조의 비정형 데이터를 저장하고 관리하기 위한 오픈 소스 기반의 비관계형(NoSQL) DB 관리 시스템쿼리가 아닌 커맨드 기반Disk가 아닌 In-memory 방식Single Thread로 동작Redis를 사용하는 이유데이터를 아주 빠르게 저장하고 가져올 수 있기 때문Redis가 빠른 이유모든 데이터가 메모리에 저장됨대부분의 DB가 정보를 컴퓨터의 메모리와 하드 드라이브에 저장메모리는 데이터를 빠르게 액세스 할 수 있지만 하드 디스크의 데이터를 액세스 하는 건 비교적 느림Redis는 하드 디스크에 정보를 저장하지 않고 모든 데이터를 메모리에 저장Redis가 모든 데이터를 아주 단순한 구조로 관리하기 때문중요한 점은 모든 데이터가 연결 리스트,..

TIL - Swagger에서 Bearer Token 설정

Todo 프로젝트에 JWT 인증을 구현하기 전까지는 다음과 같이 간단한 코드만으로 http://localhost:8080/swagger-ui/index.html에서 API 테스트를 할 수 있었다.@Configurationclass SwaggerConfig { @Bean fun openApi() = OpenAPI().components(Components()) .info(Info().title("Todo API").description("Todo API schema").version("1.0.0"))} JWT 인증 구현 후에는 위 코드만으로는 Swagger에서 테스트를 할 때 인증 헤더를 입력할 수 없어서 PostMan을 사용하다가 Swagger에도 인증 헤더를 입력하는 방법이 있지..

TIL - JWT Token 생성 및 검증(Access Token, Refresh Token)

JWThttps://jwt.io/RFC 7519 웹 표준으로 지정되어 있는 JSON 객체를 사용해서 토큰 자체에 정보들을 저장하고 있는 Web Token당사자 간에 정보를 JSON 형태로 안전하게 전송하기 위한 토큰URL로 이용할 수 있는 문자열로만 구성되어 있으며, 디지털 서명이 적용되어 있어 신뢰할 수 있으며 HTTP 구성요소 어디든 위치할 수 있음주로 서버와의 통신에서 권한 인가를 위해 사용됨JWT의 장점중앙의 인증서버, 데이터 스토어에 대한 의존성 없음, 시스템 수평 확장 유리Base64 URL Safe Encoding > URL, Cookie, Header 모두 사용 가능JWT의 단점Payload의 정보가 많아지면 네트워크 사용량 증가(트래픽 증가), 데이터 설계 고려 필요토큰이 클라이언트에 저..

TIL - Java 8 date/time type `java.time.LocalDateTime` not supported

Spring Security를 사용해 로그인 처리를 할 때, 성공 시 응답 본문에 Json 형식의 데이터를 담아 보내려고 했다.그런데 LocalDateTime 타입의 createdAt에 대해 다음과 같은 예외가 발생했다.com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: org.zerock.todolist.domai..

TIL - Spring Security에서 JSON으로 로그인 처리

Spring Security에서 formLogin()을 사용하면 Content-Type이 x-www-form-urlencoded인 방식으로만 데이터를 받을 수 있다.이런 경우 Rest Api 통신에 사용하는 Json으로 보내는 데이터는 처리되지 않는다.Json으로 데이터를 받아서 로그인 처리를 하기 위해서는 AbstractAuthenticationProcessingFilter나 UsernamePasswordAuthenticationFilter를 상속 받아 처리할 수 있다. 다음은 AbstractAuthenticationProcessingFilter를 상속 받아 로그인을 구현한 코드이다.class JsonUsernamePasswordAuthenticationFilter( private val obje..

TIL - Offset-based Pagination & Cursor-based Pagination

오프셋 기반 페이지네이션(Offset-based Pagination)DB의 offset, limit 쿼리를 사용이전의 데이터를 모두 조회 후 offset을 조건으로 잘라내는 방식페이지 단위로 구분해 요청 및 응답총 레코드 개수 및 전체 페이지 크기를 알 수 있음원하는 페이지로 바로 이동 가능데이터의 변경이 잦은 경우 중복 또는 누락 데이터가 발생(데이터 불일치)레코드의 개수가 많고 offset 값이 올라갈수록 시간 복잡도 ↑ SELECT * FROM todo ORDER BY create_at DESC LIMIT 10 OFFSET 10 -- 10개 skip 후 10개의 데이터 요청SELECT * FROM todo ORDER BY create_at DESC LIMIT 20 OFFSET 10 -- 20개 sk..

TIL - SQL WITH 재귀 쿼리

프로그래머스에서 SQL 문제 중 입양 시각 구하기(2) 문제를 푸는데 결과에 없는 시간대를 어떻게 만들어야 할지 몰라서 질문하기를 참고 했는데 MySQL의 경우 with을 사용한 재귀 풀이가 많았다.문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/59413 SQL 재귀 쿼리에 대해 찾다가 MySQL Recursive CTE에 대해 이미지와 함께 잘 설명되어 있는 페이지를 발견했다.https://www.mysqltutorial.org/mysql-basics/mysql-recursive-cte/ CTE의 요소 재귀적 CTE의 실행 단계앵커와 재귀 멤버를 분리앵커 멤버는 초기 행( SELECT 1)을 형성하므로 첫 번째 반복에서는 n = 1..