인증(Authentication) 과 인가(Authorization)
인증: 사용자가 로그인 하는 것
인가: 사용자에게 해당 요청에 대한 권한을 부여하는 것
로그인을 통해서 인증을 하면 요청을 보낼 때 마다 서버는 권한이 필요한 요청에 대해 인가과정을 거친다.
세션 (Session)
세션은 웹 브라우저를 통해 웹서버에 접속한 시점부터 웹브라우저를 종료하는 시점까지 클라이언트가 누군지 구별하고 클라이언트에 따라 다른 권한을 주기위해 사용되는 기술이다.
클라이언트가 로그인하면 서버는 회원 정보 세션을 생성하고 세션 저장소에서 Session ID를 발급하여 클라이언트에서 보낸다. (인증)
이제 권한이 필요한 요청을할 때 쿠키에 sessionID를 저장하여 보내고 서버는 전달받는 sessionID로 session을 조회하여 검증이 되면 응답을 보낸다. (인가)
장점
- 더 이상 유저정보 등을 쿠키에 직접 담아서 전송할 필요가 없다. 쿠키에 유저정보를 담게되면 보안상 위험하며, 클라이언트에서 유저 권한에 대한 정보를 가지고 있을 필요가 없고, 서버에서 sessionID로만 검증하기 때문에 보안이 좀 더 좋다.
- 클라이언트는 sessionID만 관리하면 된다.
- sessionID가 탈취되더라도 DB에 저장된 session을 삭제하면 된다.
단점
- 서버DB에 세션 정보가 저장되므로 DB 리소스를 잡아먹는다.
- 사용자가 많아질수록 리소스에 부담이 된다.
JWT (Json Web Token)
JWT(JSON Web Token)는 서로 간의 정보를 JSON 개체로 안전하게 전송하기 위한 간결하고 자체 포함된 방법을 정의하는 개방형 표준이다.
JWT는 세션, 쿠키를 대신하는 의미있는 문자열 토큰이다.
JWT 구성
헤더(header)
alg 알고리즘과 type을 포함한다.
페이로드(payload)
사용자 혹은 데이터 속성 등을 나타내는 클레임(Claim) 이라는 정보 단위로 구성된다. 모두 선택적으로 작성이 가능하다.
등록된 클레임 (Registered Claim)
JWT 사양에 이미 정의된 클레임이다.
- iss : Issuer. 토큰 발급자를 나타낸다.
- sub : Subject. 토큰 제목을 나타낸다.
- aud : Audience. 토큰 대상자를 나타낸다.
- exp : Expiration Time. 토큰 만료 시각을 나타낸다. Numeric Date 형식으로 나타낸다.
- nbf : Not Before. 토큰의 활성 시각을 나타낸다. 쉽게 말해, 이 시각 전에는 토큰이 유효하지 않다는 의미이다. Numeric Date 형식으로 나타낸다.
- iat : Issued At. 토큰이 발급된 시각을 나타낸다. Numeric Date 형식으로 나타낸다. 이 값으로 토큰이 발급된지 얼마나 오래됐는지 확인할 수 있다.
- jti JWT ID. JWT 의 식별자를 나타낸다.
subject는 유일한 값을 사용한다. 주로 사용자 이메일을 사용한다.
토큰 만료시각을 꼭 지정해야한다.
공개 클레임 (Public Claim)
공개 클레임은 JWT 를 사용하는 사람들에 의해 정의되는 클레임으로, 공개용 정보를 위해 사용한다.
{
"email": "sample@domain.com",
"profile": "http://domain.com/image.png",
"http://domain.com/xxx/yyy/is_admin": true
}
비공개 클레임 (Private Claim)
서버와 클라이언트 사이에서만 협의된 클레임으로, 공개 클레임과 충돌이 일어나지 않게 사용하면 된다.
{
"user_id": "123456790",
"user_age": 25
}
시그니처(signature)
특정 암호화 알고리즘을 사용하여, Base64 인코딩된 헤더와 Base64로 인코딩된 페이로드 그리고 비밀키를 이용하여 암호화한다. 서명을 통해 서버는 헤더 혹은 페이로드가 누군가에 의해 변조되었는지 그 무결성을 검증하고 보장할 수 있다.
헤더와 페이로드는 Base64로 인코딩된 값이기 때문에 누구나 확인 가능하다. 토큰을 검증할 때 서명이 매우 중요하며 서명에 사용되는 secret key 비밀 키를 잘 관리해야한다.
인증, 인가 과정 (Access Token만 사용)
https://tansfil.tistory.com/58?category=475681
- 사용자가 로그인을 한다.
- 서버에서는 계정정보를 읽어 사용자를 확인 후, 사용자의 고유한 ID값을 부여한 후, 기타 정보와 함께 Payload에 넣습니다.
- JWT 토큰의 유효기간을 설정합니다.
- 암호화할 SECRET KEY를 이용해 ACCESS TOKEN을 발급합니다. (인증)
- 사용자는 Access Token을 받아 저장한 후, 인증이 필요한 요청마다 토큰을 헤더에 실어 보냅니다.
- 서버에서는 해당 토큰의 Verify Signature를 SECRET KEY로 복호화한 후, 조작 여부, 유효기간을 확인합니다.
- 검증이 완료된다면, Payload를 디코딩하여 사용자의 ID에 맞는 데이터를 가져옵니다. (인가)
장점
- 사용이 간편하다.
- 별도의 저장소 관리가 필요하지 않고, Stateless 한 서버를 만들 수 있다. (이는 서버를 확장하거나 유지,보수 하는데 유리하다.)
- 확장성이 뛰어나다. 토큰 기반으로 하는 다른 인증 시스템에 접근이 가능하다. (예를 들어 Facebook 로그인, Goole 로구인)
단점
- 한번 발급되면 유효기간이 만료될 때 까지 계속 사용이 가능하다. 유효기간이 지나지 전에 탈취당해 정보가 털릴 수 있다.
- 페이로드를 누구나 확인할 수 있다. 중요한 정보는 페이로드에 넣을 수 없다.
- 페이로드에 값을 많이 넣을수록 JWT의 길이가 길어진다. 인증이 필요한 요청이 많아질 수록 서버의 자원낭비가 발생한다.
Access Token의 유효기간이 만료되면, Refresh Token을 이용하여 Access Token을 재발급한다.
Access Token을 비교적 유효기간을 짧게 만들고, 유효기간이 비교적 긴 Refresh Token을 사용하여 보안을 강화한다.
인증, 인가 과정 (Access Token + Refresh Token)
https://tansfil.tistory.com/58?category=475681
- 사용자가 ID , PW를 통해 로그인합니다.
- 서버에서는 회원 DB에서 값을 비교합니다(보통 PW는 일반적으로 암호화해서 들어갑니다)
3~4. 로그인이 완료되면 Access Token, Refresh Token을 발급합니다. 이때 일반적으로 회원DB에 Refresh Token을 저장해둡니다.
5.사용자는 Refresh Token은 안전한 저장소에 저장 후, Access Token을 헤더에 실어 요청을 보냅니다.
6~7. Access Token을 검증하여 이에 맞는 데이터를 보냅니다.
8. 시간이 지나 Access Token이 만료됐다고 보겠습니다.
9. 사용자는 이전과 동일하게 Access Token을 헤더에 실어 요청을 보냅니다.
(10~11. 서버는 Access Token이 만료됨을 확인하고 권한없음을 신호로 보냅니다.)
12. 사용자는 Refresh Token과 Access Token을 함께 서버로 보냅니다.
13. 서버는 받은 Access Token이 조작되지 않았는지 확인한후, Refresh Token과 사용자의 DB에 저장되어 있던 Refresh Token을 비교합니다. Token이 동일하고 유효기간도 지나지 않았다면 새로운 Access Token을 발급해줍니다.
14. 서버는 새로운 Access Token을 헤더에 실어 다시 API 요청을 진행합니다.
장점
- Access Token만 있을 경우보다 안전하다.
단점
- 구현이 복잡하다.
- Access Token이 만료될 때마다 새롭게 발급하는 과정에서 생기는 HTTP 요청 횟수가 많다. 이는 서버의 자원 낭비로 이어진다.
Refresh Token까지 탈취당할 경우 해당 유저의 리프래시 토큰을 모두 만료시키는 방법이 있다.
source
https://tansfil.tistory.com/58?category=475681
https://jay-ji.tistory.com/101
https://hudi.blog/self-made-jwt/
https://tansfil.tistory.com/59?category=475681
https://mangkyu.tistory.com/56
'Web' 카테고리의 다른 글
[HTTP 웹 기본 지식] 섹션8. HTTP 헤더2 캐시와 조건부 요청 (0) | 2022.11.20 |
---|---|
[HTTP 웹 기본 지식] 섹션7. HTTP 헤더1 일반 헤더 (0) | 2022.11.19 |
[HTTP 웹 기본 지식] 섹션6. HTTP 상태코드 (0) | 2022.11.18 |
[HTTP 웹 기본 지식] 섹션5. HTTP 메서드 활용 (0) | 2022.11.18 |
[HTTP 웹 기본 지식] 섹션4. HTTP 메서드 (0) | 2022.11.17 |