회원 가입 & 로그인 & 글쓰기

Tasic·2021년 6월 7일
0

Django

목록 보기
2/2


웹 서비스를 사용할때, 보통은 회원 가입 및 로그인을 하고 사용이 가능합니다. 이과정들에서 어떠한 기술들이 필요한지 정리하였습니다.

인증(Authentication)

유저의 identification을 확인하는 절차

인증 절차

  1. 유저 아이디와 비번 생성
  2. 유저 비번 암호화 해서 DB에 저장.
  3. 유저 로그인 -> 아이디와 비밀번호 입력
  4. 유저가 입력한 비밀번호 암호화 한후 암호화되서 DB에 저정된 유저 비밀번호와 비교.
  5. 일치하면 로그인 성공
  6. 로그인 성공하면 access token을 클라이언트에게 전송.
  7. 유저는 로그인 성공후 다음부터는 access token을 첨부해서 request를 서버에 전송함으로서 매번 로그인 해도 되지 않도록 한다.

인가(Authorization)

유저가 요청하는 request를 실행할 수 있는 권한이 있는 유저인가를 확인하는 절차 이다.

인가 절차

  1. 인증 절차를 통해 access token을 생성한다. access token에는 유저 정보를 확인할 수 있는 정보가 들어가 있어야 한다. (예를 들어 user id)
    • 이 정보는 유일해야된다 (이름같은 중복되는 정보는 안됨)
  2. 유저가 request를 보낼때 access token을 첨부해서 보낸다.
  3. 서버에서는 유저가 보낸 access token을 복호화 한다.
  4. 복호화된 데이터를 통해 user id를 얻는다.
  5. user id를 사용해서 database에서 해당 유저의 권한(permission)을 확인하다.
  6. 유저가 충분한 권한을 가지고 있으면 해당 요청을 처리한다.
  7. 유저가 권한을 가지고 있지 않으면 Unauthorized Response(401) 혹은 다른 에러 코드를 보낸다.

비밀번호 암호화

유저의 비밀번호는 절대 그대로 DB에 저장하면 안됩니다.

  • DB가 해킹을 당하면 유저의 비밀번호도 그대로 노출 됩니다.
  • 외부 해킹이 아니더라도 서비스 개발자 들이 유저들의 비밀번호를 볼 수 있습니다.

비밀번호 암호에는 단방향 해쉬 함수(one-way hash function)가 일반적으로 쓰입니다.

  • 단방향 해시 함수는 원본 메시지를 변환하여 암호화된 메시지인 다이제스트(digest)를 생성합니다.
  • 원본 메시지를 알면 암호화된 메시지를 구하기는 쉽지만 암호화된 메시지로는 원본 메시지를 구할 수 없어서 단방향성(one-way) 이라고 합니다.

Bcrypt

패스워드 저장을 목적으로 설계되어 매우 강력한 패스워드 다이제스트를 생성하는 시스템을 쉽게 구현할 수 있다. 관련된 라이브러리도 언어별로 쉽게 찾을 수 있습니다.

# 비밀번호 암호화 하기
In [42]: hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
In [43]: hashed_password
Out[43]: b'$2b$12$FyPZgflEujF6H.Ur2aZHIuOqFmOM.lzgS8zVRQ1SAlmUiPOmSihCG'

# 비밀번호 확인
In [46]: bcrypt.checkpw('1234'.encode('utf-8'), hashed_password)
Out[46]: True

access token

  • 유저가 로그인에 성공한 후에는 access token이라고 하는 암호화된 유저 정보를 첨부해서 request를 보내게 된다.
  • 이런 절차의 목적은 해당 유저가 매번 로그인 해도 되지 않도록 하는 것이다.
  • 서버에서는 암호화된 유저정보를 받아서 복호화해서 해당 유저가 누구 인지 알 수 있다.
  • 복호화가 되기 때문에, 양방형성 이라고 합니다.

jwt (JSON Web Tokens)

  • access token을 생성하는 방법중 가장 널리 사용되는 기술중 하나
  • JWT는 말 그대로 유저 정보를 담음 JSON 데이터를 암호화 해서 클라이언트와 서버간에 주고 받는 것입니다.
SECRECT_KEY = 'asdfghjkl'

# 암호화
In [53]: hashed_user_id = jwt.encode({'user_id': '100'}, SECRECT_KEY, algorithm='HS256')
In [54]: hashed_user_id
Out[54]: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiMTAwIn0.Q2gKLee212mZtPKqD0GzIlmAt64mRPqqu8CQ7OE3a6M'

# 복호화
In [55]: jwt.decode(hashed_user_id, SECRECT_KEY, algorithms='HS256')
Out[55]: {'user_id': '100'}

SECRECT_KEY와 algorithm을 다른 사용자가 안다면 복호화를 할 수 있으므로, 유출되서는 안됩니다.

정리

  1. 회원가입시 비밀번호 같은 유출이 되서는 안되는 정보는 단방향성 hash알고리즘으로 암호화 후 로그인 시에 사용자가 입력한 정보와 db에 있는 정보가 일치하는지만 확인
  2. 로그인이 되면 서버에서 클라이언트에게 암호화된 유저정보를 보내준다. 클라이언트는 요청을 보낼때마다 암호화된 유저정보를 포함해서 요청을 보내면, 서버에서 암호화된 유저 정보를 복호화해서 어떠한 유저인지 알아냄
  3. 암호화된 유저 정보를 키카드라고 생각하면 될 것 같습니다. 그냥 보기에는 카드이기 때문에 어떠한 정보인지 알 수 없으나, 테그를 하게되면 관리자 측에서 해석해서 어떤 유저인지 알 수 있음.

Reference

안전한 패스워드 저장 - naver D2
JSON 웹 토큰 - wikipedia

profile
블로그 옮겼습니다 (https://jotasic.github.io)

0개의 댓글