목차
완벽한 정리가 목적이 아니고, 로드맵을 보면서 기본 개념을 알고 차후 파고들어서 공부하기 위한 사전 준비 과정인 스터디이다. 따라서 이하 정리한 내용이 부실할 수 있습니다.
Learn about APIs
HATEOAS
⚈ HATEOAS is an acronym for Hypermedia As The Engine Of Application State, it's the concept that when sending information over a RESTful API the document received should contain everything the client needs in order to parse and use the data i.e they don't have to contact any other endpoint not explicitly mentioned within the Document
⚈ 요청에 필요한 URI를 응답에 포함시켜 반환하는 것.
- 기존 API 리턴
{
"orderId" : "42",
"state" : "AWAITING_PAYMENT"
}
- HATEOAS 적용 API 리턴 (Spring HATEOAS 적용 시 리턴되는 형태로, application/hal+json 형태임)
{
"orderId" : "42",
"state" : "AWAITING_PAYMENT",
"_links" : {
"self" : {
"href" : "http://localhost/orders/999"
},
"payments" : {
"href" : "/payments/42"
}
}
}
⚈ HATEOAS는 일종의 개념이고, 이걸 위한 표준 방식 중 하나가 HAL(Hypertext Application Language)
- application/hal+json
- application/hal+xml
Open API Spec and Swagger
⚈ OpenAPI
- OpenAPI Specification (OAS). RESTful API의 API 스펙을 규칙에 맞게 json이나 yaml로 표현하는 표준
- Swagger의 현재 이름을 뜻하기도 함. (Swagger에서 변경됨)
⚈ Swagger
- OpenAPI 스펙을 맞춘 api-docs를 이용하여 html 페이지로 문서화해주는 프레임워크
⚈ Spring Boot Swagger 3.0.0 적용하기
- OpenAPI 3.0 적용 = Swagger 3.0 적용
- 링크 (springfox로 적용한 글임)
⚈ Spring REST Docs도 있음 -> 찾아보기
⚈ springfox랑 springdoc이랑 다른거임.
- 둘 다 스프링에 적용하기 위한 라이브러리인데, 처음엔 springfox만 있다가 중간에 springdoc도 나옴. 둘 다 스웨거를 쓸 수 있는 라이브러리지만 스프링에 적용할 때 코드에 차이가 있으니, 모른다면 구글링으로 스웨거 적용 시 맞왜틀을 외치게 될 수 있음.
- springfox쪽이 좀 더 사용량이 높은듯.
REST
⚈ REpresentational State Transfer
⚈ 자원을 이름으로 구분하여 해당 자원의 상태(정보)를 주고 받는 모든 것을 의미한다.
- 자원을 요청하는 쪽이 Client
- 자원이 있는 쪽이 Server
⚈ HTTP URI를 통해 자원(리소스)를 명시하고, HTTP Method(POST, GET,...)을 통해 해당 자원에 대한 행동을 적용한다.
⚈ REST API
- REST 기반으로 서비스 API를 구현하는 것
- RESTful : REST 원리를 따르는 시스템
- CRUD 기능을 모두 POST로만 처리하는 API라면 RESTful 하지 않다.
⚈ REST API 설계 기본 규칙
- URI는 정보의 자원을 표현해야 한다.
- 자원에 대한 행위는 HTTP Method로 표현한다.
- GET /members/delete/1 (X) -> DELETE /members/1 (O)
- '/'는 계층 관계를 나타내는데 사용
- '_'은 사용하지 않는다.
- '-'은 가독성을 높이는데 사용
- URI에 대문자의 사용은 피한다
- 파일 확장자는 URI에 포함하지 않는다.
SOAP
⚈ Simple Object Access Proctocol
⚈ HTTP, HTTPS, SMTP등을 통해서 XML 기반의 메시지를 컴퓨터 네트워크상에서 교환하는 프로토콜
⚈ RESTful 보다 규격화 되있어서 사용환경, 플랫폼에 구애를 안받는다고 함.
Authentication
Authentication
⚈ 쿠키/세션 기반
- 클라이언트에서 로그인
- 서버가 사용자 검증 후 유효하다면 고유 ID을 부여하여 세션 저장소에 저장 후 이와 연결되는 세션 ID를 생성하여 응답 헤더에 포함시켜 반환
- 클라이언트는 서버에서 리턴한 세션id를 쿠키에 저장 후 필요할 때마다 요청 헤더에 포함시켜 보냄
- 서버에서는 쿠키를 받아 세션 저장소에서 검증 후 응답
- 장점 : 세션 ID로 사용자를 구분할 수 있으므로 하나하나 사용자 정보를 확인할 필요 없음
- 단점 : 세션을 저장하므로 사용자 수가 많아지면 서버 부담이 늘어남. 여러 서버 컴퓨터를 추가 시 어려워짐. 여러 도메인에서 관리하기 번거로움
⚈ 토큰 기반
- 미리 토큰을 가지고 있는 경우 클라이언트에서 요청 보낼 시 토큰 포함
- 서버에서는 토큰 검증해서 응답 보냄.
- 클라이언트에서 로그인 시 토큰을 발행해주는 방식도 사용 가능.
- Stateless. 상태정보를 유지하지 않는다. 서버가 전달받은 토큰을 검증만 함
- 장점 : 서버의 상태를 유지할 필요가 없으므로 서버에 부하가 적고 확장성이 높음
- 단점 : 토큰이 해킹 당한 경우가 단점. (그래서 보통은 Access Token은 20~30분으로 짧게 두고, 재발급을 위한 Refresh Token도 함께 발급)
⚈ JWT vs OAuth
- JWT는 토큰의 종류
- OAuth는 토큰을 발급하고 인증하는 오픈 스탠다드 프로토콜
- 스프링 부트 JWT 적용 예시 : 내 github
⚈ 인증, 인가
- 인증(Authentication) : 사용자가 누구인지 확인하는 절차 (회원가입을 하고 로그인하게 하는 것)
- 인가(Authorization) : 사용자에 사용 권한을 허락해 주는 절차 (로그인 후 이뤄지는 사용자의 행위에 대해 허가해 주는 것)
⚈ SAML, Oauth, OpenID
- SAML : 개방형 인증과 인가의 표준. SSO를 하기 위한 목적으로 XML로 개발된 기술. OAuth와 관련 없음. 주로 기업 사용자가 단일 로그인을 사용해 다수의 어플리케이션에 로그인하는 데 사용됨.
- OAuth : 개방형 인가의 표준. API 연동 및 허가를 위한 목적으로 json으로 개발된 기술
- OpenID : 개방형 인증의 표준. 주로 컴슈머 어플리케이션(앱스토어나 구글 플레이스토어에 올라와 있는 앱) 간의 sso 인가를 위한 목적. OAuth 2.0 상위에 구축된 인증 계층으로 JWT를 활용함.
⚈ Access Token(OAuth) vs ID Token(OpenID)
- Access Token : OAuth에서 발급. 해당 토큰을 이용해 유저 프로필 정보에 대한 접근 요청을 보내야함
- ID Token : OpenID에서 발급. 별도의 요청 필요 없이 해당 토큰을 디코드하여 유저 프로필에 대한 정보를 바로 획득 가능
Caching
CDN
⚈ Content Delivery Network
⚈ 사용자가 인터넷상에서 가장 가까운 곳의 서버로 컨텐츠를 전송받아 트래픽이 특정 서버에 집중되지 않고 각 서버로 분산되도록 하는 기술
Server Side
⚈ Local Cache
- 서버마다 캐시를 따로 저장
- 로컬 서버의 리소스 사용
- 서버 내에서 작동하므로 속도가 빠름
- 다른 서버의 캐시를 참조하기 어려움
⚈ Global Cache
- 캐시 서버를 따로 두는 것(레디스 등)
- 여러 서버에서 캐시 서버를 참조
- 네트워크 트래픽을 사용하므로 로컬 캐시보다는 느림
- 서버간 데이터 공유가 쉬움
⚈ 캐싱 적용 대상
- 반복적이고 동일한 결과가 나오는 기능(업데이트가 자주 발생하지 않는)의 반환값. 즉 입력값과 출력값이 일정한 데이터
- 자주 조회되는 데이터
⚈ Redis
- key-value 형태로 데이터를 저장하는 인메모리 NoSQL DB
- 유투브 조회수처럼 매번 업데이트 치기 부담스러운 부분에 대해 lazy propagation을 위해 쓰거나, 캐싱을 위해 사용
- 매우 빠르게 동작한다는 점(인메모리라서)을 사용해 메시지 큐잉에도 사용 가능
⚈ 레디스 스프링부트 적용
- @EnableCaching
- RedisCacheManager 빈 등록 후 적용할 곳에 @Cacheable
⚈ Memcached
- 레디스랑 비슷하지만 세부적으로 좀 차이가 있음. 레디스가 더 기능이 많은편.
Client Side
⚈ 로컬 스토리지는 자동 로그인을 생각하면 되고, 세션 스토리지는 비로그인 장바구니를 생각하면 됨.
쿠키의 경우, HTTP.는 기본적으로 요청-응답이 끝나면 연결이 끊어지는 무상태성이 특징임. 따라서 클라이언트의 상태를 서버가 아닌 클라이언트에 저장해두고 필요 시 서버에 전달해 보완해야함.
기본 로직은 '클라가 서버에 HTTP 요청 -> 서버가 응답 시 쿠키 전달 -> 클라이언트는 이후 쿠키를 담아 보냄' 임.
스프링, 스프링부트의 경우 외장 혹은 내장 톰캣에서 이 쿠키를 처리해줌. 그래서 스프링에서 별도로 사용자 정보를 유지하지 않아도 로그인을 페이지 변경될때마다 다시 안해도 됨.
Web Security Knowledge
Hashing Algorithms
⚈ 암호화 vs 해싱
- 암호화는 양방향 암호화로 전송중 데이터를 보호하기 위한 것 (대표적으로 AES)
- 해싱은 단방향으로 파일 및 데이터가 변경되지 않았음을 확인하기 위한 것. 복호화가 불가능.
⚈ 해싱의 충돌
- 해싱 시 두 개의 서로 다른 파일이 동일한 해시값을 생성하는 경우임. 두 개를 구분할 수 없으므로 충돌.
⚈ 단방향 vs 양방향
- 단방향(해싱) : 입력값이 동일하면 동일한 출력값이 나올 뿐, 복호화는 불가능. (대표적으로 SHA) 예시는 DB에 비밀번호 저장할 때 생각하면 됨.
- 양방향(암호화) : 키가 있다면 복호화 가능. 암호화해서 전송하고, 받은쪽에서 복호화해서 해석 가능 (대표적으로 AES)
- 양방향에는 대칭키, 비대칭키가 있음. 대칭키는 암호화키 = 복호화키, 비대칭키는 암호화키 != 복호화키
- 양방향 예시 : 이하는 AES를 사용해 download 가능한 키값을 넣어둔 형태. 서버에서는 키값을 받아 복호화해서 파일을 제공
⚈ MD5
- Message-Digest Algorithm 5
- 임의의 길이의 값을 입력받아 128비트 길이의 해시값을 출력하는 알고리즘.
- 속도가 빨라서 무차별 대입이나 사전 공격에 취약해서 잘 안쓰임. -> 단 암호화 변경 시 전체적인 기존 인프라 변경의 문제로 현재로 종종 사용됨.
⚈ SHA Family
- 미국 NSA에서 설계한 암호화 해시 함수
- GPU를 이용한 암호화
- 따라서 연산속도가 매우 빠르므로 오프라인 brute force에 더 취약하다.
⚈ scrypt
- 2009년에 나옴
- 오프라인 brute force 공격에 더 강력하지만 많은 메모리와 CPU를 사용함
- OpenSSL 1.1 이상을 제공하는 시스템에서만 동작
⚈ bcrypt
- 1999년 나옴
- blowfish 암호를 기반으로 설계된 암호화 함수
⚈ 해싱 선택 (비밀번호 암호화 시)
- SHA, MD5는 brute force에 취약
- ISO-127001 보안 규정을 준수해야할 상황이라면 PBKDF2 사용
- 일반적으로는 구현이 쉽고 비교적 강력한 bcrypt
- 보안 시스템을 구현하는데 많은 비용을 투자할 수 있다면 scrypt
HTTPS, SSL, TLS
⚈ HTTPS = HTTP + 추가 보안 계층 (TLS. 전송 계층 보안)
⚈ SSL이나 TLS 인증서로 보호되는 통신. 사실상 현재는 TLS로 보호되는 경우임.
⚈ SSL
- v1 : 결함으로 공개된 적 없음
- v2 : 1995년 공개, 2011 사용 금지
- v3 : 1996년 공개, 2015 사용 금지
⚈ TLS
- SSL 좀 더 향상 시킨건데, SSL이 더 보편적인 단어라 SSL이라고 하기도 함.
- v1.0 : SSL v3이 가진 취약점 해결. 1999 공개, 2020까지만 사용
- v1.1 : 2006년 공개, 2020년까지만 사용
- v1.2 : 2008년 공개, 현재 대부분의 사이트에서 지원
- v1.3 : 2018년 공개. 최초 연결시에 암호화 통신 개시 절차 간소화, 오래된 암호화 기술(Cipher Suites) 폐기
⚈ Cipher Suites
CORS, CSP, OWASP
⚈ CORS
- 동일한 오리진 끼리만 데이터를 송수신할 수 있다. 프론트에서 자체적으로 해결 가능한 경우도 있지만, 일반적으로 서버에서 화이트리스트로 관리해주는 것이 맞다. CrossOrigin 어노테이션 혹은 WebMvcConfigurer를 implements해서 addCorsMappings의 registry.allowedOrigins()에 화이트 리스트를 추가할 수 있다.
⚈ CSP
- Content Security Policy, 콘텐츠 보안 정책
- 교차 사이트 스크립팅(XSS) 공격과 데이터 삽입 공격을 막기 위한 추가적인 브라우저 보안 계층
- 웹 서버의 응답 헤더에 아래와 같은 방식으로 CSP 헤더를 추가하도록 설정해서 사용 가능.
// 모든 콘텐츠는 현재 도메인에서만 제공되어야 한다.
Content-Security-Policy: default-src 'self'
// 신뢰할 수 있는 특정 도메인과 그것의 모든 하위 도메인의 콘텐츠를 허용한다.
Content-Security-Policy: default-src 'self' *.trusted.com
// 이미지는 모든 도메인, 미디어와 스크립트는 특정 도메인만 허용한다.
Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com
- 위 헤더를 전달받은 사용자의 브라우저는 1. 유효한 도메인으로 지정된 도메인의 스크립트만 실행하여 XSS 위험성을 제거, 2. 허용 목록에 있는 도메인에서 수신한 스크립트만 실행하여 그 외 스크립트는 무시.
⚈ OWASP
- Open Web Application Security Project
- 오픈소스 웹 어플리케이션 보안 프로젝트. 주로 웹에 관한 정보노출, 악성 파일 및 스크립트, 보안 취약점 등을 연구
- OWASP TOP 10 : 웹 어플리케이션 취약점 중에서 빈도가 많이 발생하고, 보안상 영향을 크게 줄 수 있는 10가지를 선정해 발표.
- 인젝션
- 취약한 인증
- 민감함 데이터 노출
- XML 외부 개체(XXE)
- 취약한 접근 통제
- 잘못된 보안 구성
- 크로스 사이트 스크립팅(XSS)
- 안전하지 않은 역직렬화
- 알려진 취약점이 있는 구성요소 사용
- 불충분한 로깅 및 모니터링
Testing
⚈ Integration Testing
- 개발된 각 컴포넌트를 통합하면서 발생할 수 있는 버그를 확인. 개별 컴포넌트만 테스트할 때는 확인할 수 없는 부분을 확인하기 위한 테스트
- 여러 모듈이 의도대로 협력하는지 확인하는 테스트
⚈ Unit Testing
- 단위 기능에 대해 확인하는 테스트. 개발자가 작성한 함수의 기능 하나 하나를 테스트한다. 따라서 코드를 가장 잘 이해하고 있는 코드 작성자가 주로 테스트를 진행한다.
- 응용 프로그램에서 테스트 가능한 가장 작은 소프트웨어를 실행하여 예상대로 동작하는지 확인
⚈ Functional Testing
- 소프트웨어의 기능을 확인하는 테스트
- 모든 코드가 함께 실행되는 상태에서 전체 어플리케이션의 기능을 확인하는 테스트
References
https://joomn11.tistory.com/26
https://stackoverflow.com/questions/25819477/relationship-and-difference-between-hal-and-hateoas
https://docs.spring.io/spring-hateoas/docs/current/reference/html/
https://etloveguitar.tistory.com/58
https://gruuuuu.github.io/programming/openapi/
https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html
https://dydals5678.tistory.com/4
http://blog.kimssoft.com/2017/05/blog-post_24.html
https://tecoble.techcourse.co.kr/post/2021-05-25-unit-test-vs-integration-test-vs-acceptance-test/
https://deveric.tistory.com/71
https://brunch.co.kr/@skykamja24/575
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=ucert&logNo=221434347680
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=vjhh0712v&logNo=221447601982
https://brunch.co.kr/@sangjinkang/43
https://ko.wikipedia.org/wiki/OWASP
https://jeonyoungho.github.io/posts/JWT%EC%99%80-OAuth%EC%9D%98-%EA%B4%80%EA%B3%84/
https://yeonyeon.tistory.com/264
https://www.okta.com/kr/identity-101/whats-the-difference-between-oauth-openid-connect-and-saml/
'Study > Backend Roadmap' 카테고리의 다른 글
[roadmap.sh] Backend 4주차 정리 (0) | 2022.12.10 |
---|---|
[roadmap.sh] Backend 2주차 정리 (0) | 2022.11.26 |
[roadmap.sh] Backend 1주차 정리 (0) | 2022.11.19 |
댓글