Courses
Reviews
- Implementing a Spring Boot-based API template project to improve productivity
- Implementing a Spring Boot-based API template project to improve productivity
- Implementing a Spring Boot-based API template project to improve productivity
- Implementing a Spring Boot-based API template project to improve productivity
- Implementing a Spring Boot-based API template project to improve productivity
Posts
Q&A
์นด์นด์คํ ํฐ๊ด๋ จ
์๋ ํ์ธ์. ์ง๋ฌธ ๋ต๋ณ๋๋ฆฝ๋๋ค.์์ ์ ์์ ํ์ค ๋๋ ์๋ง spring oauth2 client ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ จ์ ๊ฒ๋๋ค.ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ธฐ๋ฅ์ด ์ด๋ฏธ ์ถ์ํ๋์๊ณ ์ค์ ๋ง ์งํํ๋ฉด ๋๋ ๊ฒ์ด์ฃ .๋ด๋ถ์ ์ผ๋ก๋ ์ ํฌ๊ฐ ์งํํ ์นด์นด์คํ ํฐ์ ๋ฐ๊ธ ๋ฐ๊ณ ์นด์นด์คํ ํฐ์ ์ด์ฉํด์ ์นด์นด์ค์ ๊ฐ์ ๋ ํ์ ์ ๋ณด๋ฅผ ๋ถ๋ฌ์ค๊ณ ์์ต๋๋ค.์ค์ ํ์ ์์ ์ผ์ ํ์๋ค๋ณด๋ฉด ํ์ฌ ๊ฐ์์์์ฒ๋ผ API ๋ฌธ์๋ฅผ ๋ณด๊ณ API๋ฅผ ํธ์ถํด๋ณด๊ณ ์ง์ ์ฐ๋ํด์ผํ๋ ์ผ๋ค์ด ๋น๋ฒํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ ๊ฒ ์ง์ ์ฐ๋ํด๋ณด์ง ์์ผ๋ฉด ์ฌ์ฉํ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ด๋ป๊ฒ๋์ํ๋์ง์ ๋ํ ์ด์ ๋ ์ ์ ์๊ณ , ๊ทธ๋ฅ ์ด๋ ๊ฒ ์ค์ ํ๋ฉด ๋๋๊ตฌ๋ํ๊ณ ๋์ด๊ฐ๊ฒ๋ฉ๋๋ค.์ง์ ์นด์นด์ค API ๋ฌธ์๋ฅผ ๋ณด๊ณ ์์ ๋ก๊ทธ์ธ์ ๋ถ์ฌ ๋ณธ๋ค๋ฉด ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ๊ณ ์๋ spring oauth2 client ๊ฐ์๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ด๋ถ์ ์ผ๋ก๋ ๋ค ์ด๋ฐ ๊ณผ์ ๋ค์ ํตํด์ ์ฐ๋ํ๊ณ ์์์ ์ ์ ์๊ณ , ๊ผญ ์์ ๋ก๊ทธ์ธ API๊ฐ์๋๋๋ผ๋ ์นด์นด์ค๋ ๋ค์ด๋ฒ ๊ตฌ๊ธ ๋ฑ์์ ์ ๊ณตํ๋ API๋ค์ ์ฐ๋ํด๋ณด๋ ์ฆ๊ฑฐ์์ ๋๊ปด๋ณด์ค ์ ์์ ๊ฒ๋๋ค.(ex) open ai ์ด๋ฏธ์ง ์์ฑ api ์ฐ๋, ๊ตฌ๊ธ text to speech api ๋ฑ๋ฑ๋ฑ๋ ํ๋ ํท๊ฐ๋ฆฌ์๋๊ฑฐ ๊ฐ์ ๊ฐ๋ ์ ์ง์ด ๋๋ฆฌ๋ฉด JWT์ ์นด์นด์คํ ํฐ์ ์ญํ ์ด ์๋์ ๊ฐ์ด ๋ค๋ฆ ๋๋ค.- JWT ๋ฐํ : ์ฐ๋ฆฌ๊ฐ ์ ๊ณตํ๋ API๋ฅผ ์ฌ์ฉํ๊ธฐ์ํ ์ธ์ฆ ํ ํฐ- ์นด์นด์คํ ํฐ: ์นด์นด์ค๊ฐ ์ ๊ณตํ๋ API๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ์ธ์ฆ ํ ํฐ.์นด์นด์ค์์ ํ์์ ๋ณด๋ฅผ ๊ฐ์ ธ์์ ์ฐ๋ฆฌ ์๋น์ค์ ํ์ ๊ฐ์ ์ ์ํค๊ธฐ ์ํด์ ์นด์นด์คํ ํฐ์ ๋ฐํํจ.
- 0
- 2
- 38
Q&A
OAUTH2 ์ง๋ฌธ
์๋ ํ์ธ์. ์ง๋ฌธ ์ฃผ์ ๋ด์ฉ ํ๋์ฉ ๋ต๋ณ๋๋ฆฝ๋๋ค.1. ๋ก๊ทธ์ธ์๋ -> Securty -> FILTER ์ฌ์ฉ์๊ฐ DB์์์ผ๋ฉด OK -> JWT๋ฐ๊ธ ์ด ํ๋ฆ์ด ๋ง๋์ง์..?ํ๋ฆ์ ๋ง๊ณ DB์ ์ฌ์ฉ์ ์ ๋ฌด ๊ด๊ณ์์ด JWT๋ ํญ์ ๋ฐ๊ธํฉ๋๋ค. JWT๋ฅผ ์ฐ๋ฆฌ๊ฐ ์ ๊ณตํ๋ ์๋น์ค๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ์ผ์ข ์ ์ด์ ๊ฐ์ ์ญํ ์ด๋ผ๊ณ ์๊ฐํด์ฃผ์๋ฉด ๋ฉ๋๋ค.ํด๋น ์ด์ ๋ฅผ API ํธ์ถ ์ ๊ฐ์ด ์ ๋ฌํด์ผ ์ธ์ฆ์ด ํ์ํ API๋ค์ ์ฌ์ฉํ ์ ์๋ค๊ณ ๋ด์ฃผ์๋ฉด ๋ฉ๋๋ค.2. oauth2 ํ์ ๊ฐ์ ํ์ ์ด์ oauth ๋ ํ์ ๊ฐ์ ํ ๋ ํ์ํ ์ ๋ณด๋ค์ ๊ณ ๊ฐ๋ค์ด ์ง์ ์ ๋ ฅํ์ง ์์๋ ์ฝ๊ฒ ๊ฐ์ ธ์ค๊ณ ์ถ๊ฐ๋ก ํ์ํ ์ ๋ณด๋ค๋ง ์ ๋ ฅ ๋ฐ์ ์ ์๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.(๊ฐํธ ํ์ ๊ฐ์ ). ๋ํ ์นด์นด์ค๋ ๋ค์ด๋ฒ๊ฐ์ ์์ ํ์ ๊ฐ์ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ๊ณณ์์ ์ฌ์ฉ์์ ๋ํ ์ธ์ฆ์ ํด์ฃผ๊ธฐ ๋๋ฌธ์ ์ค๋ช ์ธ์ฆ ๋ฑ ๋ฐ๋ก ์ ํฌ๊ฐ ๊ตฌํํด์ผํ๋ ๊ธฐ๋ฅ๋ค๋ ํจ์ฌ ์ ์ด์ง๋๋ค.3. ํ์ ๊ฐ์ ์ด ํ์ํ ์ด์ ์์ ๋ก๊ทธ์ธ์ ํ์ ๊ฐ์ ๋ฐ ๋ก๊ทธ์ธ์ ์ข ๋ ์ฝ๊ฒ ๋์์ฃผ๋ ์ญํ ์ ํ๋ค๊ณ ์๊ฐํด์ฃผ์๋ฉด ๋ฉ๋๋ค.์ฌ์ฉ์๊ฐ ๋ณต์กํ ํ์ ๊ฐ์ ๊ณผ์ ์ ๊ฑฐ์น์ง ์์๋ ์ฝ๊ฒ ๊ฐ์ ์ ํ ์ ์๋ ๊ฒ ์ ๋๋ค.๋ํ ์ ํฌ ์๋น์ค์ ๊ฐ์ ์ ์์ผ์ผ ์๋ฅผ ๋ค์ด ๊ฒ์๊ธ์ ์ด๋ค๊ณ ํ์ ๋ ์ด๋ค ์ฌ์ฉ์๊ฐ ๊ฒ์๊ธ์ ์ผ๋์ง ํ์ id๋ฅผ ์ง์ ํด์ค ์ ์์ํ ๊ณ , ์ผ๋ฐ์ ์ธ ์๋น์ค๋ผ๋ฉด ํ์ DB๋ฅผ ์ง์ ๊ด๋ฆฌํด์ ์ด๋ฒคํธ๋ฅผ ํ๋ค๊ณ ํ์ ๋ ํด๋น ํ์์ ์์ด๋๋ก push์๋ฆผ์ ๋ณด๋ด์ค๋ค๋๊ฐ ๊ธฐํ ๊ธฐ๋ฅ ๋ฑ์ ๊ตฌํํ ์ ์์ ๊ฒ ์ ๋๋ค.๋ํ ํ์ ๊ฐ์ ์ ํ์ง ์๋๋ค๋ฉด ํ์ฌ ์ฐ๋ฆฌ ์๋น์ค์ ํ์์ด ๋ช๋ช ์ธ์ง์ ๋ํ ๊ธฐ๋ณธ์ ์ธ ๊ฒ๋ค๋ ์ ์ ์์ ๊ฒ ์ ๋๋ค.4. ๋ง์ฝ ์ฌ์ฉ์์ ๋ณด๊ฐ ์ ์ฅ์ด ์ต์ด์ ๋๋ค๋ฉด ๊ทธ๋ค์๋ถํฐ๋ ๊ทธ๋ฅ oauth2๋ก๊ทธ์ธ์ผ๋ก ์ํ๋๊ฑด์ง ๊ทธ๋ฅ security์ ๋ก๊ทธ์ธ์ ํ๋๊ฑด์ง ๊ถ๊ธํฉ๋๋ค.์ ์ฅ์ด ๋ ์ดํ์๋ ์์ ๋ก๊ทธ์ธ์ ์งํ ์ ํ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๊ณ ํด๋น ํ์์ด ์ด๋ฏธ ๊ฐ์ ์ด ๋์ด์๋ค๋ฉด ๋ก๊ทธ์ธ์ด ๋์๋ค๋ ์๋ฏธ๋กJWT๋ง ์ฌ์ฉ์ํํ ๋ฐ๊ธํฉ๋๋ค. security ๋ก๊ทธ์ธ์ด๋ผ๋๊ฒ ์คํ๋ง ์ํ๋ฆฌํฐ๋ฅผ ๋ง์ํ์๋๊ฑฐ ๊ฐ์๋ฐ ํ์ฌ ๊ฐ์์์๋ security ๊ด๋ จํ ์ฝ๋๋ ์์ต๋๋ค!5. openfeign๋ฅผ ์ฐ์ ์ ์ฝ๋๋ฅผ ๋ฐ๊ณ ๊ทธ ์ฝ๋๋ก ์์ฒญ์ ๋ณด๋ด์ ํ ํฐ์ ๋ฐ๊ณ ๊ทธ ํ ํฐ์ผ๋ก ์ฌ์ฉ์์ ๋ณด๋ฅผ ๋ฐ๋๊ฑธ๋ก ์ดํด๋ฅผ ํ์ต๋๋ค. ์ํ๋ฆฌํฐ์์๋ ํด๋น๊ณผ์ ์ด ์๋๊ฑธ๋ก ์๊ณ ์๋๋ฐ ๋ง๋์ง์์คํ๋ง ์ํ๋ฆฌํฐ์์๋ ์์ด๋์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅํ๋ฉด ํด๋น ์ ๋ณด๋ฅผ ์ธ์ ์ ํตํด์ ๊ด๋ฆฌํฉ๋๋ค.์ํ๋ฆฌํฐ๋ง ์ฌ์ฉํ๋ค๋ฉด ์์ ๋ง์ํ์ ๊ฒ ๋ง๊ณ , ์คํ๋ง ์ํ๋ฆฌํฐ์ oauth๋ฅผ ๋ค ์ฌ์ฉํ์ ๋ค๋ฉดJWT๋ฅผ ์ฌ์ฉ์ํํ ๋ฐ๊ธ ํ ์ฌ์ฉ์๊ฐ ํ ํฐ์ ๋ณด๋์ ๋ ํด๋น ํ ํฐ์ ์๋ ์ ๋ณด๋ฅผ ํตํด์ ์ธ์ ์ ํ์ฌ ๋ก๊ทธ์ธํ ์ฌ์ฉ์์ ์ ๋ณด๋ฅผ ์ ์งํ๋ ๋ฑ ํจ๊ป ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋ ์์ต๋๋ค.
- 0
- 2
- 54
Q&A
auditing
@EntityListeners(value = {AuditingEntityListener.class}) ์ด๋ ธํ ์ด์ ์ ๊ฒฝ์ฐ ํ์ฌ BaseEntity, BaseTimeEntity ํด๋์ค์ ์ ์ธํด๋์์ต๋๋ค. ํด๋น ์ด๋ ธํ ์ด์ ์ฌ์ฉ ์ jpa์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋ ์ถ๊ฐ๋ก ์ฒ๋ฆฌ๋ฅผํ ์ ์๋๋ก ๋์์ฃผ๋ ๊ธฐ๋ฅ์ ๋๋ค.@CreatedDate, @LastModifiedDate ์ด๋ ธํ ์ด์ ์ ์์ฑ์๊ฐ๊ณผ ์ ๋ฐ์ดํธ์๊ฐ ํ๋์ ์ ์ธํด๋์๋๋ฐ ์ ์ฅ ๋ฐ ์ ๋ฐ์ดํธ ์ ํด๋น ๋ฆฌ์ค๋์ ์ํด์ ์์ฑ ์๊ฐ๊ณผ ์ ๋ฐ์ดํธ ์๊ฐ์ด ์ธํ ๋์ db์ ์ ์ฅ๋๋ค๊ณ ๋ด์ฃผ์๋ฉด๋ฉ๋๋ค.@EntityListeners(value = {AuditingEntityListener.class}) @MappedSuperclass @Getter public abstract class BaseTimeEntity { @CreatedDate @Column(updatable = false) private LocalDateTime createTime; @LastModifiedDate private LocalDateTime updateTime; }BaseEntity์ ๊ฒฝ์ฐ ๋ฑ๋ก์์ ์์ ์ ํ๋๋ฅผ ๊ฐ์ง๊ณ ์๋๋ฐ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ AuditorAwareImpl ์ ์ํด์ ํ์ฌ ์์ฒญํ API์ URI ์ ๋ณด๋ฅผ ์๋์ผ๋ก ๋ฑ๋กํด์ค๋๋ค.์ด๋ฐ ํธ์ ๊ธฐ๋ฅ ๋๋ถ์ ์ ํฌ๊ฐ ์ฝ๋์์์ ์ง์ ์์ฑ์๊ฐ/์์ ์๊ฐ/๋ฑ๋ก์/์์ ์๋ฅผ ์ธํ ํ๋ ๋ฒ๊ฑฐ๋ก์์ ๋ ์ ์์ต๋๋ค.@EntityListeners(value = {AuditingEntityListener.class}) @MappedSuperclass @Getter public abstract class BaseEntity extends BaseTimeEntity { @CreatedBy @Column(updatable = false) private String createdBy; @LastModifiedBy private String modifiedBy; }
- 0
- 1
- 29
Q&A
์ ์ญ์๋ฌ์ฒ๋ฆฌ์ง๋ฌธ
์๋ ํ์ธ์! http status๋ก ์ํ๋ ์ ์ ์์ง๋ง ์ ํํ ์ด๋ค ์๋ฌ๊ฐ ๋ฐ์ํ๊ฑด์ง๋ ์๊ธฐ๊ฐ ์ฝ์ง ์์ต๋๋ค.API์์ 400 http status๋ฅผ ๋ฐํํ๋ ์์ธ๊ฐ 3๊ฐ๊ฐ ์๋ค๋ฉด ์ด๋ค ์ค๋ฅ๊ฐ ๋ฐ์ํ๋์ง ์๊ธฐ๊ฐ ์ฝ์ง ์์ต๋๋ค.์๋ฒ์ api๋ฅผ ์ฌ์ฉํ๋ ํด๋ผ์ด์ธํธ์ธก์ด ํน์ ์ค๋ฅ์ผ ๊ฒฝ์ฐ ๋ณ๋ ์ฒ๋ฆฌ๋ฅผ ํด์ผํ๋ค๊ณ ํ์ ๋ http status๋ง์ผ๋ก๋ ํ์ธ์ด ์ด๋ ต์ต๋๋ค. ๋ํ ์ค๋ฅ๋ฉ์ธ์ง๋ก ์์ธ ์ฒ๋ฆฌ๋ฅผ ํ๋ค๋ฉด ์ค๋ฅ ๋ฉ์ธ์ง๊ฐ ๋ฐ๋ ๊ฒฝ์ฐ ๋์์ด ๋ถ๊ฐ๋ฅํฉ๋๋ค.๋ฐ๋ผ์ ์ค๋ฅ ๋ฉ์ธ์ง์๋ ๋ณ๊ฐ๋ก ์ค๋ฅ ์ฝ๋๋ฅผ ๊ด๋ฆฌํ๋ค๋ฉด ํด๋ผ์ด์ธํธ์์๋ ๋์ํ๊ธฐ ํจ์ฌ ํธํฉ๋๋ค. ๊ณ ๊ฐ์ด ์ค๋ฅ๊ฐ ๋ฐ์ํ์ ๋ ์ค๋ฅ ์ฝ๋๋ฅผ ์ค๋ค๋ฉด ํด๋น ์ค๋ฅ ์ฝ๋๋ฅผ ๋ฐ์์ํค๋ ์ฝ๋๋ฅผ ์ฝ๊ฒ ์ฐพ์ ์๋ ์์ต๋๋ค. http status์ ํ์ฌ๋ ๊ฐ ์ค๋ฅ๋ง๋ค ์ด๋ค http status๋ฅผ ๋์ ธ์ผํ ์ง๋ฅผ ์ ์ํ๊ณ ์์ง๋ง enum ์์ http status๋ ๊ด๋ฆฌํ์ง ์๊ณ AuthenticationException ์ด๋ฉด ํญ์ 401, BusinessException์ด๋ฉด 500, EntityNotFoundException๋ฉด 400 ๋ฑ ์์ธ๋ก๋ ๊ด๋ฆฌํ ์ ์๊ณ ์ํฉ์ ๋ง๊ฒ ๊ด๋ฆฌ๋ฅผ ํ์๋ฉด ๋ฉ๋๋ค.
- 0
- 2
- 44
Q&A
ํ ํฐ ๋ฐ๊ธ ๊ด๋ จ ๋ฌธ์ ๋๋ฆฝ๋๋ค.
์๋ ํ์ธ์! ์นด์นด์ค๊ฐ๋ฐ์ ์ผํฐ์ ๊ณต์ ๋ฌธ์์์๋ ํ ํฐ ๋ฐ๊ธ api ์์ฒญ ์ content-type์ "application/x-www-form-urlencoded;charset=utf-8" ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ผ๊ณ ๋์ด์์ต๋๋ค. ๋ง์ํด์ฃผ์ @RequestBody, @ModelAttribute ๋ฑ ์ผ๋ก ํธ์ถํด๋ณด์๋ฉด ์์๊ฒ ์ง๋ง ์นด์นด์ค ์๋ฒ์์ ์ฒ๋ฆฌํ ์ ์์ด์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒ์ ๋๋ค.content-type์ "application/x-www-form-urlencoded;charset=utf-8" ๋ก ์ ๋ฌํ๋ค๋ ๊ฒ์ http ๋ฉ์ธ์ง๋ฅผ ์๋์ ์์์ฒ๋ผ ๋ณด๋ธ๋ค๋ ๊ฒ ์ ๋๋ค.body ๋ณธ๋ฌธ์ ๋ณด์๋ฉด ์ฟผ๋ฆฌํ๋ผ๋ฏธํฐ์ฒ๋ผ key1=value1&key2=value2 ์ฒ๋ผ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๊ณ ์๋๋ฐ ์ด ๋ฐฉ์์ด ๋ฐ๋ก "application/x-www-form-urlencoded;charset=utf-8" ๋ก ๋ณด๋ด๋ ๋ฐฉ์์ ๋๋ค. POST /oauth/token HTTP/1.1Host: https://kauth.kakao.comContent-Type: application/x-www-form-urlencoded grant_type=authorization_code&client_id=123456&redirect_uri=http://localhost:8080/oauth/kakao/callback&client_secret=1234&code=123452 ๋ฐ๋ผ์ ์นด์นด์ค API ์๋ฒ์์ ์ง์ํ์ง ์๋ http ๋ฉ์ธ์ง ํ์์ผ๋ก ๋ณด๋ธ๋ค๋ฉด ํด๋น ์๋ฒ์์ ์ฒ๋ฆฌ๋ฅผ ํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์๋ ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์์๋ก ์ฃผ์ จ๋ ์ฝ๋์ ๊ฒฝ์ฐ consumes์ APPLICATION_FORM_URLENCODED_VALUE ๋ฅผ ์ง์ ํด์ฃผ์ จ๋๋ฐ consume์ ๊ฒฝ์ฐ ์ฐ๋ฆฌ ์๋ฒ๊ฐ ๋ฐ์ contenty-type์ ๋ช ์ํฉ๋๋ค.APPLICATION_FORM_URLENCODED_VALUE์ ์ ํฌ๊ฐ ์นด์นด์ค๋ก ๋ณด๋ผ ๋ฐ์ดํฐ ํ์ ์ด๊ตฌ์!@PostMapping(value = "/oauth/token", consumes = APPLICATION_FORM_URLENCODED_VALUE)KakaoTokenResponse requestKakaoToken(@RequestBody KakaoTokenRequest request); ์๋์ฒ๋ผ ์นด์นด์ค ์๋ฒ๋ก ๋ถํฐ ๋ฐ๋ ์๋ต์ application/json์ผ๋ก ์์ ํ ์์ฒญ ํ๋ค๊ณ ํ์ ๋ @RequestBody์ ๊ฒฝ์ฐ request์ ๋ฐ์ดํฐ๋ฅผ http body์ json์ผ๋ก ์ ๋ฌํฉ๋๋ค.@PostMapping(value = "/oauth/token", consumes = "application/json")KakaoTokenResponse requestKakaoToken(@RequestHeader("Content-Type") String contentType, @RequestBody KakaoTokenRequest request);http ๋ฉ์ธ์ง๋ ์๋ ์์์ฒ๋ผ ์ ์ก์ด ๋ ๊ฒ์ ๋๋ค. ์ด๋ฒ์๋ http body์ ๋ฐ์ดํฐ ํ์์ด key1=value1 ํ์์ด ์๋๋ผ json์ผ๋ก ์ ์ก์ด ๋ ๊ฒ์ด๊ณ ์นด์นด์ค ์๋ฒ์์๋ "application/x-www-form-urlencoded" ํํ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ผ๊ณ ํ๋๋ฐ ์ ํฌ๊ฐ ๋ง์๋๋ก ๋ฐ์ดํฐ๋ฅผ json ํ์์ผ๋ก ๋ณด๋ด๊ฒ ๋๊ฒ์ด๊ตฌ์! ๊ทธ๋์ ํด๋น ์๋ฒ๊ฐ ๋ฉ์ธ์ง๋ฅผ ์ ์์ ์ผ๋ก ์ฝ์ ์ ์์ด์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒ ์ ๋๋ค. POST /oauth/token HTTP/1.1Host: https://kauth.kakao.comContent-Type: application/json {"grant_type": "authorization_code","client_id": "123123123123","redirect_uri": "http://localhost:8080/oauth/kakao/callback","code": "123123123123123","client_secret": "3124123123123"} @ModelAttribute์ ์๋ฌด ์ด๋ ธํ ์ด์ ๋ ์ฌ์ฉํ์ง ์๊ณ ๋ณด๋์ ๋๋ ๋๋ค json ํํ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๊ฒ์ผ๋ก ๋ก๊ทธ๋ฅผ ํ์ธํ๊ณ application/json์ ์นด์นด์ค ํ ํฐ ๋ฐ๊ธ api์์ ์ฒ๋ฆฌํ ์ ์์ด์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.@PostMapping(value = "/oauth/token", consumes = "application/json")KakaoTokenResponse requestKakaoToken(@ModelAttribute KakaoTokenRequest request); @PostMapping(value = "/oauth/token", consumes = "application/json")KakaoTokenResponse requestKakaoToken(KakaoTokenRequest request);
- 0
- 2
- 69
Q&A
์ด ํ๋ฆ์ด ๋ง์๊น์??
์๋ ํ์ธ์! ์ดํดํ ๋ด์ฉ์ด ๋ง์ต๋๋ค! ๋จผ์ ์นด์นด์ค๋ก๋ถํฐ ์นด์นด์ค์๋น์ค๋ฅผ ์ด์ฉํ๊ธฐ ์ํ ํ ํฐ์ ๋ฐ๊ธ ํ ์นด์นด์ค์ ๋ฑ๋ก๋ ํ์ ์ ๋ณด๋ฅผ ์ด์ฉํ์ฌ ์ฐ๋ฆฌ ์๋น์ค์ ํ์ ๊ฐ์ ๋ํ๊ณ , ์ด๋ฏธ ๊ฐ์ ๋ ๊ฒฝ์ฐ๋ผ๋ฉด ํ์ ๊ฐ์ ์ ์ฐจ ์์ด JWT๋ฅผ ๋ฐ๊ธํฉ๋๋ค.JWT์๋ ์ธ์ฆ ์ ๋ณด๊ฐ ๋ด๊ฒจ์ ธ์๊ธฐ ๋๋ฌธ์ Authorizaion Header์ ๋ฃ์ด์ ์ ์กํ๋ฉด ์ธ์ฆ์ด ํ์ํ API์ ๊ฒฝ์ฐ ํ ํฐ์ ๊ฒ์ฌํ์ฌ ์ ์์ ์ธ ํ ํฐ์ด๋ผ๋ฉด ์์ฒญํ API๋ฅผ ์ํํฉ๋๋ค.
- 0
- 2
- 84
Q&A
OpenFeign์ ์ด๋ค ์ํฉ์์ ์ด๋ป๊ฒ ์ฌ์ฉํ๋์ง ๊ฐ์ด ์์ต๋๋ค...
์๋ ํ์ธ์! ์ค์ ์๋น์ค๋ฅผ ๋ง๋ค๋ค๋ณด๋ฉด ์ธ๋ถ API๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ์๋ฅผ ๋ค์ด์ ๋ค์์ ๊ตฌํํ๋ ์์ ๋ก๊ทธ์ธ์ ๊ฒฝ์ฐ๋ ์นด์นด์ค API๋ฅผ ํธ์ถํด์ผํ๊ธฐ ๋๋ฌธ์ feign client๋ฅผ ํตํด์ API๋ฅผ ์์ฒญํ๊ณ ์๋ต์ ๋ฐ์์ ํ์ฉํฉ๋๋ค. ์ค๋ฌด์์๋ ํํ์ฌ์ ํ์ ์ํ๊ฒ ๋๋ค๋ฉด ํ ํ์ฌ๊ฐ ์ ๊ณตํ๋ API๋ฅผ ํธ์ถํด์ผํ๋ ์ผ์ด์ค๋ ๋น๋ฒํ๊ตฌ์! ๊ท๋ชจ๊ฐ ์ด๋์ ๋ ๋๋ ํ์ฌ๋ผ๋ฉด ๋จ์ผ ์ดํ๋ฆฌ์ผ์ด์ ์ด ์๋๋ผ ๋๋ฉ์ธ๋ณ๋ก ์๋ฒ๋ ๋ถ๋ฆฌ๋์ด ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง์๋ฐ ๊ทธ๋ด ๊ฒฝ์ฐ ๋ด๋ถ ์๋ฒ๊ฐ ํต์ ์๋ ํ์ฉํฉ๋๋ค.
- 0
- 2
- 140
Q&A
5:23๋ถ ํ ์คํธ ๊ฒฐ๊ณผ ๊ด๋ จ ๋ฌธ์๋๋ฆฝ๋๋ค.
์คํ๋ง๋ถํธ ๋ฒ์ ์ด ์ฌ๋ผ๊ฐ๋ฉด์ ์๋ API๋ฅผ ํธ์ถํ ๊ฒฝ์ฐ NoResoucrFoundException ์์ธ๋ฅผ ๋ฐ์์ํค๋๋ก ๋ฐ๋๊ฑฐ ๊ฐ์ต๋๋ค. NoResoucrFoundException์ ๋ฐ๋ก ExceptionHandler๋ก ์ฒ๋ฆฌ ํด์ฃผ๊ณ ์์ง ์์์ Exception์ ์ฒ๋ฆฌํ๋๊ณณ์์ ์ฒ๋ฆฌ๊ฐ ๋์ต๋๋ค. GlobalExceptionHanlder์ ์๋ ์์ธ๋ฅผ ์ถ๊ฐํด์ฃผ๋ฉด 404๋ก ์ค๋ฅ๋ฅผ ๋ฐํํ ๊ฒ ์ ๋๋ค.@ExceptionHandler(NoResourceFoundException.class) protected ResponseEntity handleNoResourceFoundException(NoResourceFoundException e) { log.error("NoResourceFoundException", e); ErrorResponse errorResponse = ErrorResponse.of(NOT_FOUND.toString(), "Requested resource not found."); return ResponseEntity.status(NOT_FOUND).body(errorResponse); } ๊ทธ๋ฆฌ๊ณ ExceptionHandler๊ฐ ๋จผ์ ์ํ๋๋๊ฑด ์๋ฒ ์๊ธฐ ์์ ํํ ์์ฒญํ๊ธฐ ๋๋ฌธ์ ์์ ํํ ์๋ API์ด๊ธฐ ๋๋ฌธ์ GlobalExceptionHandler์์ ๋จผ์ ์ฒ๋ฆฌ๋ฅผ ํ๊ณ , FeignClientExceptionErrorDecoder ์์๋ ์๋ฌ ์๋ต์ ๋ฐ์ ํ ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ 2๋ฒ์งธ๋ก ์ฒ๋ฆฌ๊ฐ ๋์ต๋๋ค. 8081 ์๋ฒ๋ฅผ ํ๋ ๋ ๋์ฐ๊ณ (์ฌ์ง)8081 ์๋ฒ๋ก /api/health2 ๋ฅผ ์์ฒญํ๋ค๋ฉด 8080์๋ฒ์์๋ ExceptionHandler์์ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ์ํ๊ณ , FeignClientExceptionErrorDecoder์์๋ง ์๋ฌ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค. 8081 ์๋ฒ๋ GlobalExceptionHandler์์ ์ค๋ฅ ๋ก๊ทธ๋ฅผ ๋จ๊ธฐ๊ณ ๋ฐํํ ์ค๋ฅ ์๋ต์ ๋ง๋ค ๊ฒ ์ ๋๋ค.(์ฌ์ง)
- 0
- 3
- 146
Q&A
5:23๋ถ ํ ์คํธ ๊ฒฐ๊ณผ ๊ด๋ จ ๋ฌธ์๋๋ฆฝ๋๋ค.
์๋ ํ์ธ์ ์ง์๋! ๊ฐ์ ์ ๋ฃ๊ณ ๊ณ์ ๊ฐ์ฌํฉ๋๋ค!ํน์ ๊นํ๋ธ๋งํฌ๋ฅผ ๋จ๊ฒจ์ฃผ์ค ์ ์์ผ์ค๊น์?
- 0
- 3
- 146
Q&A
๋๋ฉ์ธํ ํจํค์ง ๊ตฌ์กฐ ์ง๋ฌธ
์๋ ํ์ธ์! ๋๋ฉ์ธ ์ฃผ๋ ๊ฐ๋ฐ์ด๋ผ๊ณ ํด์ ๊ผญ ํน์ ํจํค์ง ๊ตฌ์กฐ๋ก๋ง ํด์ผ ๋๋ฉ์ธ ์ฃผ๋ ๊ฐ๋ฐ์ธ ๊ฒ์ ์๋๊ธดํด์ ๋งํ๊ธฐ ์กฐ์ฌ ์ค๋ฌ์ด ๋ถ๋ถ์ด ์๊ธดํ๋ค์! ๋จ์ํ controller / service/ dto ๊ธฐ๋ฐ์ผ๋ก ํ๋ฉด๋จ์๋ก ๊ฐ๋ฐํ๋๊ฒ๋ณด๋ค๋ ๋๋ฉ์ธ ์ฃผ๋ ๊ฐ๋ฐ์ชฝ์ ๊ฐ๊น๋ค๊ณ ๋ ์๊ฐํฉ๋๋ค.
- 0
- 1
- 186