웹 개발의 정석인 mozilla를 참고하자!
(MIME type, Media type와 비슷하다고 할 수 있다)
참고 reference
content-type header 영상
Content-type -HTTP 링크
content-type이 쓰이게 된 이유: 텍스트 파일 변환(binary 파일) 링크
content type 링크
MIME type은 파일의 형식을 나타내는 문자열로 파일과 같이 송신되는데 content의 형식을 나타내기 위해 사용한다. 예를 들면 오디오 파일은 audio/ogg로 그림 파일은 image/png로 분류할 수 있다.
http 프로토콜로 데이터를 보낼 떄 서버가 이해할 수 있는 것. 이를 모르면 전달하는 데이터 형식이 변할 떄 왜 오류가 발생했는지 모른다.
목적: 이에 대한 이해가 있으면 서버와 커뮤니케이션하는 데이터에 대해 빠르게 맞추고 해결한다.
웹브라우저에서는 HTTP 통신으로 데이터를 수신받을 때, 어떠한 데이터가 올 지 모르기 떄문에 웹브라우저가 서버로부터 수신받을 떄, content-type header에 무엇을 기대할지 알려준다. 데이터를 어떻게 처리(분석, 파싱, 처리)해야 할 지 판단.
- 예를 들어, 웹 페이지 수신받을 때 HTML인지 CSS, JS인지 모른다.
수신받을 때, content-type과 파일 확장자(file extension)의 결합으로 합리적으로 추츤한다.
- 같은 CSS도 Json으로 받으면 적용이 안된다.
HTTP메소드에 POST, PUT처럼 Body에 data를 보낼때 Content-Type이 필요하다. 특정 data(img, viedo 등)를 Content-Type없이 보내면 data를 받는 쪽에서는 단순 텍스트 데이터로 받는다.
서버에 요청을 보낼 떄도 사용된다!
- 예를 들어, request로 Json형태를 보낼 때, header에 application/json으로 표시한다.
- 요청 내에서, (POST 혹은 PUT처럼), 클라이언트는 서버에게 어떤 유형의 데이터가 실제로 전송됐는지를 알려줍니다.
HTML 폼 전송으로 일어나는 POST 요청 내에서, 요청의 Content-Type은 form 요소 상의 enctype 속성에 의해 지정됩니다.
<form action="/" method="post" enctype="multipart/form-data">
<input type="text" name="description" value="some text">
<input type="file" name="myFile">
<button type="submit">Submit</button>
</form>
참고 서버사이드 렌더링 영상
1990년 대까지만 해도 static site. HTML 만 사용. 단점: HTML 문서 통째로
1996년부터는 iframe 태그로 부분적으로만 받아올 수 있다.
1998부터: XMLHttpRequest API 개발 => JSON과 같은 포맷으로 서버에서 가볍게 필요한 데이터만 받아온다.
2005: 위 방식이 AJAX라는 공식적인 방법으로. 이 방식으로 웹 애플리케이션 개발. 이것이 바로 SPA(싱글 페이지 어플리케이션) => 한 페이지에 머무르면서 필요한 부분만 부분적으로 업데이트 => 웹 사용성 향상
CSR(클라이언트 사이드 랜더링= 약간 인터페이스 느낌??): pc 성능 향상, JS 프레임워크의 발전으로 도입
- 서버에서 다 처리하는 것을 말한다.
SSR(서버 사이드 랜더링): 웹사이트에 접속하면 서버에서 필요한 데이터들을 모두 가져온다.
SSR의 3번째 단점을 이해하려면 TTV(Time to view), TTI(time to interact)을 이해할 필요가 있다. TTV는 사이트를 볼 수 있는 시간, TTI는 사용자와 인터렉션할 수 있는 시간
- CSR은 TTV와 TTI가 동시에. SSR은 TTV가 먼저, TTI는 이 후에.
==> CSR은 일단 필요한 부분만 먼저, SSR은 단차를 어떻게 좁힐 지 고민하라.
SSG(Static Site Generation):
- 리액트는 CSR에 최적화된 프레임워크지만, Gatsby와 함께 활용하면 리액트로 만든 애플리케이션을 정적으로 미리 만들어서 서버에 배포해놓을 수 있다. 동적인 요소도 물론 함께 추가 가능
- Next.js(갯츠비 다음으로 많이 사용): 강력한 SSR을 지원. 요즘에는 SSG, CSR+SSR 지원
===> 어떤 것이 정답이기보다는 우리 사이트가 정적/동적인지, 얼마나 자주, 많은 사용자가 있는지에 따라 유연하게 섞으면서 개발해나가시라.
Exception 예외 클래스의 계층 구조
Exception 구조
- 대부분 super(). throwable에서 처리한다.
Throwable 구조
- 해당 클래스 타입의 이름과 msg 출력
HttpStatus
enum 클래스이다. 이는 서로 관련있는 상수들을 모아 심볼릭한 명칭의 집합으로 정의한 것, 즉 클래스처럼 보이게 하는 상수
series는 어떤 타입의 에러인지를 나타낸다.
해당 에러코드의 의미를 나타내는 resasonPhrase
public class DanielException extends Exception {
// 직렬화를 위한
private static final long serialVersionUID = 42577772L;
private Constants.ExceptionClass exceptionClass;
private HttpStatus httpStatus;
public DanielException(Constants.ExceptionClass exceptionClass, HttpStatus httpStatus,
String message) {
super(exceptionClass.toString() + message);
this.exceptionClass = exceptionClass;
this.httpStatus = httpStatus;
}
public Constants.ExceptionClass getExceptionClass() {
return exceptionClass;
}
public int getHttpStatusCode() {
return httpStatus.value();
}
public String getHttpStatusType() {
return httpStatus.getReasonPhrase();
}
// 객체 리턴
public HttpStatus getHttpStatus() {
return httpStatus;
}
==> 라이징캠프에서 진행했던 것은 HttpStatus를 따로 정의해주었던 것이다.
예외가 사용되는 ExceptionHandler
@ExceptionHandler(value = DanielException.class)
public ResponseEntity<Map<String, String>> ExceptionHandler(DanielException e) { // 예외를 받아온다.
HttpHeaders responseHeaders = new HttpHeaders();
Map<String, String> map = new HashMap<>();
map.put("error type", e.getHttpStatusType());
map.put("error code",
Integer.toString(e.getHttpStatusCode())); // Map<String, Object>로 설정하면 toString 불필요
map.put("message", e.getMessage());
return new ResponseEntity<>(map, responseHeaders, e.getHttpStatus());
}
어떻게 사용되는가?
@PostMapping(value = "/product/exception")
public void exceptionTest() throws DanielHubException {
throw new DanielException(ExceptionClass.PRODUCT, HttpStatus.FORBIDDEN, "접근이 금지되었습니다.");
}
아래와 같이 Product, Sign 등 도메인별로도 exception의 종류를 정의할 수 있는 듯하다. 출력될 때, msg가 "Product Exception. @@가 발생했습니다." 로 정의되는 것이다. 이를 통해 어디서 에러가 발생했는지를 알 수 있다.
==> BaseException은 code번호를 커스텀할 수 있는 있지만 어느 도메인에서 진행하는지 구별이 어려웠다. 그래도 BaseException<>(@@@) 로 나타낼 수 있던 것은 장점이다.
public class Constants {
public enum ExceptionClass {
PRODUCT("Product"), SIGN("Sign");
private String exceptionClass;
ExceptionClass(String exceptionClass) {
this.exceptionClass = exceptionClass;
}
public String getExceptionClass() {
return exceptionClass;
}
@Override
public String toString() {
return getExceptionClass() + " Exception. ";
}
}
}
참고
1. 링크
2. HTTP header와 body
3. Spring io ResponseEntity
Spring MVC 로 마지막 프로젝트를 진행할 때 때, 리턴값은 Object와 View 뿐이었다 . Header 값을 통해 조금 더 견고한 API를 개발했더라면 더 좋았을걸 이라는 아쉬움이 남았다.
public class HttpEntity<T> {
private final HttpHeaders headers;
@Nullable
private final T body;
}
Spring Framework에서 제공하는 클래스 중 HttpEntity라는 클래스가 존재한다. 이것은 HTTP 요청(Request) 또는 응답(Response)에 해당하는 HttpHeader(body, req, res에 대한 정보)와 HttpBody(실제 데이터 컨텐츠)를 포함하는 클래스이다.
HttpEntity 클래스를 상속받아 구현한 클래스가 RequestEntity, ResponseEntity 클래스이다. ResponseEntity는 사용자의 HttpRequest에 대한 응답 데이터를 포함하는 클래스이다.
따라서 HttpStatus, HttpHeaders, HttpBody를 포함한다.
출처: https://medium.com/codestorm/custom-json-response-with-responseentity-in-spring-boot-b09e87ab1f0a
이전에는 지리 위치, 카메라, 연락처 정보, 블루투스, 파일시스템 등에 접근하려면 앱을 설치해야했다.
하지만 현재는 위의 기능들을 다 JS을 통해 웹 브라우저에서 가능하고, PWA(progressive web application)으로 모바일 웹처럼 보이는 사이트를 통해 진행한다.
앱 스토어에서 설치하는 것들은 앱이 아니라 바로가기 였다!
이를 실행하면 웹 브라우저가 열리는데, PWA이기 때문에 브라우저 탐색 표시줄이 숨겨져서 앱처럼 보일 것이다.
==> 그런 애플이 이제 2023년부터 푸시 알림에 필요한 API들을 구현할 것이라 발표
거대 IT기업들은 비밀번호 없애기에 착수했다.
애플은 Passkeys 기술을 발표했는데, 이는 비밀번호 없는 인증을 제공하는 기술이다.
비밀번호 방식의 문제점
- 유저들의 비밀번호의 재사용
- 피싱의 대상
계속 해결하고자 노력했으나 모두 완벽한 방법들이 아니었다.
FIDO(Fast Identity Online)
- 비밀번호 사용을 줄이기위한 표준을 만드는 단체
Passkeys를 사용하게되면 이미 동기화된 휴대폰과 컴퓨터에서 QR 코드를 통해 Touch ID(혹은 Face Id) 로그인
==> 털릴 위험, 피싱의 위험이 없다. 컴퓨터와 휴대폰이 근접해야한다.
보안 절차가 점점 단순하면서 강화되고 특정 기업에 종속되지 않고 범용성이 커지고 있는 추세군요
앱에서 웹화면을 보여주는 하이브리드앱은 이미 흔하고 이렇게 하면 푸시도 쓸 수 있어서 PWA가 아니라도 방법이 없는건 아니었습니다만, 세계적인 OS들의 한 축이 웹에대한 지원을 제공한다는건 좋은 일이라고 생각합니다. 애초에 안드로이드와 iOS앱을 따로 만들고 따로 관리하는건 비용이 너무 많이 들어가고 무엇보다도 비효율적입니다.
앱푸시가 앱을 개발하는데 중요한 이유중에 하나이긴하나 하이브리드앱이 결국 주류가 되지 못한것 처럼, 편의성(스토어), 서드파티앱과의 연동성 등 네이티브앱의 장점들을 넘어서거나 비슷하게 구현할 수 없다면 역시 돌고돌아 네이티브는 살아 남을 수 있을것 같습니다
하지만, 반대로 이런 기능들이 필요없고 정말 ~ 앱푸시 하나만 있는 앱을 만든다거나, 플랫폼을 만드는 사업에 대해서는 PWA가 다시 한번 게임체인저로 부상할 순 있겠네요!
결국 고유한 유니크 키를 전세계 모두에게 부여하고 그 키의 생성권한을 완전히 글로벌 대기업만 가짐으로서 영구적인 우위를 시도하는거같네요. 카카오 없으면 민원결과 볼수없는 한국이 그런상태죠
휴대폰의 소유주임을 인증하기위해 생체인증같은 방법을 사용해야할텐데, 생체인증의 경우 한번해킹당하면 그 소스를 변경할수 없기 때문에 개인적으로 위험한 방법이라 생각하고있습니다. 패스워드의 경우 해킹당하면 바꾸면되지만, 지문이나 얼굴정보는 해킹당하면 바꿀수없기 때문이죠..(지문을 바꾼다거나 성형을한다거나..?)