항해99 Week_01 WIL

그루트·2021년 9월 19일
0

프로젝트01

앱 개발을 처음 배우게 됐을 때, 각종 화면을 디자인해보면서 프론트엔드 개발에 큰 흥미가 생겼서 프론트엔드 개발자를 꿈꾸게 됬어요. 그러나 서버와 통신을 처음 배웠을 때 마냥 쉬운 일은 아니구나라고 생각했습니다. 항상 당연하게 생각해왔던 기능(데이터를 보내고 받는 작업)들을 직접 구현하려고 하니 헷갈리는게 한둘이 아니더라구요

그래도 팀원들과 소통하며 공부했던 과정을 실제로 적용해봐서 확실히 좋았어요.
팀원과 무엇을 목표로 만드는과정을 해보지못해서 많이 낯설었습니다.
하지만 팀원분들이 다들 착하시고 프로젝트를 진행하는데 있어 매우 적극적이시고 본인이 알고있는 지식을 공유하는것을 주저하시지않으셔서 매우좋았어요!

머... 지금도 쉽진 않지만 계속해서 적용해보면 좋아질꺼라고 생갑합니다 😊

팀원과 무엇을 목표로 만드는과정을 해보지못해서 많이 낯설었습니다.
하지만 팀원분들이 다들 착하시고 프로젝트를 진행하는데 있어 매우 적극적이시고 본인이 알고있는 지식을 공유하는것을 주저하시지않으셔서 매우좋았어요!👍

처음에는 와이어프레임을 짜는것부터 난관이였어요.
하지만 서로의 의견을 적극적으로 제시하고 받아드리면서 해결했어요.😁

github사용이 미숙해서 팀원들 끼리 고생 좀 했습니다.😥
일딴 기본적인 git init, git clone, git add -A, git commit -m "~", git push, git pull로 일일이 영상을 공유하며 작업 했어요..
예전에 따로 공부는 했지만 오래 사용하지않아서인지 까먹어서...
github사용법 공부를 따로 해야겠습니다.😂

매일 새벽 2시 전까진 안 자고 했던거 같아요.
나름 결과가 잘 나왔다고 생각하는데 아직 부족한게 많으니 더 열심히 해야겠죠?😏

결과물

WaterMelon

WaterMelon 시연영상


로그인 기능을 구현하면서 JWT 기능에 대해 공부 하고 적용했어요!

--사용시 임포트--

JWT 패키지를 사용합니다. (설치해야할 패키지 이름: PyJWT)
import jwt

토큰에 만료시간을 줘야하기 때문에, datetime 모듈도 사용합니다.
import datetime

회원가입 시엔, 비밀번호를 암호화하여 DB에 저장해두는 게 좋습니다.
그렇지 않으면, 개발자(=나)가 회원들의 비밀번호를 볼 수 있으니까요.^^;
import hashlib

플라스크 서버에서 로그인 기능 구현하기

  • 로그인 시, 비밀번호를 같은 방법으로 암호화한 후, DB에서 해당 아이디와 비밀번호를 갖는 회원이 있는지 찾습니다. 회원 정보가 없는 경우 실패 메시지를 보내고, 찾은 경우 아이디와 토큰 만료 시간을 저장하는 토큰을 만들어 넘겨줍니다.
  • 로그인 성공 메시지를 받으면 건네받은 토큰을 쿠키로 저장하여 만료되기 전까지 갖고 있으면서, API 요청을 보낼 때마다 회원임을 확인받습니다.
  • 로그아웃 시 해당 토큰을 삭제합니다.

JWT

JWT 란?

JSON Web Token의 줄임말로, JSON 객체를 사용해 정보를 안정성 있게 전달하는 웹표준이에요!

사용자는 Access Token(JWT 토큰)을 HTTP 헤더에 실어 서버로 보내게 됩니다.

예를 들어, 로그인 기능을 생각해보면 사용자가 로그인하면 서버에서 회원임을 인증하는 토큰을 넘겨줌으로써 이후 회원만 접근할 수 있는 서비스 영역에서 신분을 확인하는 데 쓰일 수 있죠!
인증에 필요한 정보들을 암호화시킨 토큰을 뜻합니다


인증이 필요한 이유

인증은 프론트엔드 관점에서 봤을 때 사용자의 로그인, 회원가입과 같이 사용자의 도입부분을 가리키곤 합니다. 반면 서버사이드 관점에서 봤을 때는 모든 API 요청에 대해 사용자를 확인하는 작업입니다.
사용자 A와 사용자 B가 앱을 사용한다고 가정하겠습니다. 두 사용자는 기본적으로 정보가 다르고 보유하고 있는 컨텐츠도 다릅니다. 따라서 서버에서는 A,B가 요청을 보냈을 때 누구의 요청인지를 정확히 알아야 합니다. 만일 그렇지 못한다면, 자신의 정보가 타인에게 유출되는 최악의 상황이 발생하겠죠? 그렇기에 앱(프론트 엔드)에서는 자신이 누구인지를 알만한 단서를 서버에 보내야 하며, 서버는 그 단서를 파악해 각 요청에 맞는 데이터를 뿌려주게 되요.


토큰을 만들기 위해서는 크게 3가지, Header,Payload, Verify Signature가 필요합니다.
Header : 위 3가지 정보를 암호화할 방식(alg), 타입(type) 등이 들어갑니다.
Payload : 서버에서 보낼 데이터가 들어갑니다. 일반적으로 유저의 고유 ID값, 유효기간이 들어갑니다.
Verify Signature : Base64 방식으로 인코딩한 Header,payload 그리고 SECRET KEY를 더한 후 서명됩니다.

최종적인 결과 : Encoded Header + "." + Encoded Payload + "." + Verify Signature
Header, Payload는 인코딩될 뿐(16진수로 변경), 따로 암호화되지 않습니다. 따라서 JWT 토큰에서 Header, Payload는 누구나 디코딩하여 확인할 수 있습니다. 여기서 누구나 디코딩할 수 있다는 말은 Payload에는 유저의 중요한 정보(비밀번호)가 들어가면 쉽게 노출될 수 있다는 말이 됩니다.

하지만 Verify Signature는 SECRET KEY를 알지 못하면 복호화할 수 없습니다.
A 사용자가 토큰을 조작하여 B 사용자의 데이터를 훔쳐보고 싶다고 가정하겠습니다. 그래서 payload에 있던 A의 ID를 B의 ID로 바꿔서 다시 인코딩한 후 토큰을 서버로 보냈습니다. 그러면 서버는 처음에 암호화된 Verify Signature를 검사하게 됩니다. 여기서 Payload는 B사용자의 정보가 들어가 있으나 Verify Signature는 A의 Payload를 기반으로 암호화되었기 때문에 유효하지 않는 토큰으로 간주하게 됩니다. 여기서 A사용자는 SECRET KEY를 알지 못하는 이상 토큰을 조작할 수 없다는 걸 확인할 수 있습니다.

JWT 인증 사용법

  1. 사용자가 로그인을 한다.
  2. 서버에서는 계정정보를 읽어 사용자를 확인 후, 사용자의 고유한 ID값을 부여한 후, 기타 정보와 함께 Payload에 넣습니다.
  3. JWT 토큰의 유효기간을 설정합니다.
  4. 암호화할 SECRET KEY를 이용해 ACCESS TOKEN을 발급합니다.
  5. 사용자는 Access Token을 받아 저장한 후, 인증이 필요한 요청마다 토큰을 헤더에 실어 보냅니다.
  6. 서버에서는 해당 토큰의 Verify Signature를 SECRET KEY로 복호화한 후, 조작 여부, 유효기간을 확인합니다.
  7. 검증이 완료된다면, Payload를 디코딩하여 사용자의 ID에 맞는 데이터를 가져옵니다.

장점

  1. 간편합니다. 세션/쿠키는 별도의 저장소의 관리가 필요합니다.
    그러나 JWT는 발급한 후 검증만 하면 되기 때문에 추가 저장소가 필요 없습니다.
  2. 상태를 저장하지 않아 서버를 확장하거나 유지,보수하는데 유리합니다.

단점

  1. 이미 발급된 JWT에 대해서는 돌이킬 수 없습니다. 세션/쿠키의 경우 만일 쿠키가 악의적으로 이용된다면, 해당하는 세션을 지워버리면 됩니다. 하지만 JWT는 한 번 발급되면 유효기간이 완료될 때 까지는 계속 사용이 가능합니다. 따라서 악의적인 사용자는 유효기간이 지나기 전까지 신나게 정보들을 털어갈 수 있습니다.

  2. Payload 정보가 제한적입니다. 위에서 언급했다시피 Payload는 따로 암호화되지 않기 때문에 디코딩하면 누구나 정보를 확인할 수 있습니다. (세션/쿠키 방식에서는 유저의 정보가 전부 서버의 저장소에 안전하게 보관됩니다) 따라서 유저의 중요한 정보들은 Payload에 넣을 수 없습니다.

  3. JWT의 길이입니다. 세션/쿠키 방식에 비해 JWT의 길이는 깁니다. 따라서 인증이 필요한 요청이 많아질 수록 서버의 자원낭비가 발생하게 됩니다.

profile
i'm groot

0개의 댓글