당근마켓 :6 Authorization
프론트엔드에서 인증된 유저를 확인하여
페이지 접근을 제한하는 비공개 , 공개페이지를 구분 할거임
- 비공개,공개 핸들러
- swr fetching data
인증되지 않는 요청으로부터 핸들러 보호
e.g) login 하지 않은 상태에서 api/user/ 접속하지 못하게
인자가 많아지면 객체 형식으로 표현해주는것이 가독성에 좋다
`fn('GET', handler, true) -> fn({method:'GET', handler, isPrivate:true})`
withHandler.tsx
interface ConfigType {
method: "GET" | "POST" | "DELETE";
handler: (req: NextApiRequest, res: NextApiResponse) => void;
isPrivate?: Boolean;
}
export default function withHandler({
method,
isPrivate = true,//기본값 설정 비공개인 화면이 더 많을 거라서 true로 설정
handler,
}: ConfigType) {
return async function (
req: NextApiRequest,
res: NextApiResponse
): Promise<any> {
if (req.method !== method) {
return res.status(405).end();
}
if (isPrivate && !req.session.user) {
return res.status(401).json({ ok: false, error: "plz Login" });
}
try {
await handler(req, res);
} catch (error) {
console.log(error);
return res.status(500).json({ error });
}
};
}
다른 api
api/user/users confirm, enter, me .tsx
export default withApiSession(withHandler("GET", handler, false));
-->config type을 지정하므로 코드를 공유하는 입장에서 어떤의민지 더 잘 파악 할 수 있음
export default withApiSession(withHandler({
method:"GET",
handler
}));
isPrivate를 선언해 준 이유가 접근하는 API마다 private인지 public인지 구분해주기 위함인가요?
사실 로그인 체크같은 경우에도 isPrivate 없이 if(!req.session.user){...} 로도 체크 할 수 있지만, isPrivate를 추가하여 같이 검사함으로써 해당 API에 접근할때만 로그인이 되어있는지 안되어있는지 체크하기 위해 isPrivate랑 같이 사용하는것 맞죠? isPrivate 없이 if문으로만 체크한다면 어떤 API든지 요청을 보내면 로그인 검사를 하게되어 문제가 생길 수 있기 때문에 isPrivate로 구분해주는거죠?!
백엔드
-----
프엔
w정보를 api페이지에서 프론트페이지로 가져와보여주는것
libs>clients> useUser.ts유저 데이터에 접근 할 수 있는 훅을 만들고 각 페이지에서 데이터 불러오는게 편함
pages.index.tsx
useLocation().push --> home에서 login 되어 있지 않으면 enter으로 가게되는데 home이라는 history가 남음(뒤로가기) -->필요없는 기능-->.replace로 바꾸기
https://nextjs.org/docs/api-reference/next/router#routerpush
해당요청을 상품페이지, 상세페이지,유저페이지에서 매번 api요청을 보내는건 좋지않으므로 cacheing이용
훅을 한번만 사용하고 메모리에저장 -->swr
SWR
SWR은 먼저 캐시로부터 데이터를 반환한 후, fetch 요청(재검증)을 하고, 최종적으로 최신화된 데이터를 가져오는 전략입니다. SWR을 사용하면 컴포넌트는 지속적이며 자동으로 데이터 업데이트 스트림을 받게 됩니다. 그리고 UI는 항상 빠르고 반응적입니다.
SWR은 React 프레임워크인 Next.js를 만든 동일한 팀이 만들었습니다.
npm i swr 또는
https://swr.vercel.app/ko/docs/getting-started
useSWR사용하기
1. JSON 데이터를 사용하는 일반적인 RESTful API라면 먼저 네이티브 fetch의 단순한 래퍼인 fetcher 함수를 생성해야 합니다.
ex) const fetcher = (...args) => fetch(...args).then(res => res.json())
2. 그 다음, useSWR을 import하고, 함수 컴포넌트 내에서 사용하여 시작하면 됩니다.
ex) const { data, error } = useSWR('/api/user/123', fetcher)
useSWR 옵션
const { data, error, isValidating, mutate } = useSWR(key, fetcher, options)
https://swr.vercel.app/docs/options
userUser.tsx
useSWR사용으로 코드가 아주가볍게 바뀜
pages/index.ts
기존: undefined로 시작 --> fetch해서데이터가져오기
현재: 기존데이터로 fetch됨
VS react-query `https://goongoguma.github.io/2021/11/04/React-Query-vs-SWR/`
- React Query가 더 많은 기능을 제공하지만 그만큼 더 많은 용량을 차지(3배)
- 간단한 용도로 사용하기에는 유용하게 사용가능
데이터가 변경되면 자동으로 데이터를 변경해줌= 서버api 는 매번 호출
swr
stale while revalidate
"/api/users/me"는 url만이아니라
fetcher가 캐시에서 데이터를 가져올 때 사용하는 ID이다.
다시 fetch 하지 않고 캐시된 data를 로드하여 가져옴
super_cache:{
"/api/users/me":{
}
api로 키가 분류되기 때문에
같은 url이면 같은 캐시데이터를 가져오면되는구나하고 useSWR가 인지함.
}
전체적으로 React Query가 더 좋지만 패키지 크기가 SWR의 3배가 넘기 때문에 간단한 어플리케이션 만들기에는 SWR가 좋고, 많은 커스텀 기능들이 필요하면 React Query가 사용하기 좋은거 같습니다
/procduct에 접근하기위해서 또 "/api/users/proudcts"쓰고 fetcher 도 계속 import해서 쓰고싶지않아
global swr configuration
모든페이지에 적용되는 fetcher같은 것의 기본값을 지정 할 수 있는 프로바이더
Global Configuration
컨텍스트 SWRConfig는 모든 SWR 훅에 대한 Global Configuration(옵션)을 제공할 수 있습니다.
```
< SWRConfig
value={{
refreshInterval: 3000,
fetcher: (resource, init) => fetch(resource, init).then(res => res.json())
}}
>
< Dashboard />
< /SWRConfig>
```
https://swr.vercel.app/docs/global-configuration
_app.tsx
useUser.tsx