* JWT 설명
: JWT (Json Web Token) 은 가장 많이 사용하는 인증 방식 입니다.
웹과 앱에서 동일 한 인증 방식을 가져갈 수 있으며, 서버에서 별도의 정보를 가지고 있지 않기 때문에 서버가 확장할 때도 효율적입니다.
로그인 성공 시 액세스 토큰(JWT)은 웹 브라우저의 쿠키에 저장됩니다. 그 이후 프런트엔드에서 인증이 필요한 API를 사용할 때 액세스 토큰을 가져와서 헤더에 포함시켜서 백엔드에 전달합나다.
백엔드 미들웨어는 토큰이 유효한지 검증한 후 유효하면 API를 실행 합니다. 유효하지 않은면 401로 인증실패 에러를 발생시킵니다.
* 필요 한 모듈
npm install jsonwebtoken dotenv cookie --save
npm i --save-dev @types/jsonwebtoken @types/cookie
* JWT 토큰 생성
(1) 프런트엔드에서 아이디, 패스워드를 로그인 API 요청과 함께 보냅니다.
(2) 백엔드에서 JWT Secret, 회원 id, 토큰 만료시간으로 Access Token을 생성해서 프런트엔드에 응답 합니다.
(3) 프런트엔드에서는 크롬 브라우저의 쿠키에 Access Token을 저장합니다.
3-3) JWT 토큰 검증
(1) 프런트엔드에서는 인증이 필요한 API를 사용할 때 쿠키에서 AccessToken을 가져와서 헤더의 Authorization 에 넣어서 요청을 보냅니다.
(2) 백엔드 미들에어는 AccessToken을 JWT Secret으로 유효한지 검증합니다.
(3) 유효한 경우 API를 실행합니다. 유효하지 않은면 401 인증 실패 에러를 전달합니다.
* JWT 토큰 사용시 주의 사항
- 로그인 시에 아이디와 비밀번호가 서버로 넘어오면 유저의 정보가 맞는지 확인 후 쿠키에 토큰을 발급 함. 그 후 다른 페이지에서의 인증도 이 토큰을 통해 인증이 이뤄진다.
그러나 백엔드와 프론트엔드의 주소가 다른경우 로그인이 성공하더라도 별다른 에러 없이 인증이 이뤄지지 않는다. 이는 도메인 주소가 다르면 쿠키가 전송이 되지 않기 때문임.
이를 해결하기 위해 프론트에서 axios 요청을 보낼 때 withCredentioals 설정이 필요하며, 백엔드에서 받아줄 때에는 cors 부분에 credentials : true 설정이 필요하다.
즉 response header에 Access-Control-Allow-Credentials 를 설정해 준다.
// 백엔드 쪽 설정
app.use(cors({
origin,
credentials: true
}));
// 프론트 쪽 설정
const handleSubmit = async (event: FormEvent) => {
event.preventDefault();
console.log("test");
try {
const res = await axios.post(
"/auth/register",
{
email,
password,
username,
},
{
withCredentials: true,
}
);
console.log("res", res);
// router.push("/login");
} catch (error: any) {
console.log("error", error);
setErrors(error.response.data || {});
}
};
* 자바스크립트에서 Cookie 관련 추가 정보
- httpOnly
: 이 옵션은 자바스크립트 같은 클라이언트 측 스크립트가 쿠키를 사용할 수 없게 합니다. document.cookie를 통해 쿠키를 볼 수 도 없고 조작할 수도 없다.
- secure
: https 연결에서만 쿠키를 사용 할 수 있다.
- samesite
: 요청이 외부 사이트에서 일어날 때 브라우저가 쿠키를 보내지 못하도록 막아줌, XSRF 공격을 막는데 유용
- expires/max-age
: 쿠키의 만료 시간을 정해준다. 이 옵션이 없으면 브라우저가 닫힐 때 쿠키도 같이 삭제 된다.
res.set("Set-Cookie", cookie.serialize("token", token,{
httpOnly: true,
maxAge: 60 * 60 * 24 * 7, // 1 week
path: "/",
}));
* 참고자료
https://cloud.google.com/iot/docs/how-tos/credentials/jwts?hl=ko#iot-core-jwt-nodejs
'ETC' 카테고리의 다른 글
[windows] 연결한 적이 있는 wifi 비밀번호 확인 (0) | 2023.07.07 |
---|---|
[NGINX] Nginx 버전 숨기기 (0) | 2023.05.09 |
[MAC] 맥북의 MAC Address 변경 하기 (0) | 2022.11.04 |