Authorization Routes - Error 수정하기
노마드 코더의 프론트엔드 첫번째 스테이지 Authorization Routes를 마무리 하겠습니다. 로그인 파트 정리단으로 생각하시면 될 것 같습니다. 우선 몇가지 에러 사항에 대해 설명드리고자 합니다.
Error 1. useMutation 업데이트
노마드 코더가 이 강의를 찍을 당시랑 현재랑 시간차이가 있는데요. 그 만큼의 시간 덕분에 발생한 몇가지 에러를 다루어 보겠습니다. 그 첫번째로는 바로 useMuatation
에러 입니다.
노마드 코더는 당시 본인의 코드에서 useMutation을 사용할 때
src/Routes/Auth/AuthContainer.js
const requestSecretMutation = useMutation(LOG_IN, {
variables: { email: email.value }
});
const createAccountMutation = useMutation(CREATE_ACCOUNT, {
variables: {
email: email.value,
username: username.value,
firstName: firstName.value,
lastName: lastName.value
}
이렇게 requestSecretMutation을 [] 감싸지 않고 사용 했었습니다. 이는 함수가 업데이트 되면서 []배열로 만들어 주도록 업데이트 되었습니다. 예전 버전에서는 useMutation을 함수처럼 사용합니다. 하지만 현재 버전에서는 [function, {loading ...}]
처럼 function과 여러 설정값을 가지고 있는 object로 return되기 때문에 예전버전과 같이 사용할 경우에 function이 아니라는 에러를 띄우게 됩나다.
해결 방법은 간단합니다.
src/Routes/Auth/AuthContainer.js
const [requestSecretMutation] = useMutation(LOG_IN, {
variables: { email: email.value }
});
const [createAccountMutation] = useMutation(CREATE_ACCOUNT, {
variables: {
email: email.value,
username: username.value,
firstName: firstName.value,
lastName: lastName.value
}
위 처럼 배열 형태의 [requestSecretMutation]
로 만들어 주는 것입니다. 이렇게 하는 이유는 return되는 값들 중에 function으로만 사용한다는 의미가 됩니다. 따라서 이렇게 함수로 만든 후 호출하여 사용하면 됩니다.
Error 2. CORS - 서버에 데이터 요청
https://localhost:4000으로 전달하여 GraphQL <-> Apollo 백엔드와 프론트엔드를 연결하여 사용하도록 강의에서 진행하고 있고 또 저도 그렇게 사용하였습니다. 하지만 아래의 이미지와 같이 이러한 에러가 뜨는 경우가 있습니다.

에러 메시지는 다음과 같습니다. Error Message:”Access to fetch at ‘http://localhost:4000/’ from origin ‘http://localhost:3000’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.” 과연 CORS?가 무엇일까요?
Cross Origin Resource Sharing의 약자로 도메인 또는 포트가 다른 서버의 자원을 요청하는 매커니즘을 말합니다. 요청을 할 때 cross-origin-HTTP에 의해 요청되나 ‘same-origin-policy’때문에 CORS와 같은 상황이 발생하였을 때 외부 데이터를 브라우저에서 보안 목적으로 차단하는 경우가 있습니다. 이 때문에 정상적으로 데이터를 받을 수 없습니다.
동일 출처 정책(same-origin policy) 불러온문서나 스크립트가 다른 출처에서 가져온 리소스와 상호작용하는 것을 제한하는 중요한 보안 방식입니다. 이것은 잠재적 악성 문서를 격리하여, 공격 경로를 줄이는데 도움이 됩니다.
– MDN web docs –
저는 실습하는 동안 localhost:4000에서 server를 실행하였고 localhost:3000에서 react를 실행하고 있었기에 포트가 달라 CORS가 발생할 여지가 충분한 상황이었습니다. 해결방법으로는 서버와 클라이언트가 같은 도메인과 포트를 사용하면 됩니다. 이 방법이 불가능하면 미들웨어 CORS를 추가하면 됩니다. 추가하는 방법은 아래와 같습니다.
yarn add cors
로 cors를 설치한 뒤에 BackEnd 서버에 아래와 같은 미들웨어를 추가하면 됩니다. 이 때 노마드 코더의 serve.js에 추가하도록 합니다. 자세한 사항은 여기 문서로 접속하시면 나와 있습니다. 아래는 백엔드의 server.js에 코드를 추가하시면 CORS에러는 잡을 수 있습니다.
BackEnd:prismagram/src/server.js
import "./env";
import { GraphQLServer } from "graphql-yoga";
import logger from "morgan";
import schema from "./schema";
import "./passport";
import { authenticateJwt } from "./passport";
import { isAuthenticated } from "./middlewares";
import { uploadMiddleware, uploadController } from "./upload";
const PORT = process.env.PORT || 4000;
const server = new GraphQLServer({
schema,
context: ({ request }) => ({ request, isAuthenticated })
});
// 여기서부터 추가된 코드입니다.
const express = require('express');
const cors = require('cors');
const app = express();
const corsOptions = {
origin: 'http://localhost:3000',
credentials: true,
};
app.use(cors(corsOptions));
//여기까지..
server.express.use(logger("dev"));
server.express.use(authenticateJwt);
server.express.post("/api/upload", uploadMiddleware, uploadController);
server.start({ port: PORT }, () =>
console.log(`✅ Server running on http://localhost:${PORT}`)
);
위와 같이 BackEnd GraphQL 서버에 추가하시면 CORS 에러를 해결할 수 있습니다.
Passport 미동작
얼마나 수없이 많은 console.log를 찍었는지 모르겠네요.. 결국 문제는 dotenv가 동작을 제대로 하지 않는 것이었습니다. 왜 그러는지는 모르겠지만 import 하는 과정에서 시점에 import 시점에 따른 문제로 보여집니다. 해서 저는 BackEnd의 prismagram/src/utils.js
에서 결국 sendgrid ID / Password 값을 직접 입력해주었습니다.
//.. 이하 코드 생략
const SENDGRID_USERNAME = "pacdong";
const SENGRID_PASSWORD = "xxxxxxxxxxxx";
const sendMail = email => {
const options = {
auth: {
api_user: SENDGRID_USERNAME,
api_key: SENGRID_PASSWORD
}
};
const client = nodemailer.createTransport(sgTransport(options));
return client.sendMail(email);
};
이렇게 sendMail 부분에서 SENDGRID_KEY 부분에서 직접 넣어 주어 Error를 해결하였습니다. 또한 SECRET CODE를 제러레이터를 통해 만들고 나서 Jwt_Token에 저장할 때도 process.env.Jwt_Secret이 undefind 되는 버그가 있어 src/env.js
값을 아래와 같이 수정하였습니다.
import dotenv from "dotenv";
import path from "path";
dotenv.config({ path: path.resolve(__dirname, ".env") });
이렇게 수정하고 나서야 console.log 해 보았을 때 정상적으로 값이 들어오는 것을 확인하였습니다.
Leave a comment