React

 

 

 

 Next.js 서버사이드렌더링

 

버전이 다르기 때문에 소스가 강좌와 다를 수 있다.

버전

next:  13.0.4

antd:  5.0.1

 

소스 : https://github.dev/braverokmc79/node-bird-sns

 

제로초 소스 : https://github.com/ZeroCho/react-nodebird

 

 

 

 

 

 

 

 

81.  도메인 연결하기

 

강의 :

https://www.inflearn.com/course/%EB%85%B8%EB%93%9C%EB%B2%84%EB%93%9C-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%A6%AC%EB%89%B4%EC%96%BC/unit/49017?tab=curriculum

 

Back End/AWS

[AWS] EC2 와 도메인 연결하기 (feat. 가비아)

 

 

 

 

cors 참조 :

1.

React(Nextjs)로 NodeBird SNS 만들기 - 4 -2 백엔드 노드 서버 (Nodejs) 구축하기, 회원가입 구현, CORS 문제 해결하기,패스포트로 로그인, 로그아웃, Credentials로 쿠키 공유, 내 로그인 정보 매번 불러오기

 

 

2.React 따라하며 배우는 노드, 리액트 시리즈(John Ahn) - 2 리액트란, 리액트설치,Npm 과 Npx차이,릭액트구조,CRA To Our Boilerplate,React Router Dom,Proxy ServerCORS 이슈, Proxy 설정,데이터 Flow & Axios,Concurrently

 

 

3. https://www.zerocho.com/category/NodeJS/post/5e9bf5b18dcb9c001f36b275

 

백엔드와 프론트엔드의 도메인 주소가 다른 경우가 많습니다. 이는 localhost인 경우에도 마찬가지입니다. 포트가 다르면 다른 주소로 칩니다. 이들간에는 쿠키 전송이 되지 않으므로 로그인이 유지되지 않아서 당황하시는 경우가 많습니다. 특히 개발자도구 Network 탭에서 Response Header에 Set-Cookie는 있는데 Application 탭에서 Cookie를 체크해보면 뜨지 않아서 어디가 문제인지 난처한 경우가 있습니다.

이럴 때 요청/응답 헤더를 적절하게 설정해주면 다른 도메인이더라도 쿠키가 전송됩니다.

먼저 프론트에서 ajax 요청을 보낼 때 withCredentials를 설정해주어야 합니다.

axios.post(주소, 데이터, { withCredentials: true });

순수한 xhr이라면 xhr.withCredentials = true를 추가하세요.

const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;
xhr.send(null); 

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials 

서버에서는 CORS 설정을 해주어야 하는데요. CORS 설정은 제 CORS 게시글을 참조바랍니다.

여기에 응답 헤더로 Access-Control-Allow-Credentials 옵션도 설정해주셔야 쿠키가 전송됩니다. Access-Control-Allow-Credentials를 true로 설정하고 Access-Control-Allow-Origin 옵션도 *가 아닌 정확한 도메인을 적어주면 됩니다.

express 사용 시 cors 모듈로 쉽게 설정할 수 있습니다.

const cors = require('cors');

app.use(cors({
  origin: true,
  credentials: true
}));

origin: true는 프론트 도메인 주소가 자동으로 Access-Control-Allow-Origin에 들어갑니다. 와일드카드인 *와는 다릅니다. credentials는 Access-Control-Allow-Origin을 true로 만들어주는 옵션입니다.

cors 모듈을 사용하지 않더라도 라우터에서 응답 헤더를 직접 넣어주시면 됩니다. 

res.setHeader('Access-Control-Allow-Origin', 'localhost:3000');
res.setHeader('Access-Control-Allow-Credentials', 'true'); 

 

 

 

 

 

백엔드 설정

app.js

1. ★ **쿠키를 저장할 도메인 설정해 줘야 한다.

app.use(session({
    secret: process.env.COOKIE_SECRET,
    resave: false,
    saveUninitialized: false,
    cookie: {
        httpOnly: true,
        secure: false,
        //**쿠키를 저장할 도메인 설정
        //http://192.168.120.136/
        //domain: process.env.NODE_ENV === 'production' && '.mynodebird.com'
        domain: process.env.NODE_ENV === 'production' && 'macaronics.iptime.org'
    }
}

 

 

 

2. cors 설정

if (process.env.NODE_ENV === 'production') {
    console.log(" production 실행 ");
    app.use(morgan('combined'));
    app.use(hpp());
    app.use(helmet({ contentSecurityPolicy: false }));
    app.use(cors({
        //origin: 'https://nodebird.com'
        // origin: true, // orign: true 로 설정해두면 * 대신 보낸 곳의 주소가 자동으로 들어가 편리합니다.
        //프론트 URL 주소
        origin: ["http://localhost:3060", "http://macaronics.iptime.org", "http://macaronics.iptime.org:3060"],
        credentials: true
    }));

} else {
    console.log(" dev 실행 ");
    app.use(morgan('dev'));
    app.use(cors({
        //origin: 'https://nodebird.com'
        // origin: true, // orign: true 로 설정해두면 * 대신 보낸 곳의 주소가 자동으로 들어가 편리합니다.
        origin: true,
        credentials: true  //사용ㅇ자 인증이 필요한 리소스 (쿠키, ... 등) 접근
    }));
}

 

 

 

 

 

 

 

 

 

프론트 설정

 

배포시 도매인은 백엔드 도메인  

.config/config.js

let BACK_URL = "http://localhost:3065";

//let BACK_URL = "http://192.168.120.137:3065";

if (process.env.NODE_ENV === "production") {
    //운영시 백엔드 주소
    //BACK_URL = "http://api.mynodebird.com:3065";
    BACK_URL = "http://macaronics.iptime.org:3065";
}

export const backURL = BACK_URL;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

82. S3 연결하기

 

강의 :

 https://www.inflearn.com/course/%EB%85%B8%EB%93%9C%EB%B2%84%EB%93%9C-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%A6%AC%EB%89%B4%EC%96%BC/unit/49080?tab=curriculum

 

 

AWS S3(Simple Storage Service)란?

https://dev.classmethod.jp/articles/for-beginner-s3-explanation/

 

 

=>  AWS - S3 사용하기 (버킷 만들기)

 

 

 

 

 

 

 

 

83. Lambda로 이미지 리사이징 하기

강의:

https://www.inflearn.com/course/%EB%85%B8%EB%93%9C%EB%B2%84%EB%93%9C-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%A6%AC%EB%89%B4%EC%96%BC/unit/49081?tab=curriculum

 

 

 

aws  s3  로 올리기전에  Lambda 썸네일 생성

 

[2/2] AWS Lambda와 Sharp로 이미지 리사이징하기 (이미지 최적화)

 

=> https://2donny-world.tistory.com/20

 

 

 

 

 

 

 

 

 

 

83.카카오톡 공유하기 & 강좌 마무리

 

강의 : https://www.inflearn.com/course/%EB%85%B8%EB%93%9C%EB%B2%84%EB%93%9C-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%A6%AC%EB%89%B4%EC%96%BC/unit/49434?tab=curriculum

 

 

pages/post/[id].js

//post/[id].js
import { useSelector } from 'react-redux';
import Head from 'next/head';
import { useRouter } from 'next/router';
import AppLayout from '../../components/AppLayout';
import PostCard from '../../components/PostCard';
import { LOAD_POST_REQUEST } from './../../reducers/post';
import { LOAD_MY_INFO_REQUEST } from './../../reducers/user';
import { END } from 'redux-saga';
import wrapper from '../../store/configureStore';
import axios from 'axios';

const Post = () => {
    const router = useRouter();
    const { id } = router.query;
    const { singlePost } = useSelector((state) => state.post)

    // if (router.isFallback) {
    //     return <div>로딩중...</div>;
    // }

    return (
        <AppLayout>
            {singlePost &&
                <Head>
                    <title>
                        {singlePost.User.nickname}
                        님의 글
                    </title>
                    <meta name="description" content={singlePost.content} />
                    <meta property="og:title" content={`${singlePost.User.nickname}님의 게시글`} />
                    <meta property="og:description" content={singlePost.content} />
                    <meta property="og:image" content={singlePost.Images[0] ? singlePost.Images[0].src : 'http://macaronics.iptime.org/favicon.ico'} />
                    <meta property="og:url" content={`http://macaronics.iptime.org/post/${id}`} />
                </Head>
            }

            {singlePost && <PostCard key={id && id} post={singlePost} />}

            {singlePost == null && '등록된 게시글이 없습니다.'}

        </AppLayout>
    );
};


//getStaticProps  는 다이나믹 패스에서 사용하는데,
//다이나믹이니깐 어떤것을 만들어 줘야할지 모른다 따라서,
//다음과 해당 id 만 정적인 html 만들어 준다
// export async function getStaticPaths() {
//     return {
//         paths: [
//             { params: { id: '16' } },
//             { params: { id: '17' } },
//             { params: { id: '18' } },
//         ],
//         fallback: true,
//     };
// }


//getServerSideProps

// export const getStaticProps = wrapper.getStaticProps(async (context) => {
//     const cookie = context.req ? context.req.headers.cookie : '';

//     console.log("context    : ::: ", context);

//     axios.defaults.headers.Cookie = '';
//     if (context.req && cookie) {
//         axios.defaults.headers.Cookie = cookie;
//     }
//     context.store.dispatch({
//         type: LOAD_MY_INFO_REQUEST,
//     });
//     context.store.dispatch({
//         type: LOAD_POST_REQUEST,
//         data: context.params.id,
//     });
//     context.store.dispatch(END);
//     await context.store.sagaTask.toPromise();
// });

//새로 고침시 유지
export const getServerSideProps = wrapper.getServerSideProps((store) => async ({ req, res, ...etc }) => {

    const cookie = req ? req.headers.cookie : '';
    axios.defaults.headers.Cookie = '';
    if (req && cookie) {
        axios.defaults.headers.Cookie = cookie;
    }

    store.dispatch({
        type: LOAD_MY_INFO_REQUEST,
    });

    store.dispatch({
        type: LOAD_POST_REQUEST,
        postId: req.url.replace('/post/', '')
    });


    store.dispatch(END);
    await store.sagaTask.toPromise();
})

export default Post;

 

 

 

 

 

 

 

[Next.js] Vercel로 프론트 배포하기

2022. 1. 8. 20:56

 

 

 

 

 

 

 

 Vercel 이란

Vercel 은 Next.js 에서 제공하는 배포플랫폼으로 [빌드 + 배포 + 호스팅] 서비스를 제공한다.
Next.js 공식문서에서는 Vercel를 통한 Front Project 배포를 권장하고 있으며, github의 레파지토리를 통해 쉽게 배포 할 수 있다.

 

 

 

1️⃣ deploy 추가

Vercel 에서의 배포를 위해 pakage.json 에 deploy를 추가한다.

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  }
}

 

 

 

2️⃣ repository 등록

https://vercel.com/new 에서 github 계정으로 로그인 후 배포 할 repository를 등록하고 import project 를 클릭한다

 

 

 


 

 

 

3️⃣ Configure Project 설정

프로젝트 빌드를 위한 설정을 하는 단계이다.
BUILD COMMAND 에 pakage.json 에서 추가한 Build 명령어를 입력한다.
OUTPUT DIRECTORY 은 배포시 디렉토리의 경로이다. Vercel이 프로젝트가 출력되면 자동으로 디렉토리가 구성된다.
INSTALL COMMAND 는 빌드단계에서 package-lock.json 이 있으면 Vercel이 install 명령어를 실행하여 dependencies를 설치해준다.

환경변수가 필요하다면 Environment Variables에서 설정할 수 있고  Deploy 를  실행한다.

 

 

 

 


4️⃣ Deploy

배포를 성공하면 아래와 같이 나온다.

또한, 단순한 배포 외에도 Deployment Status를 확인하거나, Analytics 등 많은 기능을 이용할 수 있다.

 

 

 

 

 

 

 

 

 

 

 

※ 참고문서

https://nextjs.org/docs/deployment#managed-nextjs-with-vercel

 

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

나는 젊었을 때 정치에 뜻을 두고, 여러 가지 쓰라린 일들을 많이 겪었다. 실패도 한두 번 한 것이 아니다. 그러나 굴하지 않고 걸어온 덕택으로 이렇게 대통령이 될 수 있었던 것이다. 생각해보면, 내 인생은 일곱 번 넘어지고 여덟 번 일어났던 것이다. -루즈벨트

댓글 ( 4)

댓글 남기기

작성