2022.06.01 - TIL [코드내용 개선]

mython·2022년 5월 31일
0

TIL

목록 보기
4/31

코드내용 개선

[기존 코드]

router.post("/posting", async (req, res) => {
    try {
        const {nickName, password, title, content} = req.body;

        const createdPosting = await Posting.create({nickName, password, title, content});
        
        res.send({ users: createdPosting});
    } catch (error) {
        
        res.status(400).send();
    }
});
  • 나는 보통 req.body 를 이용해서 스스로 입력할 것만 생각하면서 위처럼 코드를 작성하였다. 그래서 썬더 클라이언트로 실행할때 body 값에 nickName, 부터 content 까지 전부다 body 값에 넣어주면서 했다.

근데 영성님한테 다른걸 물어보다가 선더클라이언트에서 할때 좀더 편하게? 할수 있는 코드를 배웠다.

[개선된 코드]

const authMiddleware = require("../middlewares/auth-middleware");

router.post("/posting/", authMiddleware, async (req, res) => {
 
        const {nickName} = res.locals.user
       
        const {title,content} = req.body;
    
        const createdPosting = await Posting.create({ nickName,title, content});
     
        res.json({ user: createdPosting});
        
    
});
  • 달라진 점은 res.body 로 내가 직접 입력하던 거를 위쪽에 미리 만들어둔 authMiddleware 를 연결해서 토큰 값을 받아와 res.locals.user 를 이용해서 닉네임은 미리 받아놓고 시작하는 방법이다.

이렇게 시작하면

지금의 사진 처럼 로그인할때 생성된 토큰값을 auth에 미리 입력해놓고
body 쪽에는 title 과 content 만 입력해줘도 되서 훨씬 편하다.


이러한 방법을 위해 추가적이 설명을 덧붙이자면

위에서 사용한 res.locals.user

const jwt = require("jsonwebtoken");
const Object = require("../schemas/object");


module.exports =  (req,res,next)=>{              ///미들웨어의 기본 시작
    const {authorization} = req.headers;
    const [tokenType, tokenValue] = authorization.split(' ');     /// 1.
    
    if (tokenType !== "Bearer"){
       

       res.status(401).send({
           errorMessage : "로그인 후 사용 하세요",
       }); 
       return;          ///오류가 났으니 더이상 진행시키면 안되서 return
    } 
    try {
        const { userId } = jwt.verify( tokenValue, "this-is-key");    /// 복호화 겸, 검증을위한 코드

        Object.findById(userId).exec().then((Object) => {     /// 데이터베이스에서 사용자 정보를 불러와서
            res.locals.user = Object;     /// 로컬스.user 라는 공간에 담는데
            next();                      /// {userId} 변수선언 후 userId 찾기
        });                                ///미들웨어는 넥스트가 항상 잇어야      
        
    
    } catch (error) {
        
        res.status(401).send({
            errorMessage : "로그인 후 사용 하세요",
        });
        return;
    }
};


1. 스플릿 이라는 내장함수를 사용하여 다음과 같이 코드를 작성하면 authorization 안의 값인
 * Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NTM2OTk1NTJ9._IoLmTQvM4Vn8XYs27RliucFAY_VUWpp8WPqtUjdwVc
 * 위 값을 부분을 배열로 나눠줌
 * 그래서 나누면 [Bearer,  eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NTM2OTk1NTJ9._IoLmTQvM4Vn8XYs27RliucFAY_VUWpp8WPqtUjdwVc]
 * 이렇게 나온다. 그럼 배열값의 0번째 값인 tokenType 이고, 1번째 값이 tokenValue 다
 * 우리가 필요한건 토큰 value 값이다. 즉 나눠놓고 필요한거만 가져다가 쓸려고 저 함수를 쓴것.
 */

위의 코드내용은 미리 만들어놓은 미들웨어 폴더 내부의 auth-middleware 파일 내부의 코드인데 여기의 중간부분의 res.locals.user 으로 설명할수 있다.


최대한 간단하게 설명하자면 유저의 정보를 토큰의 형태로 암호화를 하였고, 그 암호화를 푸는 키를 만들어둔후

res.locals.user 가 적혀있는 저 한줄에 유저의 정보를 저장한 셈이된다.

res.locals.user에 유저정보 저장 -> 토큰이라는 박스로 이중포장 -> 그걸 풀수있는 암호화키도 설정


이제 이 res.locals.user 를 라우터 안에서 사용하면 내가 스키마의 형태로 저장해놓은 유저 정보를 그 라우터 안에서 사용할 수 있는것이다. 이제 거기서 나는 게시물 api 에서는 res.locals.user 안에 있는 nickName만 꺼내다 쓴것.


같은 아이디로 여러개의 게시물을 못만드는 오류

[에러 사진]

  • 이러한 형태로 오류가뜨면 보통 스키마 혹은 위쪽에 적힌 MonggoserverError 라는 문구에서 알수 있듯이

db의 오류일 확률이 높다.

  • 지금 사진에서는 이미 지워버려서 없지만, 처음 내가 스키마를 만드는 과정에서 지금은 불필요한 유니크 값들을 몇개 설정해놓은 뒤 db에 저장한 값들이 남아있어서 index안에 지금처럼 _id 만 있는게 아니라 몇개의 값이 더 있엇다.

  • 그러다보니 아마도 닉네임에 유니크값을 부여한 적이 있었고, 그 상태로 db에 저장한 기록 때문에 현재의 스키마에는 없지만 db상에서는 유니크값이 그대로 있는 유효한 값 때문에 현재 db에 넣을려는 값에까지 영향을 끼친것 같다.

지우고 나니깐 바로 중복해서도 입력이 되었다.

profile
삽질도 100번하면 요령이 생긴다. 부족한건 경험으로 채우는 개발자

0개의 댓글