NodeBird SNS 서비스

송은우·2022년 1월 11일
0

관계가 1:1, 1:N N:M 같은 것들이 있다면 mysql 쪽이 더 편하기는 함. 경험이 있으면 좋음

npm init 이후에 package.json 에 가서 "start":"nodemon app" 적기
npx sequelize init (sequelize-cli에 있음)

res.locals.error = process.env.NODE_ENV !== "production" ? err : {};
이 부분이 개발 중인지 아닌지를 판단해서 그 결과로 에러를 어떻게 보여줄 지 판단함
실제 서비스에서는 에러 페이지도 사용자 친화적으로 만들어야 함.

sequelize 에서 allowNull: true인 경우에 unique가 붙었을 경우 빈 값은 서로 다르다고 인정해줌.
비밀번호 같은 경우는 HASH화를 하면 길어진다는 점을 생각해 100글자 정도로 넉넉하게 최대 길이를 잡아두는 것이 좋음
비밀 번호 allowNull :true인 경우는 sns 로그인 같은 것들
defaultValue:'local'이라는 것이 sns 로그인 같은 것들을 설정해 줌.
그럴 때 snsId를 이용해 저장해 기억해야 제대로 작동 가능함.

img: {
          type: Sequelize.STRING(200),
          allowNull: true,
        },
        이런 식으로 이미지 하나를 저장 할 수 있지만, 여러개를 하려면
        hasMany로 관계를 만들어 주는 방법 밖에 없음
db.User.belongsToMany(db.User, {
      foreignKey: 'followingId',
      as: 'Followers',
      through: 'Follow',
    });
    db.User.belongsToMany(db.User, {
      foreignKey: 'followerId',
      as: 'Followings',
      through: 'Follow',
    });

db 관계 설정이 매우 중요하다.
여기 foreignKey를 보면 as와 서로 반대가 되어있음. follower 가져올 때 followingid를 가져올 수 있음.
followerId followingId
1 3 =>1이 3을 팔로우 함.
get 3번에서 자기를 팔로잉 하는 사람을 가져오려면 followingId를 통해서 검색한 결과가 followerId 가 되어야 해서

const 변수명=require('')
여기서 변수 명은 아무거나 가능하다.
module.exports나 es6으로 바꾼다면 export default 에 해당하는 것을 그냥 그 명칭으로 받아오고, 함수인 경우에는 그냥 변수명() 으로 실행해버릴 수도 있다.

enum은 타입 조금 상세하게.
JWT는 헤더, 페이로드, 시그니처 가 있음.
페이로드에 데이터가 많이 들어감. 권한 등.
JWT 비밀 키를 알면 앞도 다 알 수 있음.
헤더, 페이로드는 비밀 키에 따라 변화하지 않음. 따라서 민감한 내용은 넣으면 안 됨.
JWT의 장점은 토큰 자체에 데이터가 있기에 DB로 요청의 수가 적음.
단점은 데이터가 있기에 교환 시간이 오래 걸림.
쿠키에 넣어도 되지만 보통 헤더에 authorization key를 주고, JWT secret을 넣어 서버에 보내면 깔끔하게 처리가 가능하다.

req 안에 데이터 넣는 것은 미들웨어 끼리 데이터 전달 대표 방법

api 서버는 도메인 검사, 등 여러 검사 후
토큰 발급
이후에 앞으로 발급받은 토큰을 이용해 api 서버에 데이터 요청

항상 에러를 무조건 봐야 됨.

npm i --save 는 공식문서 잘 안 읽는 구나 라고 생각하면 됨. 사실 큰 의미 없음.
한 번 내놓은 코드는 무조건 유지해야됨. 버그 수정이 아니라, API를 다른 사람이 쓰다가 못 쓰게 하면 문제가 생김 따라서 새롭게 추가해야 됨. deprecated를 쓰고
모든 라우터에 다 적용 되는 거는 가장 위에 빼서
router.use(라우터명);
미들웨어 순서가 중요할 수 있음.
api limiter, 토큰 같은 걸로 사용자를 골라 받을 수 있음
카카오 로그인의 경우는 RESTAPI 키와, JS키를 따로 둠.
그렇게 했을 때 장점은 RESTAPI 키는 노출이 되지 않아 상대적 안전(서버용)
지금 코드에서는 client_secret이 RESTAPI키의 역할을 하기에 노출을 시키면 안 되지만 실습용 이라서 JS 키 처럼 그냥 보냄
해커가 마음대로 우리를 사칭해 요청을 보내는 경우가 생김 유료 API인 경우는 돈만 우리가 낼 수도 있음

CORS
지금까지는 서버에서 서버로 호출.
브라우저에서 서버로 호출.

브라우저에서 서버로 요청을 보내는 상황이고, 도메인이 서로 다를 때만 CORS가 발생함. 브라우저가 발생시킴. 확장 프로그램으로 처리해버릴 수도 있음. 해결은 서버가 한다는게 매우매우 특이함
res.setHeader('Access-Control-Allow-Origin',"허용 주소");가 있어야 요청을 할 수 있음.
res.setHeader('Access-Control-Allow-Credentials',"true"); 이거는 쿠키 전달 안 되는 문제 해결

실무는 npm i cors 라는 거를 이용해서 app.use(cors());로 해결해버림 그러면 잘 해결해줌. 보안상의 문제로 이렇게 설계가 됬다

app.use(cors({
 origin:true, 
 credentials:true, //쿠키 전달 허용
}); 

이런 방식으로도 해결 가능

cors는 각각 라우터 단위로 따로 적는게 좋음. 로그인 같은 것에도 cors가 적용이 되어버림.

const domain = await Domain.findOne({
    where: { host: url.parse(req.get("origin"))?.host },
  });
  if (domain) {
    cors({
      origin: req.get("origin"),
      credentials: true,
    })(req, res, next);
  } else {
    next();
  }

이렇게 처리를 하는 방식으로 보통 해결을 많이 함
브라우저에서 프록시 서버로 보내고 서버에서 보내는 방식으로도 해결할 수도 있음. (프록시 서버) 확장 프로그램의 사례

테스트를 하는 이유

기능이 많다면 수작업 힘듦
프로그램이 프로그램을 테스트 할 수 있도록 자동화
테스트 환경을 실제 환경과 비슷하게 흉내
철저하게 테스트 해도 에러를 완벽하게 막을 수 없음.
(스타트 업의 경우에는 회귀 테스트를 만들어 줌. 버그를 테스트로 만들기)

테스트 툴 jest가 편함.
테스트도 워낙 유명해 npm test 가능
tdd(test driven development 개발 기법)와 test(단순 테스트)는 다름.

test(설명,()=>{
 expect(1+1).toEqual(2);
}

실제 코드를 변경하기 전에 다양한 파일 내에 테스트를 흩뿌려놓기
단위 테스트: 함수 내에 또는 하나의 똑 떯어뜨릴 수 있는 가장 최소 단위로 테스트 하는 것
최대한 많은 시나리오를 만들어야 함. (if문 분기 기준)
같은 테스트를 dexcribe('설명',()=>{
test 어쩌구 저쩌구 그룹화
}
실제 코드 작성 전에 테스트부터 시작하는 것이 TDD이다.
express 의 req, res, next일 필요 없이
const req={};
const res={};
const next=jest.fn(); 가 가능함. 이거는 가짜 함수 표현

가짜로 테스트 하는 것을 모킹이라고 함
공통 된 것은 밖으로, 각자는 안으로.
describe, jest는 그냥 전역변수 라고 생각해도 됨 require 필요 없음.

profile
학생의 마음가짐으로 최선을 다하자

0개의 댓글