인증 및 승인

우리 모두 알고 있듯이 웹 서버는 상태 비저장입니다. 즉, 서버는 사용자가 마지막 요청에서 무엇을 했는지 알 수 없으며 요청은 서로 독립적입니다. 고객 정보는 각 요청과 함께 전달되거나 서버 자체에 저장된 공개 정보에서만 제공되며 모든 요청에 ​​사용될 수 있습니다. 이에 온라인 쇼핑의 장바구니 내역 등 이용자가 요청한 상태정보를 추적하기 위해 쿠키가 탄생하게 되었습니다.

서버가 클라이언트의 요청에 응답하면 클라이언트에 쿠키를 푸시합니다. 이 쿠키는 서버에 대한 일부 정보를 기록합니다. 클라이언트는 후속 요청에서 이 쿠키를 전달하며 서버는 이 쿠키를 기반으로 요청의 컨텍스트를 결정할 수 있습니다.

쿠키의 출현은 무상태 상태에서 상태로 전환하는 수단입니다.

로그인을 예로 들어보겠습니다. 사용자는 계정 이름과 비밀번호를 입력하고 서버에 요청을 보냅니다. 서버는 쿠키를 생성하여 브라우저에 보냅니다. 브라우저는 쿠키를 k-v 형식으로 특정 디렉터리에 텍스트 파일로 저장했다가 다음에 동일한 웹 사이트를 요청할 때 서버로 쿠키를 보냅니다. 서버는 수신된 쿠키가 서버의 쿠키와 일치하는지 확인합니다. 그렇지 않으면 확인이 실패합니다. 이것이 원래 아이디어입니다.

img src='(도메인 이름 1) 및 c.d.e.f.com.cn(도메인 이름 2). 도메인 이름 2는 도메인 이름 1의 쿠키를 읽으려고 합니다. 도메인 이름 1에 대해 어떤 도메인을 선언할 수 있나요? 대답은 e.ffcom.cn 또는 .f.com.cn입니다. 쿠키 도메인 이름을 접미사로 설정할 수 있으면 브라우저는 도메인이 .com.cn인 쿠키를 허용할 수 없습니다.

도메인 이름 1에 Set-Coo가 설정된 경우

kie: mykey=myvalue1; domain=e.f.com.cn; name 2 설정 Set-Cookie: mykey=myvalue2;domain=e.f.com.cn;path='/'

그러면 이 도메인의 mykey 값이 myvalue2로 덮어쓰기됩니다. 동일한 도메인 내에서 Cookie mykey는 고유합니다. 일반적으로 불필요한 데이터 전송을 줄이고 대역폭을 절약하려면 올바른 도메인과 경로를 설정해야 합니다.

대화형 웹 사용의 증가, 쿠키 크기 제한 및 저장된 쿠키 수에 대한 브라우저 제한으로 인해 웹사이트가 누구인지와 같은 대량의 사용자 정보를 저장할 수 있는 더 강력한 공간이 필요합니다. 장바구니에 상품을 담은 사람이 로그인한 후 서버는 수천만 명 이상의 사용자 정보를 저장해야 하는데 쿠키는 당연히 적합하지 않습니다. 무엇을 해야 할까요?

사용자 정보는 어디에 저장되나요? 서버에 직접 저장할 수 있나요?

서버에 존재하는 경우 1. 이는 서버에 엄청난 오버헤드가 되어 서버의 확장 능력을 심각하게 제한하게 됩니다. 2. 웹 서버가 로드 밸런싱되어 있고 사용자 user1이 시스템 A를 통해 시스템에 로그인한다고 가정합니다. 그런 다음 다음 요청이 다른 시스템 B로 전달되면 사용자 정보는 시스템 B에 저장되지 않으므로 찾을 수 없습니다. sessionId이므로 sessionId를 서버에 저장하면 안 됩니다. 이때 이러한 문제를 해결하기 위해 redis/Memcached가 나왔습니다. 간단히 캐시 데이터베이스라고 이해하면 됩니다.

sessionId를 독립적인 캐시 서버에 중앙 집중식으로 저장하면 모든 시스템이 이 캐시 시스템으로 이동하여 sessionId를 기반으로 사용자 정보와 인증을 얻습니다. 그러면 문제가 해결될 것입니다.

작동 원리상 이 방법에서 문제점을 발견하셨나요? 이로 인해 SSO(Single Sign-On) 실패 가능성이 높아집니다. 세션을 담당하는 시스템이 중단되면 전체 로그인도 중단됩니다. 그러나 일반적으로 프로젝트에서 세션을 담당하는 머신은 안정성을 높이기 위해 로드 밸런싱을 위한 여러 머신의 클러스터이기도 합니다.

생각:

서버를 다시 시작하면 사용자 정보가 손실되나요?

Redis 등의 캐시 서버에도 클러스터가 있는데, 특정 서비스를 다시 시작하면 실행 중인 다른 서버에서 사용자 정보를 검색하게 되는데, 만약 모든 서버가 한꺼번에 다운된다면? 일반적인 대응 전략은 메모리에 저장된 사용자 정보를 정기적으로 호스트 하드 디스크로 플러시하여 데이터를 유지하는 것입니다. 데이터가 손실되더라도 재시작 후 몇 분 이내에 발생한 사용자 데이터만 손실됩니다.

쿠키 세션 제한

쿠키를 사용하여 사용자는 브라우저 측에서 쿠키를 비활성화할 수 있습니다.

크로스엔드 호환 앱 등은 지원하지 않습니다.

p>

비즈니스 시스템이 지속적으로 캐시 서버에 사용자 정보 검색을 요청하므로 메모리 오버헤드가 증가하고 서버에 과도한 부담이 가해집니다.

서버는 캐시 서버가 없으면 확장됩니다. 매우 어려우며 여러 서버에서 세션 ID를 미친 듯이 복사해야 합니다.

Single Sign-On 실패 가능성이 있습니다

Single Sign On(Single Sign On), SSO라고 합니다. 기업이 발전함에 따라 대규모 시스템에는 n개의 여러 하위 시스템이 포함될 수 있습니다. 서로 다른 시스템을 운영할 때 사용자는 여러 번 로그인해야 하며 이는 매우 번거로운 문제를 해결하는 데 사용됩니다. 상호 신뢰할 수 있는 다른 사용 시스템에 액세스하려면 한 번만 로그인하면 됩니다.

앞서 Single Sign-On은 최상위 도메인과의 쿠키 공유를 기반으로 하며 상황에 따라 다음 세 가지 유형으로 나눌 수 있다고 말씀드렸습니다.

동일한 사이트에 속함;

시스템은 동일한 최상위 도메인 이름에 속함;

각 하위 시스템은 서로 다른 최상위 도메인 이름에 속함

일반 기업이 최상위 도메인 이름을 가지고 있는 경우 앞서 언급한 바와 같이 동일한 사이트 및 동일한 최상위 도메인에서 Single Sign-On은 쿠키 최상위 도메인 공유 기능을 사용합니다. 나는 모두가 이미 이 과정을 이해하고 있으며 다시는 반복하지 않을 것이라고 믿습니다. 하지만 다른 도메인이라면 어떨까요? 쿠키는 다른 도메인 간에 공유되지 않습니다. 어떻게 해야 합니까?

여기에서는 Single Sign-On의 표준 프로세스인 CAS(Central Authentication Service) 프로세스에 대해 이야기하겠습니다. 이는 인증을 위해 특별히 별도의 시스템을 사용하는데, 이를 아래에서 SSO 시스템이라고 합니다.

이 프로세스는 실제로 쿠키 세션 모드와 동일합니다. 싱글 사인온은 각 하위 시스템에 전체 쿠키 세션 모드 세트와 SSO 시스템 세트가 있음을 의미합니다.

사용자가 시스템 a에 액세스하여 로그인이 필요한 경우 SSO 시스템에서 계정 및 비밀번호 인증을 통과한 후 SSO 서버는 세션을 저장하고 sessionId를 생성한 후 반환합니다. 이를 SSO 브라우저에 보내고, 브라우저는 SSO 도메인에 쿠키를 작성하고 시스템 a로 전달되는 ST를 생성합니다. 시스템 a는 확인을 위해 SSO 시스템에 요청합니다. 시스템 a의 로그인 상태가 세션에 기록되고 시스템의 도메인 a에 쿠키가 심어집니다. 나중에 시스템에서 로그인 확인을 수행하면 동일한 도메인에서 인증됩니다.

이때, 사용자는 시스템 b에 접속한다. SSO로 점프하여 로그인을 준비하면 SSO가 이미 로그인되어 있는 것을 발견한다. 그러면 SSO는 ST를 생성하여 시스템 b로 전달한다. 시스템 b는 이 ST를 사용하여 요청합니다. SSO 시스템은 확인이 성공한 후 시스템 b의 서버가 로그인 상태를 세션에 기록하고 시스템 b 도메인에 쿠키를 설정합니다. 이 과정에서 시스템 b는 더 이상 로그인할 필요가 없음을 알 수 있습니다.

"SSO로 점프하여 로그인을 준비하는 중 SSO가 이미 로그인되어 있는 것을 발견했습니다." 이를 수행하는 방법 여기에는 Oauth2 인증 메커니즘이 포함됩니다. 여기서는 자세히 설명하지 않겠습니다. 즉, 시스템 b가 SSO 시스템으로 점프할 때 시스템 a에서 점프하고 시스템 a의 세션 정보를 SSO로 전달한 다음 다시 시스템 b로 리디렉션하도록 합니다.

Oauth2의 경우 Ruan Yifeng의 "OAuth 2.0의 네 가지 방법"을 읽어보세요.

Cookie-session의 한계를 이미 분석했습니다. 더 철저한 해결책이 있을까요? SSO 인증 시스템이 존재하면 단일 실패 지점이 발생할 가능성이 높아지는데 단순히 필요하지 않아야 할까요? 이것이 바로 탈중앙화, 즉 사용자 정보를 저장하고 검증하는데 사용되는 캐시 서버를 없애고, 이를 각자의 시스템에서 다른 방식으로 검증하는 아이디어이다. 간단히 말하면, CPU의 컴퓨팅 파워를 이용하여 공간을 대신하여 모든 세션 정보를 쿠키에 암호화하여 브라우저로 보내는 방식을 구현하는 것입니다.

서버는 사용자가 시스템에 로그인한 후 토큰을 발급하지 않습니다. 다음 번에 사용자가 Http를 통해 서버에 액세스하도록 요청하면 토큰이 전달됩니다. 확인을 위해 Http 헤더 또는 URL을 가져오세요. 다른 사람이 위조하는 것을 방지하기 위해 데이터에 나만 알고 있는 키를 추가하고 서명을 한 후 데이터와 서명을 함께 토큰으로 보낼 수 있습니다. 이렇게 하면 사용자에게 전송된 토큰에 이미 사용자 정보가 포함되어 있으므로 토큰을 저장할 필요가 없습니다. 사용자가 다시 요청하면 동일한 알고리즘과 키를 사용하여 토큰의 데이터를 암호화하고, 암호화된 결과가 토큰의 서명과 일치하면 이를 통해 사용자를 인증하고 얻을 수 있습니다.

서버의 경우 토큰 생성과 토큰 확인만 담당하므로 많은 세션을 저장하기 위해 추가 캐시 서버가 필요하지 않습니다. 사용자 센터 서버 전체를 확장하는 것보다 대규모 서버의 용량을 확장하는 것이 더 경제적입니다.

누군가 사용자 정보를 변조했지만 키를 알 수 없기 때문에 토큰에 포함된 서명과 변조 후 클라이언트가 계산한 서명이 확실히 불일치하여 인증이 실패하게 되므로, 그래서 안전 문제에 대해 걱정할 필요가 없습니다.

토큰의 적시성은 다음과 같이 수행됩니다. 처음 로그인하면 이후 요청마다 계정 비밀번호를 기반으로 토큰이 생성됩니다. 타임스탬프를 부여하고 새 토큰을 보내면 클라이언트는 원래 토큰을 대체합니다.

jwt 모드에서의 로그아웃은 실제로는 가짜 로그인 실패입니다. 브라우저 측에서 토큰을 지워서 발생하는 착각일 뿐이므로 이전 토큰을 사용하는 경우에는 여전히 성공적으로 로그인할 수 있습니다. 만료되지 않았습니다

보안은 키가 노출된 후 키에 의존합니다.

암호화로 생성된 데이터는 상대적으로 길고 상대적으로 더 많은 트래픽을 차지합니다.

쿠키에 의존하지 않으며 단말기 및 프로그램 전반에 걸쳐 사용할 수 있습니다. 모바일 기기 사용, 지원

Single Sign-On이 없는 쿠키 세션 모드에 비해 확장이 매우 쉽습니다

서버는 Stateless 특성을 유지하며 사용자 정보를 서버나 세션에 저장할 필요가 없습니다.

Single Sign-On의 경우 SSO 사이트에 지속적으로 확인 요청을 보내는 모드를 사용하면 관련 요청이 많이 절약됩니다. 질문과 답변:

上篇: 어떤 버전의 중장비가 가장 고전적입니까? 下篇: 소시지 파티 6주년은 언제인가요?
관련 내용