HTTP 전용 쿠키 내에 JWT 토큰을 저장하는 방법
자격되는 JWT를 하여 JWT에 대해 ./api
루트를 설정합니다.
한편 AngularJS는 이 토큰을 가져와서 세션스토리지에 저장하고 매번 auth interceptor를 사용하여 토큰을 서버로 되돌립니다.
나는 이 관행이 얼마나 위험한지 더 최근에 알게 되었다.
이 시나리오에서는 토큰의 앞뒤 전송 방법을 이해하고 있습니다.단, JWT를 클라이언트측 Javascript가 읽을 수 없는 안전한 HTTP 전용 쿠키에 저장하고 싶을 때의 방법을 대략적으로 설명해 주실 수 있을까요?
예: credential이 성공한 경우
- cookie가 서버에 생성됩니다.
- 쿠키와 동시에 JWT를 만듭니다.
- JWT를 토큰이라는 쿠키 속성에 저장합니다.
어떻게 작동하는지에 대한 정신적 모델을 얻으려고 합니다.올바른 credential 로그인을 하면 서버가 쿠키 내의 토큰을 모두 전송하기 때문에 이렇게 하면 인증 대행 수신기가 필요하지 않습니다.
쿠키를 취급하는 것은 공평한 부분이지만, 높은 수준에서 쿠키는 웹 서버가 설정할 수 있는 데이터이며, 쿠키가 유효하고 요청에 적용 가능한 한 사용자의 웹 브라우저에 의해 저장되고 브라우저가 동일한 서버에 향후 요청을 할 때 서버로 반환됩니다.
(Cookie의 송신을 보증하는 것은 브라우저 자체이기 때문에 Angular intercept를 사용할 필요가 없습니다.)
HTTP 전용과 같은 일부 특수 플래그 옵션 외에도 더 높은 수준에서 지정된 도메인 및 경로에 연결되도록 쿠키를 설정할 수 있습니다.예를 들어, 서버는 나중에 브라우저에서 경로에서 수행된 요청에만 전송되도록 쿠키를 설정할 수 있습니다.
요약하면 cookie는 HTTP 상태 관리 메커니즘입니다.자세한 내용은 관련 RFC 2617을 참조하십시오.
이와는 대조적으로 JWT는 잘 알려진 표현과 몇 가지 관례를 따르는 일부 데이터일 뿐입니다.특히 JWT는 헤더, 페이로드 및 시그니처 섹션으로 구성되어 있으며 대부분의 JWT 사용 사례에서 페이로드 크기를 작게 유지하는 것이 좋습니다.자세한 내용은 JSON 웹 토큰 시작을 참조하십시오.
앞의 기사를 보면 JWT의 마지막 표현은 점으로 구분된3개의 Base64url 부호화 문자열임을 알 수 있습니다.이는 JWT가 쿠키 값 등 HTTP 내에서 사용하기에 적합하다는 것을 의미하기 때문에 특히 중요합니다.
이 사양에 따라 브라우저가 쿠키당 최대 4096바이트의 쿠키만을 지원한다는 것을 명심해야 합니다(쿠키 이름, 값 및 속성 길이의 합계로 측정).토큰에 많은 데이터를 저장하지 않는 한 문제가 발생하지 않지만 항상 고려해야 합니다.예, JWT 토큰을 여러 개의 쿠키로 나눌 수도 있지만, 상황은 점점 복잡해지기 시작합니다.
또한 쿠키에는 유효기간 개념이 있으므로 인증 범위 내에서 사용할 경우 JWT 자체도 유효기간 개념이 있기 때문에 이를 염두에 두십시오.
를 JWT에 하는 것에 몇 .localStorage
/sessionStorage
예를 들어 스토리지와 관련된 도메인 내의 Javascript 코드가 토큰을 읽을 수 있는 경우, 그 의미를 이해해야 합니다.단, HTTP 전용 쿠키도 실버 벌릿이 아닙니다.나는 다음 기사를 읽고 싶다.쿠키 vs 토큰: 최종 가이드
기존 세션 식별자 쿠키와 토큰 기반(JWT) 인증 시스템의 차이점에 초점을 맞추고 있습니다. 토큰 저장 위치라는 섹션은 스토리지의 보안 관련 측면을 다룰 때 읽기를 보장합니다.
TL의 개요:DR 담당자:
웹 사이트가 직면한 가장 일반적인 공격 벡터는 Cross Site Scripting(XSS; 사이트 간 스크립팅)과 Cross Site Request Formature(XSRF 또는 CSRF; 사이트 간 요청 위조)입니다.사이트 간 스크립팅(Cross Site Scripting) 공격은 외부 엔티티가 웹 사이트 또는 앱 내에서 코드를 실행할 수 있을 때 발생합니다(...).
공격자가 도메인에서 코드를 실행할 수 있는 경우 로컬 저장소에 있는 JWT 토큰이 취약합니다. (...)
JWT를 로컬 스토리지와 함께 사용하는 경우에는 사이트 간 요청 위조 공격이 문제가 되지 않습니다.한편 JWT를 쿠키에 저장해야 하는 경우 XSRF로부터 보호해야 합니다.
(나머지는 내 거야)
기본적으로 사용자가 로그인할 때 데이터베이스에 저장된 리프레시 토큰 오브젝트에 access_token(jwt)을 저장합니다.다음 저장된 오브젝트의 예를 참조하십시오.
const newToken = new RefreshToken({
issuedUtc: moment().unix(), /* Current unix date & time */
expiresUtc: moment().add(4, "days").unix(), /* Current unix date&time + 4 days */
token: refreshToken, /* Generate random token */
user: data.id, /* user id */
/* Signing the access Token */
access_token: jwt.sign(
{ sub: data.id, user: userWithoutHash },
Config.secret,
{
issuer: "http://localhost:3000",
expiresIn: "30m", // Expires in 30 minutes
}
),
});
생성 및 저장된 랜드토큰은 httpOnly cookie로 브라우저로 전송됩니다.
res.cookie("refreshToken", newToken.token, {
httpOnly: true,
sameSite: "strict",
});
브라우저는 모든 요구에 대해 쿠키를 전송하므로 보호된 경로에서 미들웨어를 사용하여 쿠키에서 토큰을 가져오고 데이터베이스에서 토큰이 존재하는지 확인합니다.또한 토큰이 만료되지 않았는지 확인하고 새로 고침 토큰에 대해 데이터베이스에 저장된 액세스토큰을 확인한 후 기한이 만료된 경우 jwt를 새로 서명합니다.데이터베이스 내의 리프레시 토큰을 갱신하여 사용자가 보호된 루트로 진행할 수 있도록 합니다.유효한 경우 사용자가 보호된 루트로 진행할 수 있도록 하기만 하면 됩니다.리프레시 토큰이 만료된 경우 사용자를 로그인 페이지로 리다이렉트하고 마지막으로 리프레시 토큰이 수신되지 않은 경우 로그인 페이지로 리다이렉트합니다.
var cookie = await getcookie(req); // get the cookie as js object using my custom helper function
/* Check if refresh token was received */
if (cookie.refreshToken) {
/* Check find the refresh token object in the database */
var refreshToken = await RefreshToken.findOne({
token: cookie.refreshToken,
});
/* Check if the refresh token is still valid using expiry date */
if (moment.unix(refreshToken.expiresIn) > moment.now()) {
/* If the condition is fulfilled try to verify the access token using jwt */
jwt.verify(refreshToken.access_token, Config.secret, async (err, result) => {
/* in callback check for error */
if (err) {
/* If error this means the access_token is expired, so find and update the user's refresh token with a newly signed access token */
await RefreshToken.findByIdAndUpdate(refreshToken.id, {
access_token: jwt.sign(
{ sub: result.id, user: result.user },
Config.secret,
{
issuer: "http://localhost:3000",
expiresIn: "30m", // Expires in 30 minutes
}
),
});
/* Proceed to save the user in a local variable then call next */
res.locals.user = result.user;
return next();
}
/* If no error proceed by saving the user in a local variable then call next */
res.locals.user = result.user;
return next();
});
} else {
/* If the refresh token is expired, then redirect to log in */
return res.status(401).redirect('/login');
}
} else {
/* If no refresh token is provided, then redirect to log in */
return res.status(401).redirect('/login');
}
이것은 내가 생각해낸 것이기 때문에 완전한 증명이라고는 말할 수 없지만, dom에서는 httpOnly cookie에만 액세스 할 수 없기 때문에 DOM에서 악의적인 스크립트를 실행해도 리프레시 토큰에 액세스 할 수 없습니다.또한 리프레시 토큰이 악당의 손에 넘어가도 리프레시 토큰은 취득할 때까지 전혀 정보를 보유하지 않기 때문에 사용할 수 없습니다.서버에 접속합니다.따라서 서버에 오른쪽 cors 헤더가 설정되어 있는 한 리프레시 토큰을 사용하여 정보가 유출될 가능성은 거의 없습니다.
언급URL : https://stackoverflow.com/questions/39810741/how-to-store-a-jwt-token-inside-an-http-only-cookie
'programing' 카테고리의 다른 글
Angular에서 응용 프로그램 전체 HTTP 헤더 설정JS (0) | 2023.03.12 |
---|---|
컴포넌트에 대한 React onClick 이벤트 (0) | 2023.03.12 |
몽구스:전체 사용자 목록 가져오기 (0) | 2023.03.07 |
(각의 라우터)해결 프로세스 중 애니메이션 로드 표시 (0) | 2023.03.07 |
@Transactional with JPA and Hibernate의 사용법은 무엇입니까? (0) | 2023.03.07 |