방탈출 테마 추천 사이트라는 주제로 만든 방방곡곡 웹사이트 프로젝트!
이번 프로젝트에서는 SpringBoot를 많이 다뤄보진 못하고 단순 기능 구현에 힘쓴 것 같아 너무너무 아쉽다...
aws ec2에 docker container log를 좀 더 편리하게 보는 방법이 없을까?
ELK 스택 사용:ELK (Elasticsearch, Logstash, Kibana) 스택을 사용하면 Docker 컨테이너에서 생성된 로그를 수집, 저장, 검색, 분석할 수 있습니다. Elasticsearch는 로그를 저장하고 색인화하고 검색하는 데 사용되며, Logstash는 다양한 소스에서 로그를 수집하고 Elasticsearch로 전송합니다. 마지막으로, Kibana는 Elasticsearch에서 저장된 로그를 시각화하고 검색할 수 있습니다.
ELK 스택을 사용하려면 Elasticsearch, Logstash 및 Kibana를 설치하고 구성해야 합니다. 아래는 ELK 스택을 설정하는 간단한 단계입니다.
- Elasticsearch 설치 및 구성: Elasticsearch는 로그를 저장하고 검색하는 데 사용됩니다. Elasticsearch 다운로드 페이지에서 Elasticsearch를 다운로드하고 설치할 수 있습니다. 설치 후, elasticsearch.yml 파일을 열어 Elasticsearch를 구성해야 합니다. 이 파일은 Elasticsearch 설정 파일이며, 클러스터 이름, 노드 이름, 포트 등을 구성할 수 있습니다.
- Logstash 설치 및 구성: Logstash는 다양한 소스에서 로그를 수집하고 Elasticsearch로 전송합니다. Logstash 다운로드 페이지에서 Logstash를 다운로드하고 설치할 수 있습니다. 설치 후, logstash.conf 파일을 작성하여 로그를 수집하고 전송할 수 있는 입력 및 출력 플러그인을 구성해야 합니다. 이 파일에서는 입력, 필터 및 출력 섹션을 구성할 수 있습니다.
- Kibana 설치 및 구성: Kibana는 Elasticsearch에서 저장된 로그를 검색하고 시각화하는 데 사용됩니다. Kibana 다운로드 페이지에서 Kibana를 다운로드하고 설치할 수 있습니다. 설치 후, kibana.yml 파일을 열어 Kibana를 구성해야 합니다. 이 파일에서는 Elasticsearch 호스트 및 포트와 같은 설정을 구성할 수 있습니다.
- ELK 스택 실행: Elasticsearch, Logstash 및 Kibana를 시작하여 ELK 스택을 실행할 수 있습니다. Elasticsearch를 먼저 시작하고, 그 다음 Logstash를 시작하여 로그를 수집하고 Elasticsearch로 전송하고, 마지막으로 Kibana를 시작하여 Elasticsearch에서 로그를 시각화하고 검색할 수 있습니다.
위의 단계는 간단한 ELK 스택 설정 방법입니다. 더 자세한 구성 방법과 구성 파일 예제는 Elastic 사이트에서 확인할 수 있습니다.
Regenerate response
JWT 관리
쿠키, 세션 이런거말고 Authorization header를 써야 가장 인증이 좋데
그러면 jwt를 발급하고 프론트로 보내
프론트는 이 토큰을 localstorage, sessionstorage, cookie 이런 방식으로 관리할 수 잇는데
각각 장단점이 있지만 그나마 보안이 좋은 방식은 cookie임
왜? httponly 옵션 때문에 클라이언트 측에서 jwt토큰을 볼 수가없거든
그러면 프론트는 api요청할때마다 jwt를 보내야하는데 프론트에서도 못본다매 그럼 어캄?
백엔드에서 api엔드포인트를 생성해서 프론트가 쿠키 자체를 보내주면 우리는 그 쿠키를 받아서 쿠키안에있는 jwt를 return하는거지
그럼 이 jwt로 프론트가 쓸수있는거야
근데 왜 계속 적용이 안될까?
=⇒ localhost, 127.0.0.1 때문임
RequestBody에 넣는 데이터가 String 1개여도 RequestBody에 넣는게 맞을까?
@RequestBody 어노테이션을 사용하면 HTTP 요청 본문에서 데이터를 읽어와 메서드 인자로 전달할 수 있습니다. 이때, 요청 본문에 전달하는 데이터는 JSON, XML 또는 다른 형식으로 직렬화된 객체일 수 있습니다.
따라서, @RequestBody 어노테이션을 사용하여 HTTP 요청 본문을 읽어들일 때, 단일 String 데이터를 전달할 경우에도 객체로 래핑하여 전달하는 것이 좋습니다. 이는 요청 본문에서 전달하는 데이터에 대한 유연성을 제공하며, 앞으로 요구사항이 변경되어 여러 데이터 유형을 요청 본문에서 처리해야 하는 경우에 대비할 수 있습니다.
예를 들어, Spring Boot에서 @RequestBody 어노테이션을 사용하여 단일 String 데이터를 전달하는 예시를 살펴보겠습니다.
@PostMapping("/example")
public String exampleMethod(@RequestBody String requestBody) {
// Do something with the request body
return requestBody;
}
위의 예시에서는 @RequestBody 어노테이션을 사용하여 HTTP 요청 본문에서 전달된 단일 String 데이터를 처리합니다. 그러나 이 방법은 요청 본문에서 전달하는 데이터 유형이 변경될 가능성이 있으므로, 좀 더 유연한 방식으로 데이터를 처리하는 것이 좋습니다. 따라서, 단일 String 데이터를 전달하는 대신 객체를 래핑하여 전달하는 것이 권장됩니다.
SpringBoot로 로그인 구현하는데 refresh Token을 DB에 저장하는게 맞을까
일반적으로는 refresh token은 DB에 저장하는 것이 좋습니다.
refresh token은 일반적으로 사용자가 로그인한 이후에 발급되며, access token이 만료되었을 때 새로운 access token을 발급하기 위해 사용됩니다. 이 때 refresh token은 보안적으로 민감한 정보이기 때문에, DB에 안전하게 저장하는 것이 좋습니다. 또한, refresh token이 유효하지 않은 경우 사용자가 다시 로그인해야 하므로, DB에 저장하여 사용자의 로그인 상태를 유지하는 것이 편리합니다.
Spring Boot에서는 Spring Security와 JWT 토큰을 사용하여 로그인을 구현할 수 있습니다. 이 경우 JWT 토큰은 클라이언트 측에서 저장되며, refresh token은 서버 측에서 DB에 저장됩니다. 이를 통해 보안적인 측면에서 안전하게 로그인을 구현할 수 있습니다.
springboot의 addCorsMappings에서 CORS 설정을 해줬는데 계속 CORS 에러가 떠서 controller에서 api위에 @Crossorigin(*)을 넣어줘야만 문제가 해결했는데 왜그럴까
Spring Boot에서 CORS 설정을 제대로 하였음에도 불구하고, 계속해서 CORS 에러가 발생하는 경우가 있습니다. 이러한 문제는 Spring Boot에서 자체적으로 처리하는 CORS 필터가 원하는 결과를 내지 못하거나, 프론트엔드와 백엔드 간 통신이 충분히 허용되지 않은 경우 등으로 발생할 수 있습니다.
addCorsMappings() 메서드를 이용하여 CORS 설정을 추가하면, 기본적으로 Spring Boot의 CORS 필터가 동작하여 요청에 대한 응답 헤더에 Access-Control-Allow-Origin 등의 필수적인 정보를 추가합니다. 그러나, 이 필터는 모든 요청에 대해 CORS 허용을 적용하지 않을 수도 있습니다.
CORS 에러는 서버와 클라이언트의 도메인이 다를 때 발생합니다. 이 경우에는, 서버 측에서 클라이언트 측의 도메인을 allowedOrigins 에 추가해주어야 합니다. 또한, 도메인이 다른 경우에는, 클라이언트에서도 **withCredentials**옵션을 **true**로 설정해주어야 합니다.
=> 프론트에서 실행할 떄 localhost:3000으로 해줘야 에러가 안생김. 보통 127.0.0.1:3000으로 하더라
SPA refresh 404 처리
Nginx에서 처리를 해줘야함. hashrouter로 처리를 해줘야되나 싶었지만 nginx에서 try_file $url index.html 이걸로 하는게 확실한 방법이더라!
sonarqube
기술적 개선사항
DB 테마(1700개 정도)를 불러와서 DTO로 감싸는데 시간이 엄청 오래걸렸음.
한 5초이상 차이가 나서 메인페이지 로딩시간이 길어지는 이슈가 발생했음
무한참조 때문에 무조껀 DTO에 감싼다는 생각을 하고 있었는데 이렇게 되면 낭비가 심했음
꼭 필요한 애들만 DTO로 감싸서 활용하는것임
List<PreviewThemeResponse> list = null;
switch (type) {
case 1: // 난이도 최고
list = themeRepository.findByUserCntGreaterThanOrderByUserDifficultyDesc(4)
.stream()
.map(x -> new PreviewThemeResponse(x))
.collect(Collectors.toList());
// 테마를 위에서부터 for문으로
for (Theme theme : list) {
// 확률에 의해 담긴다
if (rnd.nextInt(10) < 8) { // 80%
cnt++;
themes.add(new PreviewThemeResponse(theme));
}
// 모두 담겼으면 끝
if (cnt == THEME_RETURN_COUNT){
result = new ThemeBundleResponse(label, themes);
return result;
}
}
이렇게 하면 필요없는 애들까지 Theme → PreviewThemeResponse 하는작업에서 엄청 오래걸렸던거임
관심, 리뷰 관련된 활동을 하면 추천 시스템이 돌아가게 되는데 웹에서 결과를 받는게 너무 오래걸림
추천시스템에 요청을 보내는 것과 결과를 리턴하는걸 비동기로 처리했음.
추천된 결과를 지속적으로 DB에 저장하고 웹에서 추천된 결과를 읽어올땐 DB의 값을 읽어오는것이고 추천을 돌려서 DB에 저장하게 하는건 비동기로 처리하기 때문에 사용자가 대기시간을 경험하지 않고 원활하게 웹페이지 이용이 가능하다
젠킨스를 이용하여 스프링을 빌드배포하는데 정상적으로 빌드가 안되도 jar가 만들어지니까 이를 docker run에서 판단하는게 너무 불편했음
로그인 관련해서 많은걸 배움
access Token과 refresh Token 2개가 있는데 access Token은 Cookie에 담아서 httpOnly 이런 설정을 줘서 보내주는게 맞음, refresh Token는 DB에 저장하고 토큰을 갱신할 때마다 이를 이용함.
근데 어떻게 이용할까?
로그인을 하면 백 -> 프론트에게 jwt를 줘야하는데 access, refresh 2개를 쿠키에 담아서 전송한다.
그럼 프론트는 이를 기억했다가 인증이 필요한 api요청시 쿠키를 함께 보내게 되는데 백에선 쿠키를 파싱하여 토큰을 얻어내서 이용하는데 만료된 토큰이면 같이 보낸 refresh Token이 이 유저의 DB에 저장된 refresh Token과 일치하다면 갱신을 시켜주는 그런 흐름으로 가야한다
'Backend > Spring' 카테고리의 다른 글
[JPA] Entity 만들기 (0) | 2023.04.24 |
---|---|
[Spring Security] BBKK에서 썼던 로그인 관련 정리 ★★★ (0) | 2023.04.13 |
프로젝트 회고(경매중) + 질문 리스트 (1) | 2023.02.20 |
[Spring Security] SecurityConfig 작성 (version. Jiwon) (0) | 2023.01.25 |
[SpringBoot] CORS 설정 (0) | 2023.01.24 |