Web - JWT

호호빵·2022년 5월 10일
0

Web

목록 보기
11/12

JWT(JSON Web Token)

JSON 객체를 사용해 정보를 안정성 있게 전달하는 웹표준
유저를 인증하고 식별하기 위한 토큰(Token)기반 인증.

  • 사용자가 로그인하면 서버에서 회원임을 인증하는 토큰을 넘겨줌으로써 이후 회원만 접근할 수 있는 서비스 영역에서 신분을 확인하는 데 쓰임
  • 토큰은 세션과 달리 클라이언트에 저장되기 때문에 메모리나 스토리지 등을 통해 세션을 관리했던 서버의 부담을 덜어줌
  • 토큰을 클라이언트에 저장하고 요청시 단순히 HTTP 헤더에 첨부하는 것만으로 단순히 데이터를 요청하고 받아올 수 있음

JWT의 구조

  • Header, Payload, Signature 로 구성
  • Header : JWT에서 사용할 타입과 해시 알고리즘의 종류
  • Payload : 서버에서 첨부한 사용자 권한 정보와 데이터
  • Signature : Header,Payload를 Base64 URL-safe Encode를 한 후, Header에 명시된 함수를 적용하고, 개인키로 서명한 전자서명
  • 사용자가 서버로 JWT를 전송하면 서버는 서명을 검증하는 과정을 거치게 되며 검증이 완료되면 요청한 응답을 돌려줌.
1. 클라이언트가 사용자의 아이디, 패스워드를 통해 웹서비스 인증
2. 서버에서 서명된 JWT를 생성하여 클라이언트 응답으로 돌려주기
3. 클라이언트가 서버에 데이터를 추가적으로 요구할 때 JWT를 HTTP Header에 첨부
4. 서버에서 클라이언트로부터 온 JWT를 검증
# app.py

@app.route('/sign_in', methods=['POST'])
def sign_in():
    # 로그인
    username_receive = request.form['username_give']
    password_receive = request.form['password_give']

    pw_hash = hashlib.sha256(password_receive.encode('utf-8')).hexdigest()
    # username, 암호화된 pw로 유저 정보 찾기
    result = db.users.find_one({'username': username_receive, 'password': pw_hash})


	# 찾으면 JWT 토큰을 만들어서 발급
 	# JWT 토큰에는, payload와 시크릿키 필요
    # 시크릿키로 토큰을 디코딩
    # payload에는 id값과, exp(만료시간)을 담아보냄
    
    if result is not None:
        payload = {
         'id': username_receive,
         'exp': datetime.utcnow() + timedelta(seconds=60 * 60 * 24)  # 로그인 24시간 유지
        }
        token = jwt.encode(payload, SECRET_KEY, algorithm='HS256').decode('utf-8')
		
        # 토큰 전송
        return jsonify({'result': 'success', 'token': token})
    
    # 찾지 못하면
    else:
        return jsonify({'result': 'fail', 'msg': '아이디/비밀번호가 일치하지 않습니다.'})


# 클라이언트
function sign_in() {
    let username = $("#input-username").val()
    let password = $("#input-password").val()

    if (username == "") {
        $("#help-id-login").text("아이디를 입력해주세요.")
        $("#input-username").focus()
        return;
    } else {
        $("#help-id-login").text("")
    }

    if (password == "") {
        $("#help-password-login").text("비밀번호를 입력해주세요.")
        $("#input-password").focus()
        return;
    } else {
        $("#help-password-login").text("")
    }
    $.ajax({
        type: "POST",
        url: "/sign_in",
        data: {
            username_give: username,
            password_give: password
        },
        success: function (response) {
            if (response['result'] == 'success') {
                $.cookie('mytoken', response['token'], {path: '/'});
                window.location.replace("/")
            } else {
                alert(response['msg'])
            }
        }
    });
}

JWT 더 알아보기
https://tansfil.tistory.com/58?category=255594
https://datatracker.ietf.org/doc/html/rfc7519

profile
하루에 한 개념씩

0개의 댓글