Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- clone coding
- **kwargs
- docker
- *args
- 인터넷 네트워크
- bcrypt
- CSS
- 파이썬
- 파이썬입출력
- RESTfulAPI
- JavaScript
- 코딩테스트파이썬
- wecode
- QuerySet
- 자바스크립트
- Python
- clone-coding
- DP
- 파이썬리스트컴프리헨션
- django
- 파이썬문법
- 인증인가
- 윈도우우분투듀얼부팅
- decorator
- 해시충돌
- 리스트컴프리헨션
- 자료구조
- 알고리즘
- 백준
- promise
Archives
- Today
- Total
개발기록장
[Web] 인증과 인가(2) -인가란? (+JWT) 본문
** 인증 관련 글
2021/02/07 - [TIL/etc] - [etc] 인증과 인가(1) -인증이란? (+bcrypt)
1. 인가(Authorization)와 인가 절차
인가(Authorization)는 요청을 보낸 유저가 그 서비스를 사용할 수 있는 유저인지를 확인하는 절차이다.
서버는 그 유저를 어떻게 확인할까? Authorization 절차는 다음과 같다.
- 서버에 로그인을 성공한 유저는 인증을 받았다는 표시로 그 서버가 발행한 토큰을 발급받는다.
보통 이 토큰을access token
이라고 한다. 이 token에는 user id와 같이 아주 중요한 정보가 아니면서도(예를 들어 주민등록번호 같은) 유저를 확실하게 구분할 수 있는 정보가 있어야 한다. - 인증을 받은 유저는 request를 보낼 때 request header에 보통 'Authorization' 라는 이름으로 token 정보를 담아서 보낸다.
- 서버는 이 request에 담긴 token 정보를 복호화하여 우리 서버에서 발급한 token이 맞는지 그리고 token에 담긴 user id를 확인할 수 있다.
- token에서 얻은 user id를 사용해서 DB에서 해당 유저의 권한(permission)을 확인한다.
- 해당 유저가 그 요청을 사용할 수 있는 권한을 가지고 있으면 해당 요청을 처리한다.
- 유저가 권한을 가지고 있지 않은 유저라면 Unauthorized Response(401) 에러 또는 적절한 다른 에러 코드를 보낸다.
2. JSON Web Token (JWT)
- JWT란?
- access token을 생성하는 방법에는 여러가지가 있는데, 그 중 가장 널리 사용되는 기술 중 하나가 바로 JSON Web Token(JWT)이다.
- JSON Web Token (JWT) 은 웹표준 (RFC 7519) 으로서 두 개체에서 JSON 객체를 사용하여 가볍고 자가수용적인 (self-contained) 방식으로 정보를 안전성 있게 전달해주고, 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token이다.
- 자가 수용적 이라는 말은 JWT 는 필요한 모든 정보를 자체적으로 지니고 있다는 것을 뜻한다.
- 토큰에 대한 기본정보(header), 전달 할 정보(payload), 그리고 토큰이 검증됐다는것을 증명해주는 Signature 를 포함하고있다.
- JWT는 양방향 해쉬 알고리즘이 적용되어 있는데, 이를 이용하여 프론트엔드에서는 API요청 시 암호화 된 토큰 정보를 보내고 백엔드에서는 이 토큰을 복호화해서 유저의 권한을 확인한다.
- JWT 구조
1) Header
- Header 는 두가지의 정보를 지니고 있다.
- typ: 토큰의 타입을 지정. JWT는 JWT이다.
- alg: Signature 해싱 알고리즘을 지정합니다. 해싱 알고리즘으로는 보통 HMAC-SHA256 혹은 RSA 가 사용되며, 이 알고리즘은 토큰을 검증 할 때 사용되는 signature 부분에서 사용된다.
예시)
{
"alg" : "HS256",
"typ" : "JWT"
}
2) Payload
- Paylaod에는 토큰을 통해 전달할 내용이 담겨져있다.
- 여기에 담긴 하나의 key-value 쌍을 'Claim'이라고 부르고, Registered, Public, Private의 3가지 유형으로 나뉜다.
- 보통 만료일시, 발급일시, 발급자, 권한정보 등이 포함된 공개 클래임
- 그리고 클라이언트와 서버간의 협의 하에 사용하는 비공개 클래임이 있다.
- Header와 Payload 부분은 암호화하지 않고 base64로 인코딩만 하기 때문에 웹에 접속한 호스트라면 누구나 볼 수 있다. 따라서 민감함 정보는 넣지 않고, user id와 값은 PK값을 전달한다.
예시)
{
"iss": "http://example.org",
"aud": "https://exmple.com",
"exp": "1407019629",
"http://example.com/jwt_claims/is_admin" : "true",
"user_id": "3"
}
3) Signature
- signature(서명)은 인코딩된 header 와 payload 를 합쳐 header의 signature 알고리즘 정보(alg)를 가져와 암호화하여 생성한다
- 만약 헤더정보의 알고리즘이 HS256 일 경우 아래 예시와 같은 signature가 생성된다.
- 프론트엔드에서 JWT를 백엔드 API 서버로 전송하면 서버에서는 전송받은 JWT의 Signature 부분을 복호화 하여 이 서버에서 생성한 JWT가 맞는지를 확인한다.(내가 만든 건 복호화 가능하기 때문)
- 마치 계약서의 위변조를 막기 위해 서로 사인하는 것과 같다고 보면된다.
HMACSHA256(
base64UrlEncode(header) + “.”+
base64UrlEncode(payload),
Secret)
3. JSON Web Token (JWT)으로 인가 구현
파이썬에서 JWT를 이용하여 access token을 발급해보자.
1) pip로 jwt 패키지 설치
pip install pyjwt
* pyjwt 공식 문서 : pyjwt.readthedocs.io/en/stable/
2) JWT 토큰 발행 과정
import jwt
import datetime
# JWT 토큰 발행 (만료 시간을 300초로 설정)
encoded_jwt = jwt.encode({'user-id': 5, 'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=300)}, 'secret', algorithm='HS256')
- jwt.encode 함수를 사용하여 토큰을 발행할 수 있다.
- jwt.encode 함수의 인자는 아래와 같다.
- ({user_id, 토큰 만료시간 등 payload에 줄 정보}, 'secret key', algorithm='사용할 해싱 알고리즘')
- 이때 secret key는 암호화에 이용될 key로 Django project에서는 settings.py에 있는 secret 키를 불러와서 사용한다.
3) JWT 토큰 검증 (decode)
# 토큰 검증(decode)
payload = jwt.decode(encoded_jwt, 'secret', algorithms=['HS256'])
- jwt.decode 함수를 사용하여 토큰을 검증할 수 있다.
- jwt.decode 함수의 인자는 아래와 같다.
- jwt.decode(검증할 토큰, 'secret key', algorithms=['암호화에 사용된 해싱 알고리즘']) ** algorithms에 's' 주의!!
- 이 결과로 payload에 저장된 값을 가져와서 유저의 권한을 확인할 수 있다.
'TIL > Web' 카테고리의 다른 글
[CS] 웹 브라우저 요청 흐름 (www.google.com을 치면 어떤 일이 일어나는가) (0) | 2023.01.29 |
---|---|
[CS] 기본적인 인터넷 네트워크 개념 (0) | 2023.01.29 |
[Web] 인증을 유지시키는 여러가지 방법 (0) | 2021.02.21 |
[Web] 인증과 인가(1) -인증이란? (+bcrypt) (0) | 2021.02.07 |