• 로그인
  • 장바구니에 상품이 없습니다.

home2 게시판 React 게시판 선생님 invaild signature 오류가 계속 나와서 미치겠습니다.

선생님 invaild signature 오류가 계속 나와서 미치겠습니다.

2 글 보임 - 1 에서 2 까지 (총 2 중에서)
  • 글쓴이
  • #124190

    이승준
    참가자
    1번 로그인 토큰 발급 api코드
    
    import jwt, { JwtPayload } from "jsonwebtoken";
    import { MongoClient } from "mongodb";
    import { NextApiRequest, NextApiResponse } from "next";
    export default async function LoginHandler(req: NextApiRequest, res: NextApiResponse) {
      const accessSecret = process.env.ACCESS_SECRET;
      const refreshSecret = process.env.REFRESH_SECRET;
      if (!accessSecret) {
        throw new Error("ACCESS_SECRET 환경 변수가 설정되어 있지 않습니다.");
      }
      if (!refreshSecret) {
        throw new Error("REFRESH_SECRET 환경 변수가 설정되어 있지 않습니다.");
      }
      if (req.method === "POST") {
        try {
          if (!process.env.MONGODB_URL) {
            throw new Error("데이터 베이스 경로에 대한 환경 변수가 설정되어 있지 않습니다.");
          }
          const client = new MongoClient(process.env.MONGODB_URL);
          await client.connect();
          const db = client.db();
          const { id, pw } = req.body;
          const userList = db.collection("signup");
          const userInfo = await userList.findOne({ id });
          if (!userInfo) {
            res.status(403).json({ message: "일치하는 유저목록이 없습니다." });
            console.log("일치하는 회원 목록이 없습니다.");
          } else {
            if (pw !== userInfo.pw) {
              res.status(403).json({ message: "비밀번호가 일치하지 않습니다." });
              console.log("비밀번호가 일치하지 않습니다.");
            } else {
              try {
                //엑세스 토큰 발급
                const accessToken = jwt.sign(
                  {
                    id: userInfo.id,
                    password: userInfo.pw,
                    birth: userInfo.birth,
                  },
                  accessSecret,
                  {
                    expiresIn: "15m",
                    issuer: "Nike",
                  }
                );
                //리프레시 토큰 발급
                const refreshToken = jwt.sign(
                  {
                    id: userInfo.id,
                    password: userInfo.pw,
                    birth: userInfo.birth,
                  },
                  refreshSecret,
                  {
                    expiresIn: "6h",
                    issuer: "Nike",
                  }
                );
                // 리프레시 토큰은 데이터베이스에 저장
                await userList.updateOne({ id: userInfo.id }, { $set: { refreshToken: refreshToken, refreshTokenExpiresAt: new Date(Date.now() + 6 * 60 * 60 * 1000) } });
                await userList.createIndex({ refreshTokenExpiresAt: 1 }, { expireAfterSeconds: 0 });
                //엑세스 토큰은 쿠키에 저장
                res.setHeader("Set-Cookie", `accessToken=${accessToken}; HttpOnly; Secure`);
                res.status(200).json({ message: "로그인 및 토큰 발급 성공" });
                console.log("토큰 발급 성공");
              } catch (error) {
                res.status(500).json({ message: error });
              }
            }
          }
          await client.close();
        } catch (error) {
          res.status(500).json({ message: "서버에 연결을 실패했습니다." });
          console.log("서버에 연결을 실패했습니다.");
        }
      } else {
        res.status(405).json({ message: "올바른 접근이 아닙니다." });
        console.log("올바른 접근이 아닙니다.");
      }
    }
    
    위 코드로 쿠키에 accessToken이 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6InRtZHduczUyIiwicGFzc3dvcmQiOiIxMjM0IiwiYmlydGgiOiI5ODEwMDMiLCJpYXQiOjE3MTY3MjQ1NzksImV4cCI6MTcxNjcyNTQ3OSwiaXNzIjoiTmlrZSJ9.3calvmNTNUTz989X4jeQwf4TqiJ2oJcUV1VkOx67AV4
    라는 값을 가진 코드로 잘 저장되고 refreshToken도 이런 형식으로 잘 저장되고 있는데 계속 invaild signature 오류가 납니다....
    
    
    2번 유저 조회 api 코드
    import jwt, { JwtPayload } from "jsonwebtoken";
    import { NextApiRequest, NextApiResponse } from "next";
    import { MongoClient } from "mongodb";
    import cookie from "cookie";
    //로그인 유저 정보 조회
    interface CustomJwtPayload extends JwtPayload {
      id: string;
    }
    export default async function userCheck(req: NextApiRequest, res: NextApiResponse) {
      if (req.method !== "GET") {
        return res.status(405).json({ message: "허용된 작업이 아닙니다." });
      }
      if (!process.env.MONGODB_URL || !process.env.JWT_SECRET) {
        return res.status(500).json({ messgae: "서버에 대한 설정이 올바르지 않습니다." });
      }
      if (process.env.JWT_SECRET !== "jwtsecret") {
        return res.status(500).json({ message: "토큰 발급의 키가 유효한 키가 아닙니다." });
      }
      const client = new MongoClient(process.env.MONGODB_URL);
      try {
        await client.connect();
        const db = client.db();
        const userList = db.collection("signup");
        const cookies = req.headers.cookie;
        if (!cookies) {
          return res.status(401).json({ message: "쿠키가 존재하지 않습니다." });
        }
        const parsedCookies = cookie.parse(cookies);
        const token = parsedCookies["accessToken"];
        console.log("토큰재료확인", token);
        try {
          const searchToken = jwt.verify(token, process.env.JWT_SECRET);
          console.log("토큰확인", searchToken);
        } catch (error: any) {
          console.log("검증오류", error.message);
        }
        if (!token) {
          console.log("토큰이 존재하지 않습니다.");
          return res.status(401).json({ message: "토큰이 존재하지 않습니다." });
        }
        let verifyToken: CustomJwtPayload;
        try {
          verifyToken = jwt.verify(token, process.env.JWT_SECRET) as CustomJwtPayload;
          console.log("verifyToken", verifyToken);
        } catch (error: any) {
          if (error.name === "JsonWebTokenError") {
            console.log("유저확인 오류:", error.message);
            return res.status(401).json({ message: "토큰의 서명 및 형태가 변형되었습니다." });
          } else if (error.name === "TokenExpiredError") {
            return res.status(401).json({ message: "토큰이 만료되었습니다." });
          } else {
            return res.status(500).json({ message: "토큰 검증 중 오류가 발생했습니다." });
          }
        }
        const user = await userList.findOne({ id: verifyToken.id });
        if (user) {
          return res.status(201).json({ id: user.id, pw: user.pw, birth: user.birth });
        } else {
          return res.status(404).json({ message: "토큰이 존재하지 않습니다." });
        }
      } catch (error: any) {
        console.log("오류메세지:", error.message);
        return res.status(500).json({ message: "서버에 오류가 발생했습니다." });
      } finally {
        await client.close();
      }
    }
    위 코드에서 계속 invalid signature 오류가 나옵니다.
    3번 extraReducer
    
    import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
    //로그인 유무를 확인
    interface loginType {
      userInfo: {
        id: string;
        pw: string;
        birth: string;
      } | null;
      status: "idle" | "loading" | "succeeded" | "failed";
      error: string | undefined;
      isLogin: boolean;
    }
    export const fetchLoginData = createAsyncThunk("user/fetchUserData", async () => {
      try {
        const response = await fetch("/api/usercheck", {
          method: "GET",
          headers: { "Content-Type": "application/json" },
          credentials: "include",
        });
        const data = await response.json();
        console.log(data);
        if (response.ok) {
          return data;
        } else {
          throw new Error("서버에 연결을 실패했습니다.");
        }
      } catch (error) {
        throw new Error("서버 연결 중에 오류가 발생했습니다.");
      }
    });
    const initialState: loginType = {
      userInfo: null,
      status: "idle",
      error: "다시 시도하세요",
      isLogin: false,
    };
    const authSlice = createSlice({
      name: "user",
      initialState,
      reducers: {},
      extraReducers: (builder) => {
        builder
          .addCase(fetchLoginData.pending, (state) => {
            state.status = "loading";
          })
          .addCase(fetchLoginData.fulfilled, (state, action) => {
            state.status = "succeeded";
            state.userInfo = action.payload;
            state.isLogin = true;
          })
          .addCase(fetchLoginData.rejected, (state, action) => {
            state.status = "failed";
            state.error = action.error.message;
          });
      },
    });
    export default authSlice.reducer;
    몇 일 동안 이유를 찾고 있는데 못찾겠어요....
    혹시나 해서 깃허브 링크 남깁니다...
    https://github.com/LeeWinJun/nikeShop/tree/main
    
    • 이 게시글은 이승준에 의해 1 년, 1 월 전에 수정됐습니다.
    • 이 게시글은 이승준에 의해 1 년, 1 월 전에 수정됐습니다.
    #124212

    codingapple
    키 마스터
    jwt확인시 에러나는거면 jwt 까볼 때 쓰는 시크릿키가 만들 때 쓴거랑 달라서 그런게 아닐까요
2 글 보임 - 1 에서 2 까지 (총 2 중에서)
  • 답변은 로그인 후 가능합니다.

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠