HTTP 프로토콜은 Stateless방식이다. request와 response로 통신이 이루어지며, 응답을 받으면 연결이 끊어지고, 통신이 종료되면 어떠한 상태도 남지 않는다. 그렇다면 HTTP에서는 로그인을 하고 재접속하면 로그인이 끊어질텐데 어떻게 로그인 상태를 유지할까?
- 쿠키 : 쿠키는 서버가 클라이언트의 브라우저에 저장하는 Data File로 Key-Value 형식이며, Header에 담겨져 전송되는 Data 전송 매개체이다. 서버는 Header의 set-cookie에 쿠키에 전달할 Data를 담아 전송한다. 만료 날짜가 없는 세션 쿠키는 사용자 컴퓨터의 메모리에 저장되며, 브라우저가 열려있는 동안 존재하고, 만료 날짜가 있는 영구 쿠키는 디스크에 저장되며, 삭제되거나 만료 날짜까지 존재한다
- 세션 : 세션은 웹서버에 접속해 있는 상태를 하나의 단위로 보고 이 상태를 일정 시간동안 유지시키는 기술이다. 사용자가 로그인을 하면 세션이 생성되며 로그아웃하면 세션이 삭제된다. 이 세션은 서버의 세션 저장소에 저장된다
- Token 로그인 방식은 로그인을 하면 서버에서 Token을 발급하여 HTTP 요청 헤더를 통해 클라이언트에 전달해준다. 이때 접속하기 위한 Access Token을 주는데, 이 Access Token은 중요하므로 유효 시간이 짧다. 이를 Refresh Token을 통해 재발급해주어 로그인 상태를 유지할 수 있다. 이 두 가지 Token은 쿠키와 Local Storage에 나누어 저장하는 편이 보안상으로 좋다
- Token 로그인 방식은 세션을 생성하지 않는다. 서버의 클라이언트와의 상태를 저장/유지하지 않기에 Stateless 서버를 사용한다
- DB에 접근하기 위한 사용자 정보는 사용자에게 전달해주는 payload에 담아서 보내준다
- Header는 Token의 타입(typ)와 Signature 해싱 알고리즘 (alg)로 구성된다
- Payload는 사용자 정보가 들어있다. 정보의 한 ‘조각’ 을 클레임이라고 부르고, 이는 Json(Key/Value) 형태의 한 쌍으로 이루어진다. 토큰에는 여러개의 클레임들을 넣을 수 있습니다
- Verify Signature는 Token을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드가 들어있다. 즉, Header와 Payload를 인코딩한 값과 암호화한 값이 들어있다. 이는 Payload가 위변조되지 않았다는 사실을 증명하는 문자열이다
- 서버는 Token을 발급해주고, 저장하지 않으며, 사용자 요청시 Token을 검증해준다
- 토큰이 유효한지는 토큰 secret key로 판단하며, 이 secret key는 토큰 기능에 종속된다. 따라서 서버가 껏다 켜져도 유효기간이 끝나지 않은 토큰을 인증할 수 있다
- secret key로 토큰이 유효한지 검사하고, 그 다음 payload의 사용자 식별 정보를 가지고 DB에서 식별 정보가 일치하는지 검사하는 순서다
- 과정
- 사용자가 로그인 요청을 보낸다
- 서버에서는 계정 정보를 읽어 사용자를 확인하고, 사용자의 고유한 ID값을 부여하고 Payload에 정보를 넣는다
- Token의 유효기간을 설정합니다.
- SECRET KEY를 통해 암호화된 Access Token을 HTTP 응답 헤더를 통해 보낸다
- 사용자는 Access Token을 받아 쿠키나 local storage저장한 후, 인증이 필요한 요청마다 토큰을 HTTP 요청 헤더에 담아 보낸다
- 서버에서는 해당 토큰의 Verify Signature를 SECRET KEY로 복호화한 후, 조작 여부, 유효 기간을 확인한다
- 검증이 완료된다면, Payload를 디코딩하여 사용자의 ID에 맞는 데이터를 가져와서 전달한다
- Session 로그인 방식은 Session id를 통해 이루어진다. 로그인이 되면 사용자 정보가 담긴 세션이 서버의 메모리의 세션 저장소에 저장된다. Session id가 생성되어 이 id를 키로 사용한다
- 이 쿠키에
- 과정
- 사용자가 로그인을 하면 session id가 생성되고, 이 session id로 세션이 생성된다
- 서버에서 session id를 쿠키에 담아 set-cookie를 통해 클라이언트로 전송한다
- 사용자는 받은 session id가 담긴 쿠키를 저장한다
- 사용자가 session id가 담긴 쿠키를 요청할때 Header에 담아 전달
- 서버가 session id를 키로 메모리에서 사용자의 session 정보를 식별하고, 유료하다면 해당 요청에 대한 응답을 보낸다
https://dj-rest-auth.readthedocs.io/en/latest/installation.html#json-web-token-jwt-support-optional
JWT란? Json Web Token으로 Json 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token이다. 즉, 인증에 필요한 정보들을 암호화시킨 Token이다
라이브러리 설치
settings.py에 코드 추가
JWT 쿠키 : 사용자가 쿠키를 서버에 넘겨주어 서버가 해당 쿠키를 열어본다. 이 쿠키가 중요하므로 쿠키의 유효시간을 적게주고, 해당 유효시간을 갱신시켜주는 REFRESH 쿠키의 유효시간을 길게한다. 이 두 가지 쿠키는 각각 다른 곳에 저장한다
이름만 좀 바꿔준다
회원등록을 위해 DB를 mysql에 연결해주자. migrate도 실행한다
접속해보자
위에서 Raw Data를 복붙해서 Advanced Rest Client에 넘겨줘서 로그인해보자
이렇게 Advanced Rest Client로도 로그인이 가능하다
이렇게 Token이 전달된다
현재 ARC로 회원가입을 할려고 하면 EMAIL 인증때문에 오류가 난다. 따로 서버를 지정안했기 때문이다. 따라서 인증을 none으로 설정한다
로그인하면 Frontend server에서 token을 쿠키에 저장한다
local stoarge에 저장할수도 있다. 이를 통해 쿠키와 local stoarge에 나누어 Token과 Refresh Token을 따로 저장하는 방식도 있다
token을 https://jwt.io/ 사이트에 들어가서 입력하면 해당 token에 대한 정보를 볼 수 있다. verify signature는 암호화되있다
- https://www.epochconverter.com/ (시간 확인)
- https://jwt.io/ (Jwt Token 분석)
👍👍