
문제상황
예전에 react에서 django rest framework로 요청을 보낼 때 CORS error가 자꾸 떠서 해결하려다가 결국 해결 방법을 못 찾고 포기했었다. 그런데 이번에 json-server을 이용하여 간단하게 프론트를 연습하려 했는데 또 CORS error 와 마주쳤다.
다음에도 CORS error를 마주칠 게 분명했기 때문에 이번에 꼭 해결해야겠다고 생각했다.

해결과정
이상하게도, 로컬에서는 작동하는 방법이 gitpod에서는 계속해서 CORS error를 낸다는 것을 알게 되었다. 따라서 gitpod에 문제가 있다고 추정했다.
gitpod 공식 문서를 보던 중 fetch 요청에 credentials: ‘include’ 옵션이 있어야만 하고, server측에서는 Access-Control-Allow-Credentials 헤더를 포함하여 보내야만 CORS error를 해결할 수 있다는 것을 알게 되었다.
https://www.gitpod.io/docs/configure/workspaces/ports
Ports - Docs
Gitpod Documentation: Gitpod supports exposing HTTP ports via a custom domain that is associated with your workspace. You can also use port forwarding, so that you do not need to update your application if it already references the localhost hostname.
www.gitpod.io
보통 CORS요청에서는 민감한 자격 증명(credentials)이 함께 전송되지 않으나, 내가 사용하는 gitpod에서는 요청이 인증된 유저에 의해 만들어진 것인지 확인을 해야 하므로, 프라이빗한 포트에 대해서는 자격 증명을 필요로 한다. 따라서, 자격 증명을 포함하여 보내는 credentials:'include' 옵션을 포함하여 fetch 요청을 보내야만 한다.
또한, 서버 측에서는 이 자격 증명을 받아들여야 하므로 Access-Control-Allow-Credentials 헤더를 포함해야 한다.
따라서 fetch에 다음과 같이 옵션을 추가해 줬다.
fetch('json-server 주소',{credentials: 'include'})
또한 서버 측에서는 access-control-allow-credentials 헤더를 포함해야 했다. 다만, 나는 프론트 테스트를 위해 json-server를 사용 중이었기 때문에 헤더를 포함하는 방법을 한참 헤맸다.
찾아보던 도중 json-server 라이브러리를 express.js와 유사하게 사용할 수 있다는 것을 알게 되었고, 다음과 같이 코드를 짰다.
//server.js
const jsonServer = require('json-server');
const server = jsonServer.create();
const router = jsonServer.router('db.json');
server.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Credentials', true);
next();
});
server.use(router);
server.listen(9999, () => {
console.log('JSON Server is running');
});
json-server 소스코드를 보던 중 cors의 origin 주소를 모든 origin에서 접속이 가능하도록 '*'로 해놓은 것을 볼 수 있었다.
아마 간편 서버인 만큼 손쉬운 사용을 위해 모든 origin에서 접속이 가능하게 했나 보다.
// CORS
app.use(cors()).options('*', cors())
https://github.com/typicode/json-server/blob/main/src/app.ts
json-server/src/app.ts at main · typicode/json-server
Get a full fake REST API with zero coding in less than 30 seconds (seriously) - typicode/json-server
github.com
따라서, 나도 cors는 모두 받아들이도록 '*'을 했다.
server.js는 자동으로 json-server를 실행 시키므로, 기존의
json-server --port 9999 --watch db.json
과 같이 실행을 안시키고
node server.js
라고 실행시키면 된다.
실행 시켰더니 또 다음과 같은 오류가 발생하였다.
node:internal/modules/cjs/loader:1148
throw err;
^
Error: Cannot find module 'json-server'
Require stack:
- /workspace/ai/practice1/server.js
at Module._resolveFilename (node:internal/modules/cjs/loader:1145:15)
at Module._load (node:internal/modules/cjs/loader:986:27)
at Module.require (node:internal/modules/cjs/loader:1233:19)
at require (node:internal/modules/helpers:179:18)
at Object.<anonymous> (/workspace/ai/practice1/server.js:1:20)
at Module._compile (node:internal/modules/cjs/loader:1358:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1416:10)
at Module.load (node:internal/modules/cjs/loader:1208:32)
at Module._load (node:internal/modules/cjs/loader:1024:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:174:12) {
code: 'MODULE_NOT_FOUND',
requireStack: [ '/workspace/ai/practice1/server.js' ]
}
Node.js v20.13.1
이 오류는 json-server@1.0.0 버전에서 일어나는 오류로 보이는데, json-server를 다시 삭제하고, 0.17.4 버전을 설치하였다.
https://github.com/typicode/json-server/issues/1500
Again "json-server module not found" · Issue #1500 · typicode/json-server
I am trying to follow one older tutorial: https://www.journeytoawebapp.com/posts/local-mock-server-with-node Fresh repository I copy-pasted the code: const jsonServer = require('json-server'); cons...
github.com
기대감에 부푼체 실행을 하였으나, 또 이상한 오류를 마주치고 말았다.
Access to fetch at '서버주소' from origin '프론트주소' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
다행이 간단한 오류였고 access-control-allow-origin에 모든 origin을 허용하면 안 되고, 지정을 해줘야 한다는 것이었다.
따라서 다음과 같이 코드를 고치고 실행해 줬더니 해결이 되었다.
//server.js
const jsonServer = require('json-server');
const server = jsonServer.create();
const router = jsonServer.router('db.json');
server.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '프론트주소');
res.header('Access-Control-Allow-Credentials', true);
next();
});
server.use(router);
server.listen(9999, () => {
console.log('JSON Server is running');
});
문제를 해결한 채로 json-server 1.0.0이아닌 v0의 소스코드를 봤다. 그런데 무엇인가 이상한 것을 발견했다.
// Enable CORS for all the requests, including static files
if (!opts.noCors) {
arr.push(cors({ origin: true, credentials: true }))
}
https://github.com/typicode/json-server/blob/v0/src/server/defaults.js
json-server/src/server/defaults.js at v0 · typicode/json-server
Get a full fake REST API with zero coding in less than 30 seconds (seriously) - typicode/json-server
github.com
json-server 0.17.4에는 내가 server.js에서 설정한 것이 이미 설정이 되어있다는 것을 발견하였다!
따라서, 다시 server.js파일이 아닌 json-server 라이브러리를 실행시켜 봤다.
npx json-server@0.17.4 --port 9999 --watch db.json
놀랍게도 잘 작동하는 것을 볼 수 있었다.
따라서, json-server 버전을 1.0.0에서 0점대 버전(0.17.3, 0.17.4 ...)등으로 바꿔주면 되는 문제였다.
느낀점
gitpod에서 일어나는 cors 오류의 대처법을 알 수 있어서 좋았고, 앞으로 다른 라이브러리를 이용할 때도 유용하게 사용해야 겠다.
gitpod을 써서 검색해도 안 나오는 이상한 오류들이 가끔 생길 때가 있는데, 개인 서버를 새로 만들어야 하는지 고민을 해봐야겠다고 느꼈다.
'웹 > web' 카테고리의 다른 글
| [selenium] 멀티 쓰레딩 크롤러 (0) | 2024.07.28 |
|---|