
์ด๋ฒ์ ์งํํ๋ ๊ณ ๊ธ ํ๋ก์ ํธ์์๋ ๋ก๊ทธ์ธํ ์ ์ ๋ฟ ์๋๋ผ ๋ก๊ทธ์ธํ์ง ์์ ์ ์ ๋ ์ ์ํ์ฌ ๋ด์ฉ์ ๋ณผ ์ ์๋๋ก ๊ตฌํํด์ผ ํ๋ ๋ถ๋ถ์ด ๋ช ์๋ค.
๊ทธ๋ฌ๋ฉด ๋ก๊ทธ์ธ์ ํ ๋๋ header์ ์๋ ํ ํฐ์ ํ์ธ -> ๋ก๊ทธ์ธ id ์ถ์ถ -> ์ฌ์ฉ์ ์ ๋ณด ๋ฐ์๊ณผ ๊ฐ์ ๋ก์ง์ผ๋ก ๊ฐ ์ ์๋ค.
ํ์ง๋ง ๋ก๊ทธ์ธ ํ์ง ์์ ์ ์ ๊ฐ ์ ์ํ์ ๋๋ ํ ํฐ์ด ์๊ธฐ์ ํ ํฐ์ ํ์ธํ๋ ๋ฏธ๋ค์จ์ด๋ฅผ ํต๊ณผ ํ ์ ์๋ค. UnauthError๊ฐ ๋ฐ์ํ ์ ์๊ธฐ์ ๋ก๊ทธ์ธ์ ์งํํ์ฌ ํ ํฐ์ด ์๋ค๋ฉด ํ ํฐ์ ํ์ธํ์ฌ ์ ์ ์ ๋ณด๋ฅผ ๋ฐํํ๋๋ก, ํ ํฐ์ด ์๋ค๋ฉด ์ผ๋ฐ ํ์ด์ง๊ฐ ๋ณด์ด๋๋ก optional์ด ํ์ํ์๋ค.
์๋ ๋ก๊ทธ์ธํ ์ ์ ๋ง ์ ๊ทผ ๊ฐ๋ฅํ ํ์ด์ง์์๋
const extractToken = (req: Request): string | null => {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith("Bearer ")) {
return null;
}
return authHeader.split(" ")[1];
};
export const authMiddleware = async (
req: Request,
res: Response,
next: NextFunction
) => {
try {
const token = extractToken(req);
if (!token) {
throw new UnauthError();
}
const { id } = verifyAccessToken(token);
const user = await userService.getById(id);
if (!user) {
throw new UnauthError();
}
req.user = user;
next();
} catch {
next(new UnauthError());
}
};
์ด์ ๊ฐ์ด ํ ํฐ ์ ๋ณด๊ฐ ์๋ค๋ฉด "๋น์ ์ ์ด ํ์ด์ง์ ์ ๊ทผํ ์ ์์ต๋๋ค. ๋ก๊ทธ์ธ ์ํ๋ฅผ ํ์ธํด์ฃผ์ธ์" ์ ์๋ฏธ์ error๋ฅผ ๋ฑ์ผ๋ฉฐ status = 401์ด ๋์ด์ผ ํ๋ค.
๊ทธ๋ฌ๋ฉด ์ด์ ์ด๊ฒ์ ๋ก๊ทธ์ธํ์ง ์์ ์ ์ ๋ํ๋ ์ ๊ทผํ๊ฒ ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น?
export const optionalAuthMiddleware = async (
req: Request,
res: Response,
next: NextFunction
) => {
try {
const token = extractToken(req);
if (!token) {
return next();
}
const { userId } = verifyAccessToken(token);
const user = await userService.getById(userId);
if (user) {
req.user = user;
}
} catch {
} finally {
next();
}
};
์์ ๊ฐ์ด ํ ํฐ์ด ์์ ๊ฒฝ์ฐ์๋ ์ด ๋ฏธ๋ค์จ์ด๋ฅผ ๊ทธ๋ฅ ํต๊ณผํ๋๋ก next()๋ก ๋ค๋ฅธ ๋ก์ง์ผ๋ก ๋๊ฒจ์ฃผ๋ฉด ๋๋ค.
ํ์ง๋ง ์์ ์ฝ๋๋ง ๋ณด์์ ๋ ๋งฅ๋ฝ์ ๋ง์ง๋ง ํ๋ฆฐ ๋ถ๋ถ์ด ์์๋ค.
next() ๋๋ฝ๋ง์ฝ์ ๋ก๊ทธ์ธ์ ํ ์ ์ ์ธ ๊ฒฝ์ฐ,
const user = await userService.getById(userId);
if (user) {
req.user = user;
}
์ ์ ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์์ง๋ง, ๋ฏธ๋ค์จ์ด์์ ๊ฐ์ ธ์จ ์ ๋ณด์ด๊ธฐ์ ๋ค์ ๋ก์ง์ผ๋ก ๋๊ฒจ์ค์ผ ํ๋๋ฐ next()๊ฐ ๋๋ฝ๋์ด ๋๊ฒจ์ฃผ์ง ๋ชปํ๊ณ ๋ฏธ๋ค์จ์ด์ ๋จ์์๋๋ค.
error ๋ฏธ์ฒ๋ฆฌํด๋น ๋ฏธ๋ค์จ์ด์์๋ try-catch๋ฌธ์ ํตํด์ ์๋ฌ๊ฐ ์๊ธฐ๋ฉด ์ก์์ ์ ์ญ error ํจ์๋ก ๋๊ฒจ์ฃผ๋๋ก ์ค๊ณํ์๋ค.
} catch {
} finally {
next();
}
};
ํ์ง๋ง ์ฝ๋๋ฅผ ๋ค์ ๋ณด๋ ์ ์ error๋ฅผ ์ก์์ค์ผ ํ๋ catch์๋ next๊ฐ ์์ด์ error๋ฅผ ๋๊ฒจ์ฃผ์ง ๋ชปํ๊ณ ์๋ค. ์ด๋ ๊ฒ ๋๋ฉด
1) verifyAccessToken์์ ํ ํฐ์ด ์์ง๋ง ์ ํจํ์ง ์์ ๊ฒฝ์ฐ
2) ํ ํฐ์ ์ ํจํ์ง๋ง userId๋ฅผ ํตํด์ ์ ์ ๋ฅผ ์ฐพ์ผ๋ ค๊ณ ํ ๋ ํด๋น ์ ์ ๊ฐ ๋ฐ์ดํฐ ๋ฒ ์ด์ค์ ์๋ ๊ฒฝ์ฐ
์์ ๊ฐ์ ์ํฉ์์๋ ์์ด๊ฐ ์์์๋ ์ด๋ฅผ ๋ฌด์ํด๋ฒ๋ฆฌ๊ฒ ๋๋ค.
๋ค์ ์๋น์ค์์๋ ์ค๋ณต ์๋ฌ ์ฝ๋๋ฅผ ํผํ๊ธฐ ์ํด์ ๋ง์ฝ์ ์๋ฌ๋ฅผ ์ก๋ ์กฐ๊ฑด๋ฌธ์ ๋ฃ์ง ์์๋ค๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํด๋ ์ ํํ ์์ธ ๋ฐ ์์น๋ฅผ ํ์ธํ๊ธฐ ํ๋ค ๊ฒ์ด๋ค.
finally next() ์ค๋ณต ํธ์ถ if (!token) {
return next();
}
ํ ํฐ์ด ์์ ๋๋ ์๋ ํด๋น ๋ฏธ๋ค์จ์ด๋ฅผ ์ข
๋ฃํ๊ณ , ๋ค์ ์๋น์ค ๋ก์ง์ผ๋ก ๋์ด๊ฐ๋ ๊ฒ์ด ์ด ๋ฏธ๋ค์จ์ด์ ํน์ง์ด๊ธฐ์ ์ฌ๊ธฐ์์ next() ๋ฌด์กฐ๊ฑด ์์น๋์ด์ผ ํฉ๋๋ค.
ํ์ง๋ง,
} catch {
} finally {
next();
}
};
try ๋ธ๋ก ๋ด๋ถ๊ฐ ์๋ ๋์ธ finally์์ next๊ฐ ํธ์ถ๋๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
try ๋ด๋ถ์ next๊ฐ ์กด์ฌํ์ง ์๊ณ ๋ง์ฝ ์๋ฌ๊ฐ ์๋ค๊ณ ํด๋ catch ๋ฌธ ์์์๋ ์๋ฌด๊ฒ๋ ์์ด์ ์๋ฌ๋ฅผ ์ฐพ์ ์ ์๊ธฐ์ finally์์์ next()๋ ๋ฌด์กฐ๊ฑด ํธ์ถ์ด ๋ ๊ฒ์
๋๋ค.
[์์ ์ฌ๊ณ ์ํฉ]
1. ํ ํฐ์ด ์กด์ฌํ์ฌ if(!token)์ ํต๊ณผ
2. verfyAccessToken(token)์์ ์ ํจํ์ง ์์ ํ ํฐ์ผ๋ก ์ธํ ์๋ฌ ๋ฐ์
3. catch์์๋ ์๋ฌด๊ฒ๋ ์ก์ ์ ์์
4. finally ๋ธ๋ก์ผ๋ก ์์ next() ํธ์ถ
5. optionalAuthMiddleware ํจ์ ์ข
๋ฃ -> next() ํธ์ถ
๋ง์ฝ์ ์ด ๋ฏธ๋ค์จ์ด ๋ค์์ ๋ ๋ค๋ฅธ ๋ฏธ๋ค์จ์ด๋ ๋ผ์ฐํธ ํธ๋ค๋ฌ๊ฐ next()๋ฅผ ํธ์ถํ๋ ๋ก์ง์ ๊ฐ์ง๊ณ ์๋ค๋ฉด,
next()๊ฐ ํ ์์ฒญ์ ๋ํด ๋ ๋ฒ ์ด์ ํธ์ถ๋ ์ ์๋ค. ํน์ ๋ผ์ฐํธ์์ ํด๋ผ์ด์ธํธ๋ก ์ ๋ณด๋ฅผ ๋ณด๋ธ๋ค๋ฉด res.status.send ์ด๋ฌํ ์ํฉ์์๋ ์๋์ ๊ฐ์ error ๋ฉ์์ง๋ฅผ ๋ง์ฃผํ ์ ์๋ค.
Cannot set headers after they are sent to the client ์ค๋ฅ
-> ์ด๋ฏธ ํด๋ผ์ด์ธํธ์๊ฒ๋ ์๋ต์ด ์ ์ก๋์์ง๋ง ๋ค์ ์๋ต์ ๋ณด๋ด๋ ค๊ณ ์๋ํ ๋ ๋ฐ์ํ๋ ์๋ฌ
์ด์ธ์๋ ์์ฒญ ์ฒ๋ฆฌ ํ๋ฆ์ด ๊ผฌ์ฌ์ ์๋์น ์์ ๋ฏธ๋ค์จ์ด๊ฐ ์คํ๋๊ฑฐ๋, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ด ์ค๋ณต์ผ๋ก ๋ฐ์ํ๊ฑฐ๋ ์๋ฒ๊ฐ ๋ถ์์ ํด์ง ์ ์๋ค.
finally์ try์์์ ์คํ์ด ๋๋ catch๋ก ์๋ฌ๋ฅผ ๋๊ธฐ๋ ์คํ๋๋ ๋ธ๋ก์ด๊ธฐ์ try ์์์ ํด๊ฒฐ๋์ด ํด๋ผ์ด์ธํธ๋ก ์๋ต์ ๋ณด๋ด๊ฒ ๋๊ณ -> next()๊ฐ ํ ๋ฒ ๋ ์คํ์ด ๋๋ค. ์ด๋ด ๊ฒฝ์ฐ ์ค๋ณต ํธ์ถ๋ก ์ด๋ฏธ ์๋ต์ด ์๋ฃ๋ ๋ค์ ๋ ๋ค์ ํค๋๋ฅผ ์ค์ ํ๊ฑฐ๋ ์๋ต์ ๋ณด๋ด๋ ค๊ณ ์๋ํ๊ฒ ๋๋ค.
๊ผญ ๋ฏธ๋ค์จ์ด์์ ์ฌ์ฉํ ์์๋,,, catch๊น์ง๋ง ์์ฑ + try ์์์ return next()๋ฅผ ํตํด์ ์ดํ ๋ถํ์ํ ์ฝ๋ ์คํ์ ๋ง์์ฃผ์!