input 태그의 타입이 file 이나 email 인 경우 multiple 속성을 지정하면 사용자가 둘 이상의 값을 입력할 수 있다는 의미이다.
<input
type="file"
multiple
/>
콤마를 통해 사용자가 둘 이상의 이메일을 입력할 수 있다.
파일 선택시 여러 파일을 동시에 선택할 수 있다.
API 엔드 포인트를 숨기기 위해서 Vite 의 설정 파일에서 프록시를 커스텀할 수 있다.
server: {
proxy: {
'/api': {
target: process.env.VITE_API_END_POINT,
changeOrigin: false,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
});
/api 클라이언트 측에서 보여질 URLtarget 실제 엔드 포인트 주소changeOrigin 클라이언트 출처 주소를 바꿀 것인지를 결정한다. 우리 팀은 localhost 를 그대로 사용할 것이라 false 로 설정해주었다.rewrite 정규 표현식을 사용하여 경로를 어떻게 바꿀것인지 설정한다.백엔드에서 다음 OAuth 를 위한 url 을 프론트로 넘겨주었다.
https://도메인링크/oauth2/authorization/kakao
https://도메인링크/oauth2/authorization/naver
네이버와 카카오에서 로그인을 하면 헤더에 있는 Set-Cookie에 로그인 인증 토큰을 담아준다. 이렇게 받은 쿠키값은 브라우저에서 자동으로 API 요청 시 마다 전달해준다고 했다.
이렇게 로그인에 성공하면 배엔드 도메인으로 리다이렉트 되어 쿠키값을 가져와서 쿠키값을 브라우저에서 일일이 설정해주는 방법을 사용했다.
그런데 이 방식이 불편하다 보니 백엔드에게 리다이렉트로 로컬 호스트에 연결시켜줄 수 있냐는 요청을 했고, 백엔드는 localhost 로 리다이렉트를 시켜주었다.
그런데 이때부터 로그인이 되지 않았다. 클라이언트 측에서 쿠키 값을 새로 넣어도 동작하지 않음은 물론이고, 백엔드에서도 로그인이 되지 않은 상태라고 떴다.
왜 쿠키 값이 제대로 전달되지 않는지 살펴보니, JWT 토큰과 달리 쿠키는 보안 조건이 까다로워서 백엔드와 프론트 도메인이 같지 않으면 쿠키를 전달해줄 수 없다고 한다.
로그인이 해결되지 않으면 다른 API 까지 사용을 못하도록 백엔드 측에선 이미 구현을 완료해놓은 상황이라 프론트 측은 약 이틀간 API를 사용하지 못했다.
결국 도메인 문제를 해결하지 못하고 JWT 토큰을 사용하기로 했다.
웹 사이트에선 어떻게 쿠키와 쿠키의 제약을 해결하는지 알아보아야겠다.
axios 의 interceptor 를 사용하여 모든 요청에 JWT 토큰을 넣어줄 수 있다.
apiClient.interceptors.request.use((config) => {
const token = getStorageData('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
});
export defualt apiClient;
초대링크를 복사하는 UI 에서 사용자가 클립보드를 복사할 수 있도록 하려면 아래와 같은 코드를 작성한다.
const handleCopyButton = async () => {
await window.navigator.clipboard.writeText(invitationCode);
}
사용자가 임의로 TextArea 의 크기를 변경하지 못하도록 막아 놓은 상태다. 하지만 이렇다보니 글자수가 일정 이상 넘어가면 스크롤이 생기는 문제가 생겼다.
TextArea 의 영역을 사용자가 임의로 조정하지 못하게 하되, 글자 수가 늘어남에 따라 아래와 같이 TextArea 의 크기도 늘어나게 하고 싶었다. (최대 글자 200자)


height 스타일에 auto 도 줘보고 fit-content 도 줘보았지만 잘 되지 않아 인터넷을 참고해 해결했다.
<textarea
className="resize-none"
onInput={handleTextAreaHeight}
maxLen={200}
>
{content}
</textarea>
const handleTextAreaHeight = (event: KeyBoardEvent<HTMLTextAreaElement>) => {
if (event.target instanseof HTMLTextAreaElement) {
const { scrollWidth } = event.target;
event.target.style.height = String(scrollWidth) + 'px';
}
}