React-Quill 설치
$ yarn add react-quill
리액트 퀼을 그냥 쓰게 import해서 쓰게되면 이런 에러가 난다.
next.js는
먼저 Front-end서버에서 데이터를 읽고, 읽은 데이터를 가지고
Br에서도 한번더 데이터를 읽는다. 이 둘간의 읽어온 데이터의 차이점을 비교하는걸
diffing
이라고 하고 , 최종적인 결과(diffing)를 브라우저
그려주는게 hydration
이라고 한다.
그래서 Front-end서버에서 먼저 데이터를 읽기 때문에
Front-end서버에서 그릴때 문제가 생긴거임 여기서 읽을땐 브라우저가 없음
리액트는 프론트엔드서버에서 먼저 읽는 사전작업이 없기때문에
순수 리액트에선 저런 에러가 안남.
그래서 Front-end서버에서 읽을땐 "react-quill을 import하지마라"라고
import를 다이나믹
하게 줘야함
import ReactQuill from "react-quill"
이렇게 해주면 프론트엔드 서버에서 그릴때, doucment가 없어서
에러가 난다.
그래서 프론트엔드 서버상에선 import가 안되게 다이나믹하게 import 해줘야 한다.
import dynamic from "next/dynamic"
그래서 dynamic을 import 해준다.
const ReactQuill = dynamic(()=>import("react-quill", {ssr:false}))
dynamic으로 import한다, import를 "react-quill"로 하는데
{ssr:true} or {ssr:false}
참고로 ssr은 Server Side Rendering의 약자이다
{ssr:true} : 서버에서 렌더링 한다
{ssr:false} 서버에서 렌더링 안한다
프론트엔드 서버에서 렌더링 하면 안되니까 {ssr:false}
를 주고 import한다.
css를 아무것도 불러오지 않고, 리액트퀼을 쓰면
이렇게 먹힌다. 공식문서엔
import "react-quill/dist/quill.snow.css"
이걸 import하라고 되어있다.
그럼 이렇게 에디터의 모습을 갖춘상태로 보인다.
글을 입력하고 글꼴을 적용시키면
이렇게 태그로 감싸진 형태로 데이터가 들어온다.
react-quill은 다른 input태그와는 다르게 register로 값을 받는게 아닌
value로 데이터를 받는다.
그래서 강제로 값을 넣어주기 위해서 useForm기능중에 setValue
를 써준다.
const { handleSubmit, register, setValue} = useForm({
mode: "onChange",
});
function onChangeMyEdit(value) {
setValue("contents", value === "<p><br></p>" ? "" : value);
}
근데 이렇게 setValue를 통해서 값을 강제로 넣었다 쳐도 값은 들어가지만
내가 입력하면 입력된대로 데이터가 저장이 되야하는데 그렇게 안된다.
그래서 useForm의 기능중에 trigger
라는 기능이 있는데
const { handleSubmit, register, setValue, trigger } = useForm({
mode: "onChange",
});
function onChangeMyEdit(value) {
setValue("contents", value === "<p><br></p>" ? "" : value);
trigger("contents")
}
이렇게 적용시켜주면 contents라는걸 건드렸구나 라는걸 인식을 할 수 있고,
바뀐 데이터가 바로바로 저장이 된다.
앞서 React-Quill을 이용해서 글꼴이 적용된 내용을 적으면
글꼴이 적용된 상태로 화면에 보이고 data는 태그로 감싸져있는 형태로
저장이 되었다.
그 데이터를 다른곳에서 불러 올 때 태그그대로 데이터를 불러와서 화면에 보여주면
안되고 태그가 적용된 상태로 화면에 보여져야한다.
이때 dangerouslySetInnerHTML
를 쓴다.
그럼 이렇게 글꼴이 적용된 상태로 보인다.
하지만 이 방식 그대로 쓰면 위험하다. dangerouslySetInnerHTML 이름에서도
알 수 있듯이, 위험한 방식이다. 그 이유는 해킹에 취약하기 때문이다.
<script>localStorage.getItem("accessToken"); axios.post() </script>
해킹에 취약한 이유는 해커가 입력창에 이런식으로 입력하면 데이터를 탈취할 수 있기 때문이다.
<img src="#" onerror="console.log(localStorage.getItem(\"myAccessToken\"))">"
React-Quill은 1차적으로 저러한 해킹 방법을 막긴한다.
위에있는 코드중에 <
같은거를 태그로 인식 못하게끔 <
를 다른걸로 바꿔버린다.
근데 React-Quill이 아니라 플레이그라운드나 다른 곳에서 api 요청을 할때
태그를 통해서 보낸다면 위험하다
그럼 이런 해킹시도가 들어왔을때 막을 수 있어야하는데
이런것을 막아주는 라이브러리가 있다.
그건 바로 Dompurify
주간 180만 다운로드가 되는 엄청난 라이브러리다.
이걸 쓰는 이유는 웹 에디터를 썼을때 앞서 해킹에 취약한 문제가 있기 때문에
쓰는 것이다.
웹 에디터를 쓰면 이 라이브러리는 어느회사건 다 쓴다고 보면 된다.
DomPurify설치
$ yarn add dompurify
Dompurify import하기
import Dompurify from "dompurify"
그리고나서 위험한 부분을 Dompurify.sanitize
로 감싸준다
이 부분을 적용시키면 만약 컨텐츠안에 태그가 들어있으면 Dompurify가 실행
자체를 안시킨다.
근데 얘도 그냥 실행시키면 에러가 난다.
이것도 서버에서 렌더링할때 없다고 에러가 나는건데
브라우저가 없기때문에 에러가 나는거임
그래서 얘도 서버에서 그려주면 안되서
서버에서 렌더링을 막아줘야 한다.
서버에서 렌더링을 막아주는 두가지 방법이 있다.
웹브라우저가 있다면 실행 , 없으면 그리지 않기
브라우저면 실행, 아니면 실행 X
두번째 방법이 훨씬 쉬운데, 첫번째 방법을 쓰는 회사가 있을 수 있으니
알아놓자.
웹에디터 React-Quill을 쓰면 편하게 입력 툴을 사용가능하다.
useForm을 쓸때 데이터를 못 불러오니까, 강제로 데이터를 넣고
trigger를 통해서 입력이 되었음을 감지해서 입력한대로 데이터를 받을 수 있었다.
그리고나서 디테일 페이지에서 내가 입력한 데이터를 받는데,
태그가 감싸져있는 형태로 데이터를 읽어와서 dangerouslySetHTML을 써서
태그가 적용된 상태로 데이터를 읽어왔다.
하지만 이름에서 알 수 있듯이 해킹에 취약한 문제가 있었다.
그래서 Dompurify라는 라이브러리르 썼고, Dompurify 라이브러리를 썼더니
해킹에 취약했던 문제점이 사라졌다