토큰을 쿠키, 로컬 스토리지 또는 세션에 저장해야 합니까?
React SPA, Express, Express-session, Passport, JWT를 사용하고 있습니다.토큰을 저장하기 위한 클라이언트 측 스토리지 옵션 중 몇 가지가 헷갈립니다.쿠키, 세션 및 JWT / 여권.
을 저장할 수 저장해야 ?req.sessionID
많은 웹 사이트가 쇼핑 카트 토큰을 저장하기 위해 쿠키를 사용합니다.지금까지는 쿠키를 추가하지 않고 세션 ID를 기반으로 쇼핑 카트 데이터를 저장했습니다.
사용자들이 제 했을 때, 저는 그것을 의 웹사이트와 입니다.
req.sessionID
그런 다음 쇼핑 카트나 사용자 세션과 같은 데이터베이스의 데이터를 가져옵니다.
키를를 보관 ?? ???할 수 은 '접근하다'입니다.req.sessionID
이치
그리고 두 번째는
은 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★passport-google-oauth20
에 성공하면 하려면 , 가 있습니다.?token='sdsaxas'
이 경우 나는 많은 의견 차이를 보인다. 누군가는 그것을 로컬 스토리지에 저장했고 누군가는 그것을 JWT를 사용하여 토큰으로 변환하여 쿠키에 저장했다.
jwt.sign(
payload,
keys.jwt.secretOrPrivateKey,
{
expiresIn:keys.jwt.expiresIn // < i dont know what is this expired for cookies or localstorage ?
}, (err, token) => {
res.redirect(keys.origin.url + "?token=" + token);
});
세션을 사용하여 세션과 관련된 모든 내용을 저장할 수 있습니까?ID(쿠키 또는 로컬 스토리지 없음)
React SPA를 사용하기 때문에 페치를 1회 또는 매 페이지마다 새로고침 및 데이터 취득 후 redux에 저장합니다.
이 답변은 스테이트리스 어프로치에 근거하고 있기 때문에 기존의 세션 관리에 대해서는 언급하지 않습니다.
완전히 다른 두 가지 질문을 했습니다.
- 쇼핑 카트 - 비즈니스 기능과 더 관련이 있습니다.
- OAuth 2 & JWT - 보안 및 인증 관련
e커머스 웹 사이트 사용자로서 출근 중 모바일 기기에서 장바구니에 추가한 아이템은 집에 도착한 후 PC에서 웹사이트에 로그인했을 때 장바구니에서 사용할 수 있어야 합니다.따라서 카트 데이터는 백엔드 DB에 저장하여 내 사용자 계정에 링크해야 합니다.
OAuth 2.0을 사용한 인증의 경우 JWT 액세스 토큰 및/또는 리프레쉬 토큰은 클라이언트 디바이스 어딘가에 저장해야 합니다.따라서 사용자가 로그인 자격 증명을 제공하고 나면 웹 사이트를 탐색하기 위해 자격 증명을 다시 제공할 필요가 없습니다.이 경우 브라우저 로컬스토리지, 세션스토리지 및 cookie는 모두 유효한 옵션입니다.단, 여기서 cookie는 서버 측 세션에 링크되지 않습니다.즉, cookie에는 세션 ID가 저장되지 않습니다.cookie는 단순히 접근토큰의 저장소로 사용되며, 서버는 모든 http 요구와 함께 서버에 전달되며 디지털 서명을 사용하여 토큰을 검증하여 토큰이 변조되지 않고 유효기간이 만료되지 않았는지 확인합니다.
액세스 및/또는 새로 고침 토큰에 대한 세 가지 저장 옵션이 모두 인기가 있지만 쿠키를 올바르게 사용하는 것이 가장 안전한 옵션인 것 같습니다.
이것을 이해하기 위해서는 OAuth 2.0 사양과 함께 이것저것 읽어보는 것이 좋습니다.
2019년 2월 16일 갱신
아까 쿠키가 가장 안전한 옵션인 것 같다고 말씀드렸는데요.요점을 좀 더 명확히 하고 싶습니다.
가 localStorage
★★★★★★★★★★★★★★★★★」sessionStorage
인증 토큰을 저장하기에 충분한 보안을 제공하지 않음는 다음과 같습니다.
XSS가 발생하면 악의적인 스크립트는 토큰을 쉽게 읽어 리모트서버에 송신할 수 있습니다.따라서 원격 서버 또는 공격자는 공격 대상 사용자로 가장하는 데 문제가 없습니다.
localStorage
★★★★★★★★★★★★★★★★★」sessionStorage
서브패키지 간에 공유되지 않습니다.따라서 서로 다른 하위 도메인에서 두 개의 SPA를 실행하면 한 앱이 저장한 토큰을 조직 내 다른 앱에서 사용할 수 없기 때문에 SSO 기능을 사용할 수 없습니다. 하다, 하다, 하다, 하다, 하다, 하다, 하다, 이런 식의 해결책이 .iframe
하지만, 그것들은 좋은 해결책이라기보다는 회피책에 가깝습니다. 응답 헤더 " " " " " 가 때X-Frame-Options
는 클릭재킹 위해 합니다.iframe
「 」가 있는 임의의 .iframe
의문의 여지가 없다.
그러나 이러한 위험은 다시 쿠키가 필요한 지문(OWASP JWT 치트시트 참조)을 사용하여 완화할 수 있습니다.
핑거프린트의 개념은 암호학적으로 강력한 임의의 바이트 문자열을 생성하는 것입니다.은 raw64에 됩니다.HttpOnly
,Secure
,SameSite
with prefix cookie(이름 프리픽스 cookie)__Secure-
도메인 속성과 패스 속성의 적절한 값은 비즈니스 요건에 따라 사용해야 합니다.SHA256은 JWT를 사용합니다.따라서 XSS 공격이 JWT 액세스토큰을 공격자가 제어하는 리모트서버에 송신해도 원래 문자열은 cookie로 송신할 수 없기 때문에 서버는 cookie의 부재를 바탕으로 요구를 거부할 수 있습니다.가 " " " 입니다.HttpOnly
XSS를 사용합니다.
때문에 가 '우리'를 해도 '우리'는 '우리'를 사용한다.localStorage
★★★★★★★★★★★★★★★★★」sessionStorage
쿠키를 사용하여 보안을 유지해야 합니다.또한 위와 같이 서브도메인 제한을 추가합니다.
JWT를 저장하기 위해 쿠키를 사용하는 경우 CSRF 공격뿐입니다.SameSite
cookie, 요구불가능하기 때문에 됩니다.cookie, CSRF는 Cookie, CSRF를 사용합니다(AJAX를 통해). 기타 있지 않은 경우.이 브라우저는 지원되지 .SameSite
cookie는 암호화적으로 강력한 랜덤 값을 가진 CSRF cookie를 추가로 사용함으로써 CSRF를 경감할 수 있습니다.이것에 의해, 모든 AJAX 요구는 cookie 값을 읽어 커스텀 HTTP 헤더에 cookie 값을 추가할 수 있습니다(상태 변경을 실시하지 않는 GET 요구와 HEAD 요구는 제외).CSRF는 같은 오리진정책으로 인해 아무것도 읽을 수 없고 POST, PUT, DELETE 등의 안전하지 않은HTTP 방식을 이용하기 때문에 이 CSRF cookie를 사용하면 CSRF의 리스크가 경감됩니다.CSRF cookie를 사용하는 이 접근법은 모든 최신 SPA 프레임워크에서 사용됩니다.여기서는 Angular 접근법에 대해 설명합니다.
는 「 」이기 때문에,httpOnly
★★★★★★★★★★★★★★★★★」Secured
수 XSS는 읽을 수 없습니다.XSS를 사용하다
적절한 XSS를 및 할 수 .content-security-policy
응답 헤더
기타 CSRF 경감 접근법
- 상태 변수(Auth0이 사용) - 클라이언트는 모든 요구에 대해 암호화적으로 강력한 랜덤 난스를 생성 및 전달합니다.이 난스는 서버가 응답과 함께 에코백하여 클라이언트는 난스를 검증할 수 있습니다.Auth0 문서에 설명되어 있습니다.
- 항상 참조자 헤더를 확인하고 참조자가 신뢰할 수 있는 도메인인 경우에만 요청을 수락하십시오.참조자 헤더가 없거나 화이트리스트가 아닌 도메인이 있는 경우 요청을 거부하기만 하면 됩니다.SSL/TLS 를 사용하는 경우는, 통상은 레퍼러가 있습니다.랜딩 페이지(대부분 정보이며 로그인 형식이나 보안 보호된 콘텐츠를 포함하지 않음)는 약간 느긋할 수 있으며 Referer 헤더가 없는 요청을 허용합니다.
- 는 TRACE HTTP를 때 할 수 .이 메서드를 사용하여
httpOnly
를 클릭합니다 - 또한 헤더 Strict-Transport-Security: max-age=; includeSubDomains를 설정하여 보안 연결만 허용하여 서브 도메인의 man-in-the-middle 쿠키를 덮어쓰지 않도록 합니다.
LocalStorage/SessionStorage는 XXS 공격에 취약합니다.액세스 토큰은 JavaScript에서 읽을 수 있습니다.
httpOnly, secure 및 SameSite=flags가 있는 쿠키는 더 안전합니다.JavaScript에서 액세스 토큰 및 해당 페이로드에 액세스할 수 없습니다.
단, XSS 취약성이 있는 경우 공격자는 인증된 사용자로 요청을 보낼 수 있습니다.이는 악의적인 스크립트가 쿠키 값을 읽을 필요가 없기 때문입니다.브라우저에 의해 쿠키가 자동으로 전송될 수 있기 때문입니다.
이 진술은 사실이지만 위험은 다르다.
쿠키의 경우 액세스 토큰은 여전히 숨겨져 있으며 공격자는 "온사이트" 공격만 수행할 수 있습니다.웹 앱에 주입되는 악의적인 스크립트가 제한되거나 더 많은 스크립트를 변경/주입하기가 쉽지 않을 수 있습니다.사용자 또는 웹 앱이 먼저 공격 대상일 수 있습니다.이러한 조건에 의해 공격의 규모가 제한됩니다.
localStorage를 사용하면 공격자는 액세스 토큰을 읽고 원격으로 공격을 수행할 수 있습니다.다른 공격자와 토큰을 공유하여 더 심각한 피해를 입힐 수도 있습니다.공격자가 CDN에 악의적인 스크립트를 삽입할 수 있는 경우(예를 들어 Google 글꼴 API), 공격자는 구성된 CDN을 사용하는 모든 웹 사이트에서 액세스 토큰과 URL을 탈취하여 새로운 대상을 쉽게 찾을 수 있습니다.localStorage를 사용하는 웹 사이트는 더 쉽게 대상이 됩니다.
논쟁을 위해서
펜 테스트에서는 중요한 데이터에 localStorage를 위험으로 사용할 수 있습니다.
JavaScript가 XSS 공격으로부터 localStorage의 액세스 토큰을 읽는 것이 정상이라면, 왜 httpOnly 플래그가 여전히 모두에게 권장된다고 생각하십니까?
OWASP 권장 사항
데이터는 JavaScript에서 항상 액세스할 수 있으므로 세션 식별자를 로컬 저장소에 저장하지 마십시오.쿠키는 httpOnly 플래그를 사용하여 이 위험을 완화할 수 있습니다.
HTTP는 상태 비저장 프로토콜입니다.상세한 것에 대하여는, 그 회답을 참조해 주세요.그러나 기본적으로는, Web 서버등의 HTTP 서버는, 1개의 요구의 라이프 타임을 넘기지 않고 클라이언트에 관한 정보를 보존하지 않습니다.이는 로그인한 사용자를 기억하지 못하기 때문에 웹 앱에 문제가 됩니다.
쿠키는 이것의 해결책으로 발명되었다.쿠키는 클라이언트와 서버가 모든 요청에 대해 주고받는 텍스트 데이터입니다.클라이언트와 서버가 통신할 때마다 기억하는 내용에 대해 합의함으로써 애플리케이션 상태 데이터를 효과적으로 유지할 수 있습니다.
이는 기본적으로 쿠키 없이는 세션을 수행할 수 없음을 의미합니다.세션을 조회하여 현재 어떤 사용자가 앱에 로그인했는지 알 수 있도록 세션 ID를 저장하는 쿠키가 있어야 합니다.express-session이 하는 일은 다음과 같습니다.메인 세션에 대한 문서session
method는 세션 ID가 쿠키에 저장되어 있음을 명시적으로 나타냅니다.
그래서 제 질문은 쿠키를 저장해야 하나요?세션에서 접근할 수 있기 때문입니다.필요한 데이터를 가져오기 위한 ID입니다.
쿠키를 저장할 필요가 없습니다.express-module이 이 작업을 수행합니다.어플리케이션 전체가 쿠키를 저장해야 합니다.이 쿠키가 없으면req.sessionID
올려다봐.
내 경험에 따르면 토큰을 localStorage에 저장하기만 하면 됩니다.
local 스토리지:
최대 5MB의 정보를 저장할 수 있습니다. localStorage에 토큰을 저장하기 위해 사용자의 권한을 요청할 필요가 없습니다.
유일한 관심사는 타깃디바이스가 localStorage api를 지원하는지 여부입니다.
https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage 를 참조해 주세요.
그것은 널리 지지를 받고 있다.그러나 내 경험에 따르면 ios 앱을 가지고 있고 이 앱에 토큰(webview라고도 함)을 저장하도록 사용자에게 요청하는 html 페이지가 있다면 localStorage api가 인식되지 않고 오류가 발생합니다.
해결책은 간단히 url에 토큰을 넣고 매번 전송하는 것입니다.webview에서는 url이 표시되지 않습니다.
쿠키:
로컬에 정보를 저장하는 것은 매우 오래된 스타일입니다.쿠키 내 저장공간이 비교적 작기 때문에 토큰을 쿠키에 저장하기 위해서는 사용자의 허가를 받아야 합니다.
쿠키는 모든 요청과 함께 전송되므로 성능을 저하시킬 수 있습니다(특히 모바일 데이터 연결).클라이언트 스토리지의 최신 API는 웹 스토리지 API(localStorage 및 sessionStorage)와 IndexedDB(https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies)입니다.
토큰을 sessionStorage 또는 redux에 저장하지 마십시오.
탭을 닫으면 sessionStorage에 저장된 데이터가 손실됩니다.사용자가 실수로 탭을 닫으면 토큰이 손실되고 서버는 현재 사용자를 식별할 수 없습니다.redux에 저장된 토큰은 다른 js 파일에 저장되는 것과 다르지 않습니다.redux store는 js 파일일 뿐입니다.redux에 저장된 정보는 페이지를 새로 고칠 때마다 손실됩니다.
결론적으로,
최신 스타일을 사용하는 경우 대부분의 경우 토큰은 localStorage에 저장됩니다.경우에 따라서는 토큰을 cookie에 저장할 수 있으며 경우에 따라 url에 넣을 수도 있습니다.그러나 세션 중에는 저장하지 마십시오.
도움이 됐으면 좋겠다.
언급URL : https://stackoverflow.com/questions/54258233/do-i-have-to-store-tokens-in-cookies-or-localstorage-or-session
'programing' 카테고리의 다른 글
스프링 부트 - Entity Manager 구성 (0) | 2023.03.04 |
---|---|
OrderBy 뒤에 Angularjs의 $index가 잘못됨 (0) | 2023.03.04 |
플랫 번들링이란 무엇이며 롤업이 웹팩보다 나은 이유는 무엇입니까? (0) | 2023.03.04 |
Woocommerce 3에서 관련 제품 제목 이름 변경 (0) | 2023.03.04 |
크로스 오리진(CORS) 오류 검출 방법Javascript의 XMLHttpRequest()에 대한 기타 오류 유형 (0) | 2023.03.04 |