๋ฐ˜์‘ํ˜•
๋กœ๊น… (logging)

์‹œ์Šคํ…œ์ด ์ž‘๋™ํ•  ๋•Œ ๋‹น์‹œ์˜ ์ƒํƒœ์™€ ์ž‘๋™ ์ •๋ณด๋ฅผ ๊ธฐ๋ก 

 

๋กœ๊น…๋‹จ๊ณ„
๋ช…์นญ ์„ค๋ช…
TRACE 1๋‹จ๊ณ„ - DEBUG ๋ ˆ๋ฒจ๋ณด๋‹ค ์ƒ์„ธํ•œ ์ •๋ณด
DEBUG 2๋‹จ๊ณ„ - ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ๋””๋ฒ„๊น…ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์„ธ๋ถ€ ์ •๋ณด
INFO 3๋‹จ๊ณ„ - ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ์ˆœ์กฐ๋กœ์šด ์ง„ํ–‰ ์ •๋ณด
WARN 4๋‹จ๊ณ„ - ์ž ์žฌ์ ์œผ๋กœ ์œ ํ•ดํ•œ ์ƒํ™ฉ ์ •๋ณด
ERROR 5๋‹จ๊ณ„ - ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ •๋„์˜ ์˜ค๋ฅ˜ ์ •๋ณด
FATAL 6๋‹จ๊ณ„ - ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ์ค‘๋‹จ๋  ๋งŒํ•œ ์‹ฌ๊ฐํ•œ ์˜ค๋ฅ˜ ์ •๋ณด
OFF 7๋‹จ๊ณ„ - ๋กœ๊น… ๊ธฐ๋Šฅ ํ•ด์ œ 

 

JPA ๋ฐ ๋กœ๊น… ๊ด€๋ จ properties ์„ค์ • 
-- ํ”„๋กœ์ ํŠธ ๋‚ด resources > application.properties (or yaml)

server.servlet.encoding.force = true
spring.h2.console.enable=true
spring.jpa.defer-datasource-initialization=true

# JPA ๋กœ๊น… ์„ค์ •
logging.level.hibernate.SQL=DEBUG

# ์ฟผ๋ฆฌ ์ค„๋ฐ”๊ฟˆ
spring.jpa.properties.hibernate.format_sql=true

# ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ฐ’ ๋ณด์—ฌ์ฃผ๊ธฐ
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

# ์œ ๋‹ˆํฌ URL ์ƒ์„ฑํ•˜์ง€ ์•Š๊ธฐ
spring.datasource.generate-unique-name=false

# ๊ณ ์ • URL ์„ค์ •
spring.datasource.url=jdbc:h2:mem:testdb

 

๋ฐ˜์‘ํ˜•
๋ฐ˜์‘ํ˜•

โœŽ Vault 

API ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฏผ๊ฐ์ •๋ณด๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์‹œ์Šคํ…œ.

โœฑ ๋ฏผ๊ฐ์ •๋ณด
๋น„๋ฐ€๋ฒˆํ˜ธ, ํ† ํฐ, ์ธ์ฆ์„œ ๋“ฑ์˜ ์•”ํ˜ธํ™” ํ•ด์•ผํ•˜๋Š” ์–ด๋– ํ•œ ๊ฒƒ๋“ค

https://www.vaultproject.io/ ์—์„œ ๊ฐœ๋ฐœํ•จ.

 

โœŽ Vault ์‚ฌ์šฉ ์ด์œ 

ํ”„๋กœ์ ํŠธ ๋‚ด์— ๋ณด์•ˆ์ ์ธ ์š”์†Œ๋ฅผ ๊ณ ๋ คํ•ด์•ผ ํ•˜๋Š” ๊ฐ’(๊ณ„์ • ๋ฐ ํŒจ์Šค์›Œ๋“œ = ๋ฏผ๊ฐ์ •๋ณด ๋“ฑ)๋“ค์„ HTTP API ํ†ต์‹ ์„ ์ด์šฉํ•˜์—ฌ ์™ธ๋ถ€(=git ์ €์žฅ์†Œ ๋“ฑ)์— ๋…ธ์ถœ์‹œํ‚ค์ง€ ์•Š์€ ์ƒํƒœ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณด์•ˆ์— ํšจ์œจ์ ์ž„.

 

 

โœŽ ๊ฐ„๋‹จํ•˜๊ฒŒ ์Šคํ”„๋ง๋ถ€ํŠธ ํ”„๋กœ์ ํŠธ ์—์„œ ์‚ฌ์šฉํ•ด๋ณธ Vault

1. Vault ์„ค์น˜ ๋ฐ ์‹คํ–‰ ํ™•์ธ

$ brew install vault # vault ์„ค์น˜
$ vault server --dev --dev-root-token-id="00000000-0000-0000-0000-000000000000" # vault ์„œ๋ฒ„ ์‹คํ–‰

โ˜ž https://www.vaultproject.io/docs/commands/server ์— ์ž์„ธํ•œ ์„ค๋ช…์ด ์žˆ๋‹ค.

๋Œ€์ถฉ ์ด๋ ‡๊ฒŒ ๋œธ
http://localhost:8200 ์œผ๋กœ ์ ‘์†ํ–ˆ์„ ์‹œ ๋‚˜์˜ค๋Š” ํ™”๋ฉด


โ‰๏ธ ๋งŒ์•ฝ Get "https://127.0.0.1:8200/v1/sys/internal/ui/mounts/secret/application/db": http: server gave HTTP response to HTTPS client ์ด๋Ÿฌํ•œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์„ ๊ฒฝ์šฐ
↓↓ ์•„๋ž˜๋‚ด์šฉ ์‹คํ–‰ (ํ„ฐ๋ฏธ๋„)

$ export VAULT_ADDR='http://localhost:8200'

 

2. key/vaule ์ƒ์„ฑ ๋ฐ ํ™•์ธ

$ vault kv put secret/application username=mungmang password=12345 # key, vaule ์ƒ์„ฑ

Key                Value
---                -----
created_time       2022-01-08T15:46:25.89734Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1
$ vault kv get secret/application # path ์œผ๋กœ key, vaule ์กฐํšŒ 

======= Metadata =======
Key                Value
---                -----
created_time       2022-01-08T15:46:25.89734Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

====== Data ======
Key         Value
---         -----
password    12345
username    mungmang

โ˜ž https://learn.hashicorp.com/collections/vault/getting-started ์— vault ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์„ค๋ช…ํ•ด์ค€๋‹ค.

 

3. SpringBoot project ์— vault ์—ฐ๋™์—ฌ๋ถ€ ์ ์šฉ

// build.gradle ํŒŒ์ผ์— ์•„๋ž˜์˜ ์ •๋ณด ์ถ”๊ฐ€

ext {
    ...
    set('springCloudVersion', "2021.0.1-SNAPSHOT")
}

dependencies {
	...
	implementation 'org.springframework.cloud:spring-cloud-starter-vault-config'
}
    

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}
// application.yml์— ์•„๋ž˜์˜ ๋‚ด์šฉ ์ถ”๊ฐ€
spring:
  config:
    import: vault:// 
  cloud:
    vault:
      uri: http://localhost:8200
      token: 00000000-0000-0000-0000-000000000000
      kv:
        backend: secret
        default-context: application #secret ์ดํ›„์˜ ๊ฒฝ๋กœ

โœฑ ์ฐธ๊ณ ๋กœ Spring Cloude Vault 3.0 ๋ฐ Spring Boot 2.4 ์ด์ƒ์—์„  bootstrap.yml, bootstrap.properties ๊ฐ€ ๋”์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ ํ•จ. ๊ทธ๋ฆฌ๊ณ   Spring Boot Config Data ์ ‘๊ทผ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด spring: config: import์— Vault ์‹œ์Šคํ…œ์„ ๋ฐ”์ธ๋”ฉ ํ•˜๊ธฐ ์œ„ํ•œ ์†์„ฑ ์„ค์ •์ด ํ•„์š”ํ•จ. (Spring Boot ์˜ Config Data API
์•„๋‹˜, application.yml์— spring:cloud:bootstrap:enabled: true or pom.xml or build.gradle ํŒŒ์ผ์— spring-cloud-starter-bootstrap import์„ ํ•˜์—ฌ bootstrap.yml ์„ ํ™œ์„ฑํ™”๋ฅผ ํ•  ์ˆ˜ ์žˆ์Œ.

โ˜ž https://docs.spring.io/spring-cloud-vault/docs/current/reference/html/#client-side-usage ์— ์ž์„ธํ•œ ์„ค๋ช…์ด ์žˆ๋‹ค.

 

// config ํŒจํ‚ค์ง€ ์ƒ์„ฑํ›„ ์•„๋ž˜์˜ ํด๋ž˜์Šค ์ƒ์„ฑ 

@Getter
@Configuration
public class VaultData {

    @Value("${username}")
    private String username;

    @Value("${password}")
    private String password;
}
// ํ™•์ธ

@Slf4j
@SpringBootApplication
public class HelloApplication {

    public static void main(String[] args) {

        ConfigurableApplicationContext context = SpringApplication.run(HelloApplication.class, args);

        // vault ํ…Œ์ŠคํŠธ --
        VaultData vaultData = context.getBean(VaultData.class);
        log.info("username:{}", vaultData.getUsername());
        log.info("password:{}", vaultData.getPassword());
    }
}

 

 

 

end ~

๋ฐ˜์‘ํ˜•
๋ฐ˜์‘ํ˜•
์Šคํ”„๋ง ํด๋ผ์šฐ๋“œ
์„ค๋ช…

ํด๋ผ์šฐ๋“œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ
์•„๋ž˜์™€ ๊ฐ™์€ ๋‚ด์šฉ๋“ค์„ ์ œ๊ณตํ•ด์ค€๋‹ค.


    โ–ถ๏ธŽ ๋ถ„์‚ฐ / ๋ฒ„์ „ ์ปจํ”ผ๊ทœ๋ ˆ์ด์…˜
        • ๋ถ„์‚ฐ ์ปจํ”ผ๊ทœ๋ ˆ์ด์…˜์€ ํด๋ผ์šฐ๋“œ ๋„ค์ดํ‹ฐ๋ธŒ ํ™˜๊ฒฝ์—์„œ ์ธ๊ธฐ์žˆ๋Š” ํ‘œ์ค€์ด๋‹ค. 
        • ์Šคํ”„๋ง ์ปจํ”ผ๊ทธ๋Š” ๋ถ„์‚ฐ์‹œ์Šคํ…œ์—์„œ ์™ธ๋ถ€ ์ปจํ”ผ๊ทœ๋ ˆ์ด์…˜์„ ์œ„ํ•ด ์„œ๋ฒ„ ์ธก๊ณผ ํด๋ผ์ด์–ธํŠธ ์ธก์„ ์ง€์›ํ•œ๋‹ค.
            → ์ค‘์•™ ๋‹จ์ผ ์ €์žฅ์†Œ ์ƒ์„ฑ๋จ. ... vault..
        • ์ฃผํ‚คํผ(Zookeeper) ๋“ฑ์ด์žˆ๋‹ค..


    โ–ถ๏ธŽ ์„œ๋น„์Šค ๋“ฑ๋ก & ๋””์Šค์ปค๋ฒ„๋ฆฌ
        • ๋””์Šค์ปค๋ฒ„๋ฆฌ๋Š” ์ปดํ“จํ„ฐ ๋„คํŠธ์›Œํฌ์ƒ์˜ ๋””๋ฐ”์ด์Šค๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋””๋ฐ”์ด์Šค&์„œ๋น„์Šค๋ฅผ ์ž๋™์œผ๋กœ ๊ฐ์ง€ํ•˜๋Š” ์„œ๋น„์Šค์ด๋‹ค.
            → ๊ฐ ์„œ๋น„์Šค๋“ค ์‹คํ–‰์‹œ ์ค‘์•™ ์„œ๋ฒ„์— ์ž์‹ (์„œ๋น„์Šค)์„ ๋“ฑ๋กํ•˜๋Š”๊ฒƒ. (IP, Port ๋“ฑ)
            → ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ์—์„œ ๊ฐ ์„œ๋ฒ„์ธ์Šคํ„ด์Šค๋“ค์ด ์˜คํ† ์Šค์ผ€์ผ๋ง ๋˜๊ฑฐ๋‚˜, ์ƒ์„ฑ ํ™•์žฅ๋“ฑ์ด ๋ ๋•Œ IP or Port ๋“ฑ์ด ๋ณ€๊ฒฝ๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์•„์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฌํ•œ ์ •๋ณด๋“ค์„ ์บ์น˜ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ์‚ฌ์šฉํ•จ.
        • ๋„ทํ”Œ๋ฆญ์Šค OSS(Open Source Software) ์˜ ๋””์Šค์ปค๋ฒ„๋ฆฌ ํŒจํ‚ค์ง€ ์œ ๋ ˆ์นด(Eureka)๊ฐ€ ์žˆ๋‹ค.
        • ์œ ๋ ˆ์นด๋Š” ํด๋ผ์ด์–ธํŠธ & ์„œ๋ฒ„๋กœ ๊ตฌ์„ฑ์ด ๋˜๋ฉฐ, ํด๋ผ์ด์–ธํŠธ๋Š” ์›๊ฒฉ ๋””์Šค์ปค๋Ÿฌ๋น„์„œ๋ฒ„์— ์—ฐ๊ฒฐํ•˜๋Š” ์ผ์„ ๋‹ด๋‹นํ•˜๊ณ 
์„œ๋ฒ„๋Š” ๋…๋ฆฝ์ ์ธ ์Šคํ”„๋ง๋ถ€ํŠธ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋‹ด๋‹นํ•œ๋‹ค.


    โ–ถ๏ธŽ ๋ผ์šฐํŒ…
        • ๋„ทํ”Œ๋ฆญ์Šค OSS(Open Source Software) ์˜ ์ค„(Zuul)์ด ์žˆ๋‹ค.
        • ์ค„์€ ๋ถ€ํ•˜๋ถ„์‚ฐ ๋ฐ ํ•„ํ„ฐ๋ง์„ ์ˆ˜ํ–‰ํ•˜๊ณ , ๊ฒŒ์ดํŠธ์›จ์ด๋กœ์จ์˜ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•œ๋‹ค.


    โ–ถ๏ธŽ ์„œ๋น„์Šค๊ฐ„ ํ˜ธ์ถœ

        • API ๊ฒŒ์ดํŠธ์›จ์ด์—์„œ ๊ฐ ์„œ๋น„์Šค๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, ๋„๋ฉ”์ธ์œผ๋กœ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  IP๋“ฑ์œผ๋กœ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉด ๋ณ€๊ฒฝ๋œ IP์— ๋Œ€ํ•ด์„œ๋Š” ๊ด€๋ จ ๋‚ด์šฉ์„ ์—…๋ฐ์ดํŠธ ํ•ด์ค˜์•ผ ํ•จ
        • ๋””์Šค์ปค๋ฒ„๋ฆฌ ์„œ๋น„์Šค๋Š” ์ธ์Šคํ„ด์Šค์˜ ID๋‚˜ ์ด๋ฆ„์œผ๋กœ ํ˜ธ์ถœํ•˜๊ธฐ์—, ๋ณ€๊ฒฝ๋œ ์ •๋ณด๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ์—†์Œ. 
        • API ํ†ต์‹ ํ• ๋•Œ ์‚ฌ์šฉํ•˜๋Š” RestClient ์ข…๋ฅ˜๋กœ ๋„ทํ”Œ๋ฆญ์Šค OSS(Open Source Software) ์˜ํŽ˜์ธ(Feign) ์ด ์žˆ๋‹ค.


    โ–ถ๏ธŽ ๋ถ€ํ•˜๋ถ„์‚ฐ
        • ๋ผ์šด๋“œ ๋กœ๋นˆ ๊ทœ์น™์„ ๊ฐ€์ง€๊ณ  ๋””์Šค์ปค๋ฒ„๋ฆฌ์— ๋“ฑ๋ก๋œ ์ธ์Šคํ„ด์Šค ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜ค๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. (๋ถ€ํ•˜๋ถ„์‚ฐ๊ธฐ)
        • ๋„ทํ”Œ๋ฆญ์Šค OSS(Open Source Software) ์˜ ๋ฆฌ๋ณธ(Ribbon) ์ด
์žˆ๋‹ค.


    โ–ถ๏ธŽ ์„œํ‚ท๋ธŒ๋ ˆ์ด์ปค
        • ๋„คํŠธ์›Œํฌ ํƒ€์ž„์•„์›ƒ ๋ฌธ์ œ ํ•ด๊ฒฐ 
        • ์„œํ‚ท ๋ธŒ๋ ˆ์ด์ปค: ์„ฑ๊ณต & ์‹คํŒจ ํ™•๋ฅ ์„ ์ €์žฅ
        • ์ž„๊ณ„์น˜๊ฐ€ ๋„˜์œผ๋ฉด ์ฐจ๋‹จ! 
        • ํด๋ฐฑ(fallback) ๋กœ์ง ์ˆ˜ํ–‰!


    โ–ถ๏ธŽ ๋ถ„์‚ฐ ๋ฉ”์„ธ์ง• 
        • AMQP, Apache kafka ๋“ฑ์ด ์žˆ๋‹ค.

 

 

ํด๋ผ์šฐ๋“œ ๋„ค์ดํ‹ฐ๋ธŒ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜
์„ค๋ช…

ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ์„ ์œ„ํ•ด ์ž˜ ์„ค๊ณ„๋œ ํ”„๋กœ๊ทธ๋žจ
https://docs.spring.io/spring-cloud-commons/docs/3.1.1/reference/html/

 

 

 


์ฐธ๊ณ 

์ฑ…: http://www.yes24.com/Product/Goods/66581779
๋งํฌ: https://mangchhe.github.io/springcloud/2021/04/07/ServiceDiscoveryConcept/

 

[Spring Cloud] Service Discovery๋ž€?

Service Discovery๊ฐ€ ์™œ ํ•„์š”ํ•œ์ง€, Service Discovery์˜ ์ข…๋ฅ˜์™€ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ๋ฐฐ์›Œ๋ณด์ž

mangchhe.github.io

๋งํฌ: https://www.baeldung.com/spring-cloud-bootstrapping

 

๋ฐ˜์‘ํ˜•
๋ฐ˜์‘ํ˜•
json web token
์„ค๋ช…

JSON ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ† ํฐ ์ž์ฒด์— ์ •๋ณด๋“ค์„ ์ €์žฅํ•˜๊ณ  ์žˆ๋Š” ์›นํ† ํฐ.
claims์„ ์•ˆ์ „ํ•˜๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ํ‘œ์ค€.
HMAC ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์‚ฌ์šฉ ํ•˜๊ฑฐ๋‚˜, RSA or ECDSA๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ณต๊ฐœ / ๊ฐœ์ธํ‚ค ์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ช…์ด ๊ฐ€๋Šฅํ•จ.
๊ถŒํ•œ ๋ถ€์—ฌ ๋ฐ ์ •๋ณด๊ตํ™˜์‹œ์ ์—์„œ ์‚ฌ์šฉ.

โœณ๏ธŽ claims ?
JWT ์˜ PAYLOAD ๋ถ€๋ถ„์„ ๊ตฌ์„ฑํ•˜๊ณ  ๊ตํ™˜๋˜๋Š” ์ •๋ณด ์ง‘ํ•ฉ.

 

ํ† ํฐ์ƒ๊น€์ƒˆ
eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0IiwiYXV0aCI6IlJPTEVfVVNFUiIsImV4cCI6MTY0MDI2NjczOX0.A5bzyF4jkKVmdDzboK8_qsPbDh3qGO3v2lgcSp5K41CxmSgyDZlKxBfcZNiZ754S_IDhFOPO7m18bsBqhZgBMw

์œ„์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ์ƒ๊ฒผ์œผ๋ฉฐ, https://jwt.io/ ์‚ฌ์ดํŠธ์—์„œ ํ† ํฐ ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๊ตฌ์„ฑ๋ฐฉ์‹

HEADER, PAYLOAD, SIGNITURE ์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. 
์ด ์„ธ๋ถ€๋ถ„์€ Base64url ์ธ์ฝ”๋”ฉ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ„๋„๋กœ ์ธ์ฝ”๋”ฉ๋˜๋ฉฐ JWT ์ƒ์„ฑ์„ ์œ„ํ•˜ ์ (.)์„ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ๊ฒฐ๋œ๋‹ค. 

var token = base64UrlEncoding(HEADER) + '.' + base64UrlEncoding(PAYLOAD) + '.' + base64UrlEncoding(SIGNITURE);

↓↓↓↓

var token = 
eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0IiwiYXV0aCI6IlJPTEVfVVNFUiIsImV4cCI6MTY0MDI2NjczOX0.A5bzyF4jkKVmdDzboK8_qsPbDh3qGO3v2lgcSp5K41CxmSgyDZlKxBfcZNiZ754S_IDhFOPO7m18bsBqhZgBMw

 

๊ฐ ๊ตฌ์„ฑ ์„ค๋ช…์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

HEADER signiture ์ •๋ณด๋ฅผ ํ•ด์‹ฑํ•˜๊ธฐ ์œ„ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ •๋ณด๋“ค์ด ๋‹ด๊ฒจ์žˆ๋Š”๊ณณ.
HMAC, SHA256 or RSA ์™€ ๊ฐ™์€ ์„œ๋ช… ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๊ตฌ์„ฑ๋จ.
PAYLOAD ์„œ๋ฒ„, ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ฃผ๊ณ  ๋ฐ›๋Š” ์‹œ์Šคํ…œ์—์„œ ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋  ์ •๋ณด์— ๋Œ€ํ•œ ๋‚ด์šฉ์ด ๋‹ด๊ฒจ์žˆ์Œ.
PAYLOAD claims ์€ 3๊ฐ€์ง€ ์œ ํ˜•์ด ์กด์žฌ

- registered claims: ํ•„์ˆ˜๋Š” ์•„๋‹ˆ์ง€๋งŒ ์ƒํ˜ธ ์šด์šฉ์„ ์œ„ํ•ด ๋ฏธ๋ฆฌ ์ •์˜๋œ ํด๋ ˆ์ž„(RFC 7519) ์ง‘ํ•ฉ (iss, exp, sub, aud..)

- public claims: jwt ์„ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ๋งˆ์Œ๋Œ€๋กœ ์ •์˜. ์ถฉ๋Œ ๋ฐฉ์ง€ ์œ„ํ•ด ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ํฌํ•จํ•˜๋Š” URL๋กœ ์ •์˜ ํ•„์š”

- private claims: ์‚ฌ์šฉ์— ๋™์˜ํ•˜๊ณ  ๋“ฑ๋ก๋œ ํด๋ ˆ์ž„์ด๋‚˜ ๊ณต๊ฐœ ํด๋ ˆ์ž„์ด ์•„๋‹Œ ๋‹น์‚ฌ์ž๊ฐ„์˜ ์ •๋ณด๋ฅผ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•ด ์ƒ์„ฑ๋œ ๋งž์ถค ํด๋ ˆ์ž„
SIGNITURE ํ† ํฐ์˜ ์œ ํšจ์„ฑ ๊ฒ€์ฆ์„ ์œ„ํ•œ ๋ฌธ์ž์—ด. ์ด ๋ฌธ์ž์—ด๋กœ ์œ ํšจํ•œ ํ† ํฐ์ธ์ง€ ํ™•์ธํ•จ.
๋ฉ”์„ธ์ง€๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š”๋ฐ ์‚ฌ์šฉ.

 

 

๋™์ž‘๋ฐฉ์‹

jwt ํ† ํฐ ์ธ์ฆ ๋ฐฉ์‹ ๊ธฐ์ค€์œผ๋กœ ๊ทธ๋ ค๋ณธ๊ฒƒ์ด๋‹ค. (oauth2์˜ ํ—ˆ๊ฐ€๋Š” ์ƒ๋žต)

accessToken, refreshToken์ด jwt ์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด์žˆ๋‹ค.

 

์žฅ์ ๊ณผ ๋‹จ์ 
  • ์žฅ์ 
    ์ค‘์•™์˜ ์ธ์ฆ์„œ๋ฒ„, ๋ฐ์ดํ„ฐ ์Šคํ† ์–ด์— ๋Œ€ํ•œ ์˜์กด์„ฑ์ด ์—†๊ณ , ์‹œ์Šคํ…œ ์ˆ˜ํ‰ํ™•์žฅ์— ์œ ๋ฆฌํ•˜๋‹ค.

  • ๋‹จ์ 
    PAYLOAD ์ •๋ณด๊ฐ€ ๋งŽ์•„์ง€๋ฉด ๋„คํŠธ์›Œํฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ฆ๊ฐ€ํ•จ.
    ํ† ํฐ์ด ํด๋ผ์ด์–ธํŠธ์— ์ €์žฅ๋˜๊ธฐ์— ์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ์˜ ํ† ํฐ์„ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 


์ฐธ์กฐ

https://jwt.io/introduction

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

https://ko.wikipedia.org/wiki/JSON_%EC%9B%B9_%ED%86%A0%ED%81%B0

 

JSON ์›น ํ† ํฐ - ์œ„ํ‚ค๋ฐฑ๊ณผ, ์šฐ๋ฆฌ ๋ชจ๋‘์˜ ๋ฐฑ๊ณผ์‚ฌ์ „

JSON ์›น ํ† ํฐ์ƒํƒœ์ธํ„ฐ๋„ท ํ‘œ์ค€์ตœ์ดˆ ์ถœํŒ์ผ2010๋…„ 12์›” 28์ผ (2010-12-28)๋งˆ์ง€๋ง‰ ๋ฒ„์ „RFC 75192015๋…„ 5์›”์กฐ์งIETF์•ฝ์–ดJWT JSON ์›น ํ† ํฐ(JSON Web Token, JWT, "jot”[1])์€ ์„ ํƒ์  ์„œ๋ช… ๋ฐ ์„ ํƒ์  ์•”ํ˜ธํ™”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ

ko.wikipedia.org

https://velog.io/@kshired/Express%EC%97%90%EC%84%9C-JWT%EB%A1%9C-%EC%9D%B8%EC%A6%9D%EC%8B%9C%EC%8A%A4%ED%85%9C-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0-Access-Token%EA%B3%BC-Refresh-Token

 

Express์—์„œ JWT๋กœ ์ธ์ฆ์‹œ์Šคํ…œ ๊ตฌํ˜„ํ•˜๊ธฐ ( Access Token๊ณผ Refresh Token )

Express์—์„œ jwt๋ฅผ ์ด์šฉํ•˜์—ฌ access token์œผ๋กœ๋งŒ ์ธ์ฆ์„ ํ•˜๋Š” ๊ธ€์€ ๋งŽ์ด ์žˆ๋Š”๋ฐ, refresh token๊นŒ์ง€ ๊ตฌํ˜„ํ•œ ์ž๋ฃŒ๋Š” ๊ทธ๋ ‡๊ฒŒ ๋งŽ์ง€์•Š์•„ ์ด ๊ธ€์„ ์“ฐ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.์ด ๊ธ€์€ ๊ตฌํ˜„์— ์น˜์ค‘๋˜์–ด ์žˆ์–ด, JWT์˜ ์ž์„ธํ•œ

velog.io

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-jwt/dashboard

 

[๋ฌด๋ฃŒ] Spring Boot JWT Tutorial - ์ธํ”„๋Ÿฐ | ๊ฐ•์˜

Spring Boot, Spring Security, JWT๋ฅผ ์ด์šฉํ•œ ํŠœํ† ๋ฆฌ์–ผ์„ ํ†ตํ•ด ์ธ์ฆ๊ณผ ์ธ๊ฐ€์— ๋Œ€ํ•œ ๊ธฐ์ดˆ ์ง€์‹์„ ์‰ฝ๊ณ  ๋น ๋ฅด๊ฒŒ ํ•™์Šตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค., [์‚ฌ์ง„] ๋ณธ ๊ฐ•์˜๋Š” Spring Boot, Spring Security๋ฅผ ์ด์šฉํ•ด์„œ JWT ์ธ์ฆ๊ณผ ์ธ๊ฐ€๋ฅผ ์‰ฝ

www.inflearn.com

https://techdocs.akamai.com/api-gateway/docs/json-web-token-jwt-val#jwt-claims

 

JSON web token (JWT) validation

JSON web token is an open standard (RFC 7519) that defines a compact and self-contained method for securely transmitting JSON-encoded information between parties. With <<COMPANY_NICKNAME>>, you can use JWTs to quickly identify and authorize API consumers w

techdocs.akamai.com

 

๋ฐ˜์‘ํ˜•

'๊ฐœ๋ฐœ > etc' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

SSE (Server Sent Event)  (1) 2023.08.20
Vault  (1) 2023.02.07
ํ—ฅ์‚ฌ๊ณ ๋‚  ์•„ํ‚คํ…์ฒ˜ (Hexagonal Architecture)  (2) 2022.09.25
Rest API  (0) 2021.06.02
HTTP๊ด€๋ จ (https, spdy, ajax, websocket)  (0) 2018.12.09
๋ฐ˜์‘ํ˜•

์–ด๋””์„œ ๋งŽ์ด ๋ณธ ๊ทธ๋ฆผ

 

 

filter
์„ค๋ช…

dispatcherServlet ํ˜ธ์ถœ ์ „, ์š”์ฒญ์— ๋Œ€ํ•ด์„œ ์ „์ฒ˜๋ฆฌ ์ž‘์—…(์›ํ•˜๋Š” ํ˜•ํƒœ๋กœ ๋ณ€ํ˜•)์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ. (์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋“ฑ๋ก)
filter chain ์„ ํ†ตํ•ด ์—ฐ์‡„์ ์œผ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๊ฐ€๋Šฅ.
์ธ์ฆ, ๊ถŒํ•œ, CORS, ์ธ์ฝ”๋”ฉ, XSS ์ž‘์—…์‹œ ์ด์šฉ

 

 

dispatcherServlet
์„ค๋ช…

ํ”„๋ŸฐํŠธ ์ปจํŠธ๋กค๋Ÿฌ์™€ ์—ฐ๋™๋˜๋Š” ์ง„์ž…์  ์—ญํ• ์„ ํ•˜๋ฉฐ, ๊ธฐ๋ณธ์ ์ธ ์ฒ˜๋ฆฌ ํ๋ฆ„์„ ์ œ์–ดํ•˜๋Š” ์‚ฌ๋ นํƒ‘ ์—ญํ• ์„ ํ•œ๋‹ค. 

โœฟ ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ?
ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์„ ํ”„๋ŸฐํŠธ ์ปจํŠธ๋กค๋Ÿฌ๋ผ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฐ›์•„ ์š”์ฒญ ๋‚ด์šฉ์— ๋”ฐ๋ผ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•ธ๋“ค๋Ÿฌ(Handler)๋ฅผ ์„ ํƒํ•˜๋Š” ์•„ํ‚คํ…์ฒ˜

 

dispatcherServlet๊ณผ ์—ฐ๋™๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค
์ธํ„ฐํŽ˜์ด์Šค๋ช… ์—ญํ• 
HandlerExceptionResolver ์˜ˆ์™ธ์ฒ˜๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค.
LocaleResolver
LocaleContextResolver
ํด๋ผ์ด์–ธํŠธ Locale ์ •๋ณด๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค.
ThemeResolver ์Šคํ”„๋ง ํ…Œ๋งˆ๋ฅผ ๊ฒฐ์ •ํ•˜๊ธฐ ์œ„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค.
FlashMapManager FlashMap์ด๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค.
RequestToViewNameTranslator ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋ทฐ ์ด๋ฆ„๊ณผ ๋ทฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์ ์šฉ๋˜๋Š” ๋ทฐ ์ด๋ฆ„์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค. ์Šคํ”„๋ง MVC์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ ๊ตฌํ˜„ ํด๋ž˜์Šค๊ฐ€ ์ ์šฉ๋˜์–ด ์žˆ๋‹ค.
HandlerInterceptor ํ•ธ๋“ค๋Ÿฌ ์‹คํ–‰ ์ „ํ›„์— ํ•˜๋Š” ๊ณตํ†ต ์ฒ˜๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค. ์ด ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ตฌํ˜„ํ•˜๊ณ  ์Šคํ”„๋ง MVC์— ๋“ฑ๋กํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
MultipartResolver ๋ฉ€ํ‹ฐํŒŒํŠธ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค. ์Šคํ”„๋ง MVC์—์„œ ๋ช‡ ๊ฐ€์ง€ ๊ตฌํ˜„ ํด๋ž˜์Šค๊ฐ€ ์ œ๊ณต๋˜๊ณ  ์žˆ์ง€๋งŒ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.

 

 

Handler
์„ค๋ช…

ํ”„๋ ˆ์ž„์›Œํฌ ๊ด€์ ์—์„œ ๋ถˆ๋ฆฌ๋Š” Handler๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž‘์„ฑํ•˜๋Š” ํด๋ž˜์Šค์˜ ๊ด€์ ์—์„œ Controller ์ด๋‹ค.

 

 

HandlerMapping
์„ค๋ช…

์š”์ฒญ์— ๋Œ€์‘ํ•  ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์„ ํƒํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. (์ปจํŠธ๋กค๋Ÿฌ๋‚ด์˜ ๋ฉ”์†Œ๋“œ๊ฐ€ ํ•ธ๋“ค๋Ÿฌ๋กœ ์ธ์‹!)
ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ €)์—์„œ ์š”์ฒญ์ด ์˜ฌ ๊ฒฝ์šฐ RequestMappingHandlerMapping ํด๋ž˜์Šค๋Š”
์š”์ฒญ ๋‚ด์šฉ(์š”์ฒญ ๊ฒฝ๋กœ ํ˜น์€ HTTP ๋ฉ”์„œ๋“œ)๊ณผ ์š”์ฒญ ๋งคํ•‘ ์ •๋ณด๋ฅผ ๋งค์นญํ•ด์„œ ์‹คํ–‰ํ•  ํ•ธ๋“ค๋Ÿฌ๋ฅด ์„ ํƒํ•œ๋‹ค!

@Controller
class TestController {
    @RequestMapping("/hello")
    public String hello() {
        return "/hi";
    }
    // hello ๋ฉ”์†Œ๋“œ๊ฐ€ ํ•ธ๋“ค๋Ÿฌ!
}

 

 

HandlerAdapter
์„ค๋ช…

ํ•ธ๋“ค๋Ÿฌ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. (RequestMappingHandlerAdapter)
RequestMappingHandlerAdapter ํด๋ž˜์Šค ์—์„œ๋Š” ํ•ธ๋“ค๋Ÿฌ ๋ฉ”์„œ๋“œ์— ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ๋ฉ”์„œ๋“œ์˜ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ ๋˜๋Œ๋ ค ๋ณด๋ƒ„
๋นˆ ๊ฐ์ฒด ๊ฒ€์‚ฌ ๋“ฑ๋“ฑ์„ ํ•จ.

 

 

ViewResolver
์„ค๋ช…

ํ•ธ๋“ค๋Ÿฌ์—์„œ ๋ฐ˜ํ™˜ํ•œ ๋ทฐ ์ด๋ฆ„์„ ๋ณด๊ณ , ์ดํ›„์— ์‚ฌ์šฉํ•  View ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„ ํด๋ž˜์Šค๋ฅผ ์„ ํƒํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

 


์ฐธ๊ณ 

(์ฑ…) ์Šคํ”„๋ง ์ฒ ์ € ์ž…๋ฌธ
(์ฑ…) ์Šคํ”„๋ง ๋ถ€ํŠธ๋กœ ๋ฐฐ์šฐ๋Š” ์ž๋ฐ” ์›น ๊ฐœ๋ฐœ
https://exhibitlove.tistory.com/7

 

[springboot] Filter ์„ค์ •

์ถœ์ฒ˜ : https://linked2ev.github.io/gitlog/2019/09/15/springboot-mvc-13-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-MVC-Filter-%EC%84%A4%EC%A0%95/ Filter๋ž€? ํ•„ํ„ฐ๋ž€? ๊ฑฐ๋ฅธ๋‹ค๋Š” ๋œป์ด๋‹ค. ์„œ๋ธ”๋ฆฟ์˜ Servl..

exhibitlove.tistory.com

https://stargatex.wordpress.com/2015/12/08/spring-mvc-request-lifecycle/

๋ฐ˜์‘ํ˜•

'๊ฐœ๋ฐœ > spring' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[WebSocket] ์›น์†Œ์ผ“  (6) 2022.03.29
ํŠธ๋žœ์žญ์…˜  (0) 2021.11.25
Spring - DI (Dependency Injection)  (0) 2021.06.01
Spring - AOP(Aspect-Oriented Programming)  (0) 2021.05.25
IOC/DI, DI์‘์šฉ  (0) 2017.11.20
๋ฐ˜์‘ํ˜•
์ƒํ™ฉ

H2 db ์‚ฌ์šฉ, entity class ์— ํ…Œ์ด๋ธ”๋ช…์„ ๋ช…์‹œํ•ด์ฃผ์ง€ ์•Š์Œ. 
๋ฐ์ดํ„ฐ ๋“ฑ๋ก ์ฒ˜๋ฆฌ ์ค‘ ํ•ด๋‹น ์—๋Ÿฌ ๋ฐœ์ƒ (ํ…Œ์ด๋ธ” ์‹œํ€€์Šค ๊ฐ’์ด ์—†๋‹ค๋Š” ์ƒํ™ฉ)

 

ํ•ด๊ฒฐ

entity class (@Entity ์„ค์ • ํด๋ž˜์Šค) ๋‚ด id ํ•„๋“œ(@Id ์„ค์ •๋œ ๊ฐ’)์˜
@GeneratedValue(strategy = GenerationType.AUTO) ์„ค์ • ๋ถ€๋ถ„์„
@GeneratedValue(strategy = GenerationType.IDENTITY) ์œผ๋กœ ๋ณ€๊ฒฝ
    --> ๊ธฐ๋ณธํ‚ค ์ƒ์„ฑ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์œ„์ž„ํ•ด์ฃผ๊ณ  id๊ฐ€ null ์ด๋ฉด ์•Œ์•„์„œ auto_increment ํ•ด์คŒ


์ฐธ๊ณ 

https://stackoverflow.com/questions/39807483/sequence-hibernate-sequence-not-found-sql-statement

 

Sequence "HIBERNATE_SEQUENCE" not found; SQL statement

In my spring mvc app, i have the following object. I am trying to make a visual of data using devtool in my app. @Entity @Data public class ConsultationRequest { @Id @GeneratedValue p...

stackoverflow.com

https://gmlwjd9405.github.io/2019/08/12/primary-key-mapping.html

๋ฐ˜์‘ํ˜•
๋ฐ˜์‘ํ˜•
AOP (Aspect-Oriented Programming)
์„ค๋ช…

์—ฌ๋Ÿฌ ๋กœ์ง๋‹จ์— ์ ์šฉ๋˜์–ด์•ผ ํ•  ํŠน์ • ์ค‘๋ณต ๋กœ์ง์„ ์—ฌ๋Ÿฌ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ์ ์šฉํ•˜๋Š” ๊ฒƒ
ํฉ์–ด์ง„ ์ฝ”๋“œ๋ฅผ ํ•œ๊ณณ์œผ๋กœ ๋ชจ์œผ์ž!
ํšก๋‹จ ๊ด€์‹ฌ์— ๋”ฐ๋ผ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ•˜๋Š”๊ฒƒ

โ€ป ํšก๋‹จ
๋™์„œ ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐ€๋กœ์งˆ๋Ÿฌ ๊ฐ€๋Š”๊ฒƒ
โ€ป ํšก๋‹จ ๊ด€์‹ฌ์‚ฌ (Cross cutting concern)

๋‹ค์ˆ˜์˜ ๋ชจ๋“ˆ์— ๊ณตํ†ต์ ์œผ๋กœ ๋‚˜ํƒ€๋‚˜๋Š” ๋ถ€๋ถ„์ด ์กด์žฌ
๋ชจ๋“ˆ๋ณ„๋กœ ๋ฐ˜๋ณต๋˜์–ด ์ค‘๋ณตํ•ด์„œ ๋‚˜ํƒ€๋‚˜๋Š” ๋ถ€๋ถ„๋ฐ˜๋ณต๊ณผ ์ค‘๋ณต์€ ๋ถ„๋ฆฌํ•˜์—ฌ ํ•œ๊ณณ์—์„œ ํ‘œํ˜„ํ•ด์•ผ ํ•œ๋‹ค๋ผ๋Š”๊ฒƒ์„ ํ•ญ์ƒ ์ธ์ง€ํ•ด์•ผ ํ•จ.
ํŠน์ง•

Aspect ์œผ๋กœ ํ‘œํ˜„
๋กœ์ง(Code) ์ฃผ์ž…
๋กœ๊น…, ๋ณด์•ˆ, ํŠธ๋žœ์žญ์…˜ ๊ธฐ๋Šฅ์ด ๋ฐ˜๋ณต์ ์œผ๋กœ ๋‚˜ํƒ€๋‚จ
AOP๋Š” ํ”„๋ก์‹œ ๊ธฐ๋ฐ˜, ์ธํ„ฐํŽ˜์ด์Šค ๊ธฐ๋ฐ˜, ๋Ÿฐํƒ€์ž„ ๊ธฐ๋ฐ˜ ์ด๋‹ค.

 

๋ฉ”์†Œ๋“œ์— ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋Š” ์˜์—ญ

@Before: ๋Œ€์ƒ ๋ฉ”์†Œ๋“œ ์‹œ์ž‘ ์ „
@After: ๋Œ€์ƒ ๋ฉ”์†Œ๋“œ ์‹œ์ž‘ ํ›„
    @AfterReturning: ๋Œ€์ƒ ๋ฉ”์†Œ๋“œ ์ •์ƒ ์ข…๋ฃŒ ํ›„ 
    @AfterThrowing: ๋Œ€์ƒ ๋ฉ”์†Œ๋“œ ์˜ˆ์™ธ ๋ฐœ์ƒ → ์ข…๋ฃŒ ํ›„

 

AOP ์šฉ์–ด
Aspect ์—ฌ๋Ÿฌ๊ฐœ์˜ Advice, ์—ฌ๋Ÿฌ๊ฐœ์˜ Pointcut์˜ ๊ฒฐํ•ฉ์ฒด๋ฅผ ์˜๋ฏธํ•˜๋Š” ์šฉ์–ด
Advisor ํ•œ๊ฐœ์˜ Advice, ํ•œ๊ฐœ์˜ Pointcut
Advice pointcut์— ์ ์šฉํ•  ๋กœ์ง, ์ฆ‰ ๋ฉ”์„œ๋“œ๋ฅผ ์˜๋ฏธ 

@Before("execution( * runSomething())") 
public void before(JoinPoint joinPoint) { ... }
JoinPoint ์—ฐ๊ฒฐ์ . ์—ฐ๊ฒฐ ๊ฐ€๋Šฅํ•œ ์ง€์ . Aspect ์ ์šฉ ๊ฐ€๋Šฅ ์ง€์ . ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ๋นˆ์˜ ๋ชจ๋“  ๋ฉ”์„œ๋“œ

public void before(JoinPoint joinPoint) { ... }
Pointcut ์ž๋ฅด๋Š” ์ง€์ , Aspect ์ ์šฉ ์œ„์น˜ ์ง€์ •์ž. ํšก๋‹จ ๊ด€์‹ฌ์‚ฌ๋ฅผ ์ ์šฉํ•  ํƒ€๊นƒ ๋ฉ”์„œ๋“œ๋ฅผ ์„ ํƒํ•˜๋Š” ์ง€์‹œ์ž.

@Before("execution( * runSomething())") → runSomething() ์‹คํ–‰ ์ „ AOP์„ ์‹คํ–‰ํ•˜๋ผ๋Š” ๋œป

 

Pointcut ์ง€์ •์ž ๊ด€๋ จ

 
  execution

์ผ์น˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์กฐ์ธ ํฌ์ธํŠธ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ Spring AOP๋กœ ์ž‘์—… ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์ฃผ์š” ํฌ์ธํŠธ ์ปท ์ง€์ •์ž์ž…๋‹ˆ๋‹ค.

  within
ํŠน์ • ์œ ํ˜• ๋‚ด ๊ฒฐํ•ฉ ์ ์— ๋Œ€ํ•œ ๋งค์นญ์„ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค (Spring AOP ์‚ฌ์šฉ์‹œ ๋งค์นญ ์œ ํ˜• ๋‚ด์—์„œ ์„ ์–ธ ๋œ ๋ฉ”์†Œ๋“œ ์‹คํ–‰).

  this
๋นˆ ์ฐธ์กฐ (Spring AOP ํ”„๋ก์‹œ)๊ฐ€ ์ฃผ์–ด์ง„ ์œ ํ˜•์˜ ์ธ์Šคํ„ด์Šค ์ธ ์กฐ์ธ ํฌ์ธํŠธ (Spring AOP ์‚ฌ์šฉ์‹œ ๋ฉ”์†Œ๋“œ ์‹คํ–‰)์— ๋Œ€ํ•œ ๋งค์นญ์„ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

  target
๋Œ€์ƒ ๊ฐ์ฒด (ํ”„๋ก์‹œ๋˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐ์ฒด)๊ฐ€ ์ฃผ์–ด์ง„ ์œ ํ˜•์˜ ์ธ์Šคํ„ด์Šค ์ธ ์กฐ์ธ ํฌ์ธํŠธ (Spring AOP ์‚ฌ์šฉ์‹œ ๋ฉ”์„œ๋“œ ์‹คํ–‰)์— ๋Œ€ํ•œ ๋งค์นญ์„ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

  args
์ธ์ˆ˜๊ฐ€ ์ฃผ์–ด์ง„ ์œ ํ˜•์˜ ์ธ์Šคํ„ด์Šค ์ธ ์กฐ์ธ ํฌ์ธํŠธ (Spring AOP ์‚ฌ์šฉ์‹œ ๋ฉ”์„œ๋“œ ์‹คํ–‰)์— ๋Œ€ํ•œ ๋งค์นญ์„ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

  @target
์‹คํ–‰ ๊ฐ์ฒด์˜ ํด๋ž˜์Šค๊ฐ€ ์ฃผ์–ด์ง„ ํƒ€์ž…์˜ ์–ด๋…ธํ…Œ์ด์…˜์„ ๊ฐ€์ง€๊ณ ์žˆ๋Š” join point (Spring AOP ์‚ฌ์šฉ์‹œ ๋ฉ”์†Œ๋“œ ์‹คํ–‰)๋กœ ๋งค์นญ์„ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

  @args
์ „๋‹ฌ ๋œ ์‹ค์ œ ์ธ์ˆ˜์˜ ๋Ÿฐํƒ€์ž„ ์œ ํ˜•์ด ์ฃผ์–ด์ง„ ์œ ํ˜•์˜ ์–ด๋…ธํ…Œ์ด์…˜์„ ๊ฐ–๋Š” ๊ฒฐํ•ฉ ์ง€์  (Spring AOP ์‚ฌ์šฉ์‹œ ๋ฉ”์†Œ๋“œ ์‹คํ–‰)์— ๋Œ€ํ•œ ์ผ์น˜๋ฅผ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

  @within
์ฃผ์–ด์ง„ ์–ด๋…ธํ…Œ์ด์…˜ (Spring AOP๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ฃผ์–ด์ง„ ์–ด๋…ธํ…Œ์ด์…˜์ด์žˆ๋Š” ํƒ€์ž…์—์„œ ์„ ์–ธ ๋œ ๋ฉ”์†Œ๋“œ์˜ ์‹คํ–‰)์ด์žˆ๋Š” ํƒ€์ž… ๋‚ด์—์„œ ์กฐ์ธ ํฌ์ธํŠธ์— ๋Œ€ํ•œ ๋งค์นญ์„ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

  @annotation
Join point์˜ ์ฃผ์ œ (Spring AOP์—์„œ ์‹คํ–‰๋˜๋Š” ๋ฉ”์†Œ๋“œ)๊ฐ€ ์ฃผ์–ด์ง„ ์–ด๋…ธํ…Œ์ด์…˜์„ ๊ฐ€์ง€๊ณ ์žˆ๋Š” join point๋กœ ๋งค์นญ์„ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

 

Pointcut ํ‘œํ˜„์‹ ์˜ˆ์ œ

 
  ๋ชจ๋“  ๊ณต์šฉ ๋ฉ”์†Œ๋“œ ์‹คํ–‰

execution(public * * (..))

  ๋‹ค์Œ์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ ๋ชจ๋“  ๋ฉ”์†Œ๋“œ์˜ ์‹คํ–‰ 
setexecution(* set * (..))

  AccountService์ธํ„ฐํŽ˜์ด์Šค์— ์˜ํ•ด ์ •์˜ ๋œ ๋ชจ๋“  ๋ฉ”์†Œ๋“œ์˜ ์‹คํ–‰ 
execution(* com.xyz.service.AccountService. * (..))

  serviceํŒจํ‚ค์ง€์— ์ •์˜ ๋œ ๋ชจ๋“  ๋ฉ”์†Œ๋“œ ์‹คํ–‰ 
execution(* com.xyz.service. *. * (..))

  ์„œ๋น„์Šค ํŒจํ‚ค์ง€ ๋˜๋Š” ํ•˜์œ„ ํŒจํ‚ค์ง€ ์ค‘ ํ•˜๋‚˜์— ์ •์˜ ๋œ ๋ชจ๋“  ๋ฉ”์„œ๋“œ ์‹คํ–‰
execution(* com.xyz.service .. *. * (..))

  ์„œ๋น„์Šค ํŒจํ‚ค์ง€ ๋‚ด์˜ ๋ชจ๋“  ์กฐ์ธ ํฌ์ธํŠธ (Spring AOP์—์„œ๋งŒ ๋ฉ”์„œ๋“œ ์‹คํ–‰)
within(com.xyz.service. *)

 ์„œ๋น„์Šค ํŒจํ‚ค์ง€ ๋˜๋Š” ํ•˜์œ„ ํŒจํ‚ค์ง€ ์ค‘ ํ•˜๋‚˜ ๋‚ด์˜ ๋ชจ๋“  ์กฐ์ธ ์ง€์  (Spring AOP์—์„œ๋งŒ ๋ฉ”์„œ๋“œ ์‹คํ–‰)
within(com.xyz.service .. *)

  ํ”„๋ก์‹œ๊ฐ€ AccountService์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ชจ๋“  ์กฐ์ธ ํฌ์ธํŠธ (Spring AOP์—์„œ๋งŒ ๋ฉ”์„œ๋“œ ์‹คํ–‰) 
this(com.xyz.service.AccountService)

 


 

์ฐธ๊ณ 


https://wikibook.co.kr/java-oop-for-spring/ (์ฑ…: ์Šคํ”„๋ง ์ž…๋ฌธ์„ ์œ„ํ•œ ์ž๋ฐ” ๊ฐ์ฒด์ง€ํ–ฅ์˜ ์›๋ฆฌ์™€ ์ดํ•ด)
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop

 

๋ฐ˜์‘ํ˜•

'๊ฐœ๋ฐœ > spring' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

ํŠธ๋žœ์žญ์…˜  (0) 2021.11.25
Spring - ์Šคํ”„๋ง MVC ๊ฐ„๋‹จ ์ •๋ฆฌ  (0) 2021.06.05
Spring - DI (Dependency Injection)  (0) 2021.06.01
IOC/DI, DI์‘์šฉ  (0) 2017.11.20
spring ์‹œ์ž‘, maven ์„ค์น˜  (0) 2017.11.12
๋ฐ˜์‘ํ˜•

ํ”„๋ก ํŠธ์—์„œ ๋ณด๋‚ด์ง€ ์•Š์€ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’์„ ์„œ๋ฒ„์—์„œ ๋ฐ›์œผ๋ ค๊ณ  ํ• ๋•Œ ๋ฐœ์ƒ.

 

@RequestParam์˜ required ์—ฌ๋ถ€ ํ™•์ธ

ex. @RequestParam(value=“param”, required=false) MultipartFile param ....

๋กœ ์ •์˜ํ•˜๋ฉด param ์„ null๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

 

+ MultipartFile[]์˜ ๊ฒฝ์šฐ๋Š” ํ”„๋ก ํŠธ์—์„œ ๊ฐ’์„ ์•ˆ๋„˜๊ธฐ๋”๋ผ๋„

๊ธฐ๋ณธ ์ฃผ์†Œ(null ์ด ์•„๋‹Œ ๊ธฐ๋ณธ ๊ธธ์ด 0)๊ฐ€ ์กด์žฌํ•˜์—ฌ ํ•ด๋‹น์ƒํ™ฉ ๋ฐœ์ƒ ์•ˆํ•จ!

๋ฐ˜์‘ํ˜•
๋ฐ˜์‘ํ˜•

์‚ฌ์šฉ์ค‘์ธ ํฌํŠธ ํ™•์ธํ•„์š” -> ํฌํŠธ๋ฅผ ์ฃฝ์ด์„ธ์š”.

$ lost -I :ํฌํŠธ๋ฒˆํ˜ธ
COMMAND   PID       USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
java    24496 xxx   6u  IPv6 xxxx     0t0  TCP *:http-alt (LISTEN)

$ kill -9 PID (PID๋Š” 24496)

 

๋ฐ˜์‘ํ˜•

+ Recent posts