인증 및 세션 관리의 SPA 베스트프랙티스
Angular, Ember, React 등의 프레임워크를 사용하여 SPA 스타일의 어플리케이션을 구축할 때 인증 및 세션 관리의 베스트 프랙티스는 무엇입니까?나는 그 문제에 접근하는 것을 고려할 수 있는 몇 가지 방법을 생각할 수 있다.
API와 UI가 동일한 원본 도메인을 가지고 있다고 가정할 때 일반 웹 애플리케이션을 사용한 인증과 동일하게 취급합니다.
여기에는 세션 쿠키, 서버 측 세션 스토리지 및 인증된 웹 UI가 개인화에 도움이 되는 현재 사용자 정보를 가져오거나 클라이언트 측 역할/기능을 결정하는 데 사용할 수 있는 세션 API 엔드포인트가 포함될 수 있습니다.서버는 여전히 데이터에 대한 액세스를 보호하는 규칙을 적용합니다. 물론 UI는 이 정보를 사용하여 경험을 사용자 지정합니다.
퍼블릭 API를 사용하는 서드파티 클라이언트처럼 취급하여 OAuth와 유사한 토큰 시스템을 사용하여 인증합니다.이 토큰 메커니즘은 서버 API에 대한 모든 요청을 인증하기 위해 클라이언트 UI에 의해 사용됩니다.
저는 그다지 전문가는 아니지만, 대부분의 경우 1번으로도 충분하다고 생각합니다만, 좀 더 경험 있는 의견을 듣고 싶습니다.
이 질문은 다음과 같이 약간 다른 형태로 상세하게 다루어졌습니다.
서버측에서 대응하고 있습니다.클라이언트측에서 봅시다.하지만 그러기 전에 중요한 서막이 있습니다.
Javascript 암호는 희망이 없다
이것에 관한 마타사노의 기사는 유명하지만, 그 안에 담긴 교훈은 매우 중요하다.
요약:
- 를 man-in-the-middle로 하는 경우가 .
<script> function hash_algorithm(password){ lol_nope_send_it_to_me_instead(password); }</script>
- 중간자 공격은 SSL이 아닌 연결을 통해 리소스를 제공하는 페이지에 대해 사소한 것입니다.
- SSL을 취득하면, 어쨌든 실제의 암호화를 사용할 수 있습니다.
그리고 나 자신의 결과를 덧붙이자면:
- XSS 공격이 성공하면 SSL을 사용하는 경우에도 공격자가 클라이언트의 브라우저에서 코드를 실행할 수 있습니다.따라서 모든 해치를 고정하더라도 공격자가 다른 사용자의 브라우저에서 Javascript 코드를 실행하는 방법을 발견하면 브라우저 암호화가 실패할 수 있습니다.
이로 인해 많은 RESTful 인증 방식이 불가능하거나 JavaScript 클라이언트를 사용하려는 경우 바보가 됩니다.어디 보자!
HTTP 기본 인증
우선 HTTP Basic Auth 입니다.가장 간단한 방식: 모든 요청과 함께 이름과 암호를 전달하기만 하면 됩니다.
물론 모든 요청과 함께 Base64(역방향으로) 인코딩된 이름과 비밀번호를 전달하기 때문에 SSL이 필요합니다.회선을 듣고 있는 유저는, 유저명과 패스워드를 3회 추출할 수 있습니다."Basic Auth is securable" 인수의 대부분은 "Basic Auth over HTTP"에서 유래합니다.이것은 끔찍한 아이디어입니다.
브라우저는 내장 HTTP Basic Auth를 지원하지만 매우 못생겼기 때문에 앱에 사용하지 않는 것이 좋습니다.대신 사용자 이름과 비밀번호를 JavaScript에 저장하는 방법이 있습니다.
이것이 가장 RESTFul한 솔루션입니다.서버는 상태에 대한 지식이 전혀 필요하지 않으며 사용자와의 모든 개별 대화를 인증합니다.일부 REST 지지자들(대부분 스트로맨)은 어떤 상태든 유지하는 것은 이단이며 다른 인증 방법을 생각하면 입에 거품이 오른다고 주장한다.이러한 표준 준수에는 이론적인 이점이 있습니다. Apache에서 즉시 지원되므로 원하는 경우 .htaccess 파일에 의해 보호되는 폴더에 객체를 파일로 저장할 수 있습니다.
문제요?클라이언트 측에서 사용자 이름과 비밀번호를 캐시하고 있습니다.이것에 의해, evil.ru는, XSS 의 가장 기본적인 취약성에서도, 클라이언트는 유저명과 패스워드를 악의 있는 서버에 송신할 가능성이 있습니다.비밀번호를 해시하고 솔트함으로써 이 위험을 완화할 수 있지만 JavaScript Crypt는 절망적이라는 것을 기억하십시오.브라우저의 Basic Auth 지원에 맡김으로써 이 위험을 완화할 수 있지만,앞서 언급했듯이, 죄만큼 추악하다.
HTTP 다이제스트 인증
보다 안전한 인증은 요청/응답 해시 챌린지입니다.JavaScript Crypt는 가망성이 없기 때문에 SSL 상에서만 동작하며 클라이언트 측에서 사용자 이름과 패스워드를 캐시해야 하므로 HTTP Basic Auth보다 복잡하지만 보안이 강화되지 않습니다.
추가 시그니처 파라미터를 사용한 인증 쿼리.
또 다른 '시큐어' 인증에서는 (반복 및 타이밍 공격으로부터 보호하기 위해) 난스 및 타이밍 데이터를 사용하여 파라미터를 암호화하여 전송합니다.가장 좋은 예 중 하나는 OAuth 1.0 프로토콜입니다.이것은 REST 서버에 인증을 실장하는 매우 어려운 방법입니다.
https://www.rfc-editor.org/rfc/rfc5849
아, 근데 자바스크립트용 OAuth 1.0 클라이언트는 없어요. 왜요?
JavaScript 암호는 희망이 없습니다.JavaScript는 SSL이 없으면 OAuth 1.0에 참여할 수 없습니다.또한 클라이언트의 사용자 이름과 비밀번호를 로컬로 저장해야 합니다.이것에 의해, 다이제스트 인증과 같은 카테고리로 분류됩니다.HTTP Basic Auth보다 복잡하지만, 시큐러티는 향상되지 않습니다.
상품권
사용자는 사용자 이름과 비밀번호를 전송하고 그 대신 요청 인증에 사용할 수 있는 토큰을 받습니다.
이것은 HTTP Basic Auth보다 약간 안전합니다.사용자명/패스워드 트랜잭션이 완료되는 즉시 기밀 데이터를 폐기할 수 있기 때문입니다.토큰이 "상태"를 구성하고 서버 구현이 더 복잡해지기 때문에 RESTFUL도 줄어듭니다.
SSL 그대로
단, 토큰을 취득하기 위해서는 초기 사용자 이름과 패스워드를 송신할 필요가 있습니다.중요한 정보는 여전히 손상 가능한 JavaScript에 영향을 미칩니다.
사용자의 자격 증명을 보호하려면 여전히 공격자가 JavaScript에 액세스하지 못하도록 해야 하며 유선을 통해 사용자 이름과 암호를 전송해야 합니다.SSL이 필요합니다.
토큰 만료
오래 되었을 때 하십시오."이할 수 IP 는 "이 토큰을 사용할 수 있는 유일한 IP 일 것입니다와 같은 토큰 합니다.XXX.XXX.XXX.XXX
이 중 것들이 꽤 입니다."
방화
단, SSL을 사용하지 않는 토큰을 사용해도 'sidejacking'이라는 공격에 취약합니다.http://codebutler.github.io/firesheep/
공격자는 사용자의 자격 증명을 얻지 못하지만 여전히 사용자의 사용자인 것처럼 가장할 수 있습니다. 이는 매우 심각한 문제일 수 있습니다.
tl;dr: 암호화되지 않은 토큰을 회선을 통해 전송하면 공격자가 해당 토큰을 쉽게 포착하고 사용자로 위장할 수 있습니다.FireSheep은 이것을 매우 쉽게 만드는 프로그램이다.
개별적이고 안전한 영역
실행 중인 응용 프로그램이 클수록 중요한 데이터를 처리하는 방법을 변경하는 코드를 주입할 수 없게 됩니다.CDN을 전적으로 신뢰하십니까? 광고주님들요?당신만의 코드 베이스?
신용카드 상세에는 공통으로 사용자 이름 및 비밀번호에는 거의 공통적이지 않습니다.일부 구현자는 어플리케이션의 다른 페이지와는 다른 페이지에 '중요한 데이터 입력'을 보관하고 있습니다.이 페이지는 가능한 한 엄격하게 제어하여 잠글 수 있으며, 가급적 사용자를 피싱하기 어려운 페이지입니다.
Cookie(토큰을 의미)
cookie에 인증 토큰을 넣을 수 있습니다(또한 공통).토큰에 의한 auth의 속성은 변경되지 않습니다.그것은 편리성에 가깝습니다.이전 인수는 모두 그대로 적용됩니다.
세션(여전히 토큰만 의미)
Session Auth는 토큰 인증일 뿐이지만 약간 다른 것처럼 보이는 몇 가지 차이점이 있습니다.
- 사용자는 인증되지 않은 토큰으로 시작합니다.
- 백엔드는 사용자의 토큰에 연결된 '상태' 개체를 유지합니다.
- 토큰은 쿠키로 제공됩니다.
- 애플리케이션 환경에서 세부 정보가 추상화됩니다.
하지만 그것 말고는 토큰 인증과 다를 바 없습니다.
이것은, RESTful 실장으로부터 한층 더 멀어지고 있습니다.스테이트 오브젝트를 사용하면, 스테이트 풀 서버상의 플레인 ol' RPC 의 패스를 점점 더 내려갑니다.
OAuth 2.0
OAuth 2.0에서는 소프트웨어 B가 사용자 X의 로그인 credential에 액세스 할 수 없는 상태에서 소프트웨어 A가 소프트웨어 B에게 사용자 X의 데이터에 대한 액세스 권한을 부여하는 방법에 대해 설명합니다.
구현은 사용자가 토큰을 얻은 후 서드파티 서비스를 통해 "예, 이 사용자와 이 토큰이 일치하며 이제 해당 사용자의 데이터 일부를 얻을 수 있습니다."라고 하는 표준적인 방법에 불과합니다.
그러나 기본적으로 OAuth 2.0은 토큰 프로토콜에 불과합니다.이 프로토콜은 다른 토큰 프로토콜과 동일한 속성을 나타냅니다. 이러한 토큰을 보호하려면 SSL이 필요합니다. 이러한 토큰이 생성되는 방식만 변경됩니다.
OAuth 2.0은 다음 두 가지 방법으로 도움이 됩니다.
- 다른 사람에게 인증/정보 제공
- 다른 사람으로부터의 인증/정보 취득
하지만 결국엔, 넌 그냥...토큰을 사용합니다.
질문으로 돌아가다
즉, "토큰을 쿠키에 저장하고 환경의 자동 세션 관리를 통해 자세한 내용을 처리해야 합니까, 아니면 토큰을 Javascript에 저장하고 직접 처리해야 합니까?"라는 질문입니다.
그 답은 '행복한 건 뭐든지 해라'입니다.
하지만 자동 세션 관리의 장점은 이면에서 많은 마법이 일어나고 있다는 것입니다.종종 그런 세부 사항들을 스스로 통제하는 것이 더 좋습니다.
저는 21살이므로 SSL은 yes입니다.
또 다른 대답은: 모든 것에 https를 사용하지 않으면 강도가 사용자의 비밀번호와 토큰을 도용한다.
JWT(JSON Web Tokens) 및 SSL/HTTPS 를 사용하면, 인증 프로세스의 시큐러티를 강화할 수 있습니다.
기본 인증/세션 ID는 다음을 통해 도난당할 수 있습니다.
- MITM 공격(Man-In-The-Middle) - SSL/HTTPS 없음
- 침입자가 사용자의 컴퓨터에 액세스합니다.
- XSS
JWT를 사용하면 사용자의 인증 세부 정보를 암호화하여 클라이언트에 저장하고 모든 요청과 함께 API로 전송하면 서버/API가 토큰을 검증합니다.
개인 키(서버/API가 비밀리에 저장)가 없으면 복호화/읽기가 불가능합니다. 업데이트를 읽습니다.
새로운(더 안전한) 흐름은 다음과 같습니다.
로그 인.
- 사용자가 로그인하여 (SSL/HTTPS를 통해) API에 로그인 자격 증명을 전송합니다.
- API가 로그인 자격 증명을 수신합니다.
- 유효한 경우:
- 데이터베이스에 새 세션을 등록합니다. 업데이트
- 개인 키를 사용하여 JWT에서 사용자 ID, 세션 ID, IP 주소, 타임스탬프 등을 암호화합니다.
- API가 (SSL/HTTPS를 통해) JWT 토큰을 클라이언트에 반송합니다.
- 클라이언트가 JWT 토큰을 수신하여 localStorage/cookie에 저장합니다.
API에 대한 모든 요청
- 사용자가 HTTP 헤더에 저장된 JWT 토큰을 사용하여 (SSL/HTTPS를 통해) API에 HTTP 요청을 전송합니다.
- API가 HTTP 헤더를 읽고 개인 키로 JWT 토큰을 해독합니다.
- API는 JWT 토큰을 검증하고 HTTP 요청의 IP 주소를 JWT 토큰의 IP 주소와 대조하여 세션이 만료되었는지 확인합니다.
- 유효한 경우:
- 요청된 내용과 함께 회신
- 유효하지 않은 경우:
- 예외 발생(403/401)
- 시스템 침입 플래그
- 사용자에게 경고 이메일을 보냅니다.
갱신 30.07.15:
JWT payload/claims는 개인 키(비밀) 없이도 읽을 수 있으며 localStorage에 저장하는 것은 안전하지 않습니다.이런 거짓 진술에 대해 죄송합니다.다만, JWE 규격(JSON Web Encryption)에 준거하고 있는 것 같습니다.
JWT에 클레임(userID, exp)을 저장하고 API/백엔드만이 아는 개인키(비밀)로 서명하여 클라이언트에 안전한 HttpOnly 쿠키로 저장하였습니다.이렇게 하면 XSS를 통해 읽을 수 없고 조작할 수 없습니다.그렇지 않으면 JWT는 시그니처 검증에 실패합니다.또, 시큐어인 Http Only cookie 를 사용하면, cookie 가 HTTP 요구(스크립트에 액세스 할 수 없음)만으로 송신되어 시큐어 접속(HTTPS)으로 송신되는 것을 확인할 수 있습니다.
갱신 17.07.16:
JWT는 원래 스테이트리스입니다.즉, 스스로 무효화/기한이 만료됩니다.세션 추가토큰의 유효성은 서명 확인 및 만료 날짜에 따라 달라질 뿐만 아니라 서버의 세션 상태에 따라 달라지기 때문에 상태 저장으로 만들고 있는 토큰의 클레임에 있는 ID입니다.단, 이전에는 상태 비저장 JWT에서는 불가능했던 토큰/세션을 쉽게 비활성화할 수 있다는 장점이 있습니다.
두 번째는 토큰 시스템입니다.
ember-auth 또는 ember-simple-auth에 대해 알고 계십니까?둘 다 ember-simple-auth 스테이트와 같은 토큰 기반 시스템을 사용합니다.
Ember.js 응용 프로그램에서 토큰 기반 인증을 구현하기 위한 가볍고 방해되지 않는 라이브러리입니다.http://ember-simple-auth.simplabs.com
세션 관리 기능이 있으며 기존 프로젝트에도 쉽게 연결할 수 있습니다.
ember-simple-auth의 Ember App Kit 버전도 있습니다.OAuth2 인증에 ember-simple-auth를 사용한ember-app-kit의 작업 예입니다.
언급URL : https://stackoverflow.com/questions/20963273/spa-best-practices-for-authentication-and-session-management
'programing' 카테고리의 다른 글
Java에서 두 JSON 파일을 비교하는 가장 좋은 방법 (0) | 2023.04.05 |
---|---|
모델을 통해 입력 자리 표시자 값을 변경하시겠습니까? (0) | 2023.04.05 |
수집되지 않은 유형 오류: 데이터.푸시는 기능이 아닙니다. (0) | 2023.04.05 |
저장 후 Mongoose 입력 (0) | 2023.04.05 |
google-services.json의 실제 역할은 무엇입니까? (0) | 2023.03.31 |