스프링 부트로 프로젝트를 하면서 API를 만들어 포스트맨 확인 후 넘겨드렸는데 CORS 오류가 발생했다는 얘기를 전해들었다. 해당 오류는 SOP 정책을 위반했을 때 발생하는 오류이며 SOP 정책은 다음과 같다.

 

SOP(Same Origin Policy) 정책

같은 호스트, 같은 포트, 같은 프로토콜에서만 요청을 주고받을 수 있는 보안 정책

스프링 부트에서 아무런 설정을 적용하지 않으면 위 SOP 정책을 그대로 따르게 된다고 한다.

 

그럼 SOP 정책을 어떻게 변경할 수 있을까?

해답은 CORS(Cross-Origin Resource Sharing)을 이용하면 된다고 한다.

CORS는 같은 호스트, 같은 포트, 같은 프로토콜이 아니더라도 요청을 주고 받을 수 있도록 해준다.

 

CORS를 적용하는 법

1. CORS 적용이 필요한 컨트롤러 위에 @CrossOrigin("*") 애노테이션을 추가한다.

2. WebMvcConfigurer 인터페이스를 상속받아서 설정한다.(스프링 시큐리티 사용 안할 시)

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("http://localhost:3000");
    }

3. 스프링 시큐리티 설정 관련 config 파일에 아래 내용 추가 (스프링 시큐리티 사용할 시)

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity.cors().configurationSource(request -> {
        var cors = new CorsConfiguration();
        //허용할 주소
        cors.setAllowedOrigins(List.of("http://localhost:3000")); 
        //허용할 http 메소드
        cors.setAllowedMethods(List.of("GET","POST", "PUT", "DELETE", "OPTIONS"));
        //허용할 header
        cors.setAllowedHeaders(List.of("*"));
        return cors;
    });

 

필자는 스프링 시큐리티를 사용하고 있어서 3번으로 해결했다.

 

참고 사이트

https://velog.io/@minchae75/Spring-boot-CORS-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0

 

 

 

Jwt 파싱할 때 발생한 오류다.

구글링해서 알아보니 parsing한 secert key 값이 원래 로컬에 저장된 secret key값과 달라서 발생하는 오류라고 한다.

 

먼저 오류 발생했던 초기 코드는 아래와 같다.

Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject();

 

이후 구글링을 통해 다수의 사람들이 해결하던 .getBytes()를 추가하는 방식으로 수정해봤으나 오류가 해결되지 않았다.

.getBytes()를 통해 바이트 형식으로 키 값을 다뤄 key 값이 토큰에 들어가거나 파싱되는 순간에 변경이 되는 걸 방지한다는 디버깅 방식이었다.

Jwts.parser().setSigningKey(secretKey.getBytes()).parseClaimsJws(token).getBody().getSubject();

 

위 방식으로도 해결이 안된 이후로 몇 시간 동안 이 코드만 디버깅을 시도했었다.

구글링해도 자료가 많지 않아 난항을 겪고 있던 와중에 한 중국인이 올린 코드를 보게 됐고 그 분 방식처럼 아예 parsing하는 함수를 따로 분리하면서 문법도 바꿔 작성하니 오류가 해결됐다...

 

참고한 글은 아래 참고 사이트에 링크 남겼고 내가 작성한 오류 해결 코드는 아래와 같다.

 /**
     * Access 토큰 파싱
     * @param jwt
     * @return
     */
    public Claims parseJwt(String jwt) {
        Claims claims = Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();

        return claims;
    }
    
    Claims claims = parseJwt(token);
    String s=claims.getSubject();

 

 

 

참고 사이트 

https://github.com/jwtk/jjwt/issues/177

스프링 부트에서 Redis 서버를 연결해서 작동하는 로직이 있는데 코드를 작성한 후 관련 api를 실행시켜보니 ERR Client sent AUTH, but no password is set라는 에러로그가 출력됐다.

Redis 서버에 비밀번호 설정을 안해줬거나 설정해줬는데 yml과 같은 Redis 서버 연결관련 설정 파일에 비밀번호를 제대로 적지 않아줘서 생기는 오류이다.

분명 초반에 깔 때 비밀번호를 설정해주고 확인까지 했었는데 비밀번호가 날라가있었다. 
+원인을 알았다. 집에서 사용하는 IP가 고정적인 IP가 아니여서 가끔씩 IP가 바뀌는데 IP가 바뀌면 redis 설정을 다시 해줘야하는 것 같다.

 

참고용 내 redis 서버 yml 설정 파일 코드는 아래와 같다.

spring:
  redis:
    host: localhost
    port: 6379
    password: '설정한비밀번호'
    lettuce:
      pool:
        max-active: 10
        max-idle: 10
        min-idle: 2

 

비밀번호를 설정해주지 않았거나 기억이 안난다면 아래를 따라오면 된다.

 

비밀번호 확인

 

redis-cli 실행

config get requirepass

 

"requirepass"

""

뜨면 비밀번호 설정이 안된 상태로 설정해줘야 한다.

 

비밀번호 설정법

 

redis-cli 실행

config set requirepass 비밀번호

이후 아래 코드를 치면

auth 설정한비밀번호 

config get requirepass

"requirepass"

"설정한비밀번호"

정상적으로 비밀번호가 변경됐음을 확인할 수 있다.

 

 

confing폴더에 securityConfig 생성

securityConfig에 아래와 같은 코드로 passwordEncoder를 Bean으로 추가

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class SecurityConfig {

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

참고사이트

https://stackoverflow.com/questions/60848619/consider-defining-a-bean-of-type-org-springframework-security-crypto-bcrypt-bcr?rq=1

스프링 부트 실행 시 cannot access MimeMessage와 같은 오류가 떴다.

구글링 후 build.gradle dependices에 다음과 같은 설정 추가

implementation 'org.springframework.boot:spring-boot-starter-mail'

 

참고 사이트 

https://youtrack.jetbrains.com/issue/IDEA-276659

스프링 부트 2.6 이상에서 Querydsl 5.0을 사용하려고 할 때 이전의  build.gradle에서의 Querydsl 설정법을 사용하면 발생하는 오류이다.

 

아래 코드를 build.gradle에 추가해주면 정상적으로 스프링 부트가 실행된다.

 

buildscript {
   ext {
      queryDslVersion = "5.0.0"
   }
}

plugins {
   //querydsl 추가
   id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"
}

dependencies {
   //querydsl 추가
   implementation "com.querydsl:querydsl-jpa:${queryDslVersion}"
   implementation "com.querydsl:querydsl-apt:${queryDslVersion}"
}

def querydslDir = "$buildDir/generated/querydsl"

querydsl {
   jpa = true
   querydslSourcesDir = querydslDir
}
sourceSets {
   main.java.srcDir querydslDir
}
compileQuerydsl{
   options.annotationProcessorPath = configurations.querydsl
}
configurations {
   compileOnly {
      extendsFrom annotationProcessor
   }
   querydsl.extendsFrom compileClasspath
}

+ Recent posts