목표 : Flask에 회원 비밀번호 암호화 기능을 추가합니다.
1. 암호화 : bcrypt 암호 알고리즘의 특징
일반적인 해시의 취약점을 보완하기 위해 salting과 key stretching 방법이 구현된 bcrypt를 사용합니다.
- salting : 기존 비밀번호 + 특정문자열 -> 으로 해싱을 진행함
- key stretching : 단방향 해시 값을 여러차례 계산해내 해시함 (해시 알고리즘의 빠른 실행 속도 덕분에 채택 가능)
2. bcrypt 설치
$ pip install bcrypt
2. 회원가입 부문에 암호화 기능 추가하기
password 정보를 str->bytes로 변경한 후 bcrypt로 암호화하고, 다시 암호화한 데이터를 str로 변형하여 DB에 저장합니다. bytes로 저장시 데이터가 원하는 방향으로 저장되지 않아 str로 저장하였습니다.
# vim app001/models.py
# ...
def useradd(username, password, email):
# bcrypt hash transfer
password = (bcrypt.hashpw(password.encode('UTF-8'), bcrypt.gensalt())).decode('utf-8')
cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute("INSERT INTO `users` (`username`, `password`, `email`) VALUES (%s, %s, %s)", (username, password, email))
mysql.connection.commit()
# ...
3. 로그인 부문에 암호화 기능 추가하기 ( 매우 중요 )
로그인 시도시에 입력된 password를 str->bytes 로 변경한 데이터와 DB에서 꺼낸 str->bytes 로 변경한 데이터에 대하여 bcrypt.checkpw(A, B) 를 통해 해당 계정의 비밀번호가 일치하는지 확인하고, 정상이면 "check_password=True" & "account=계정정보" 를 return합니다.
( 또한, input_password는 bcrypt로 변형되기 전 상태여야하며, account['password'].encode('utf-8')은 bcrypt로 변형된 후의 상태여야 에러없이 checkpw 가능합니다. )
# vim app001/models.py
# ...
class User():
def login_check(input_username, input_password):
# bcrypt hash transfer
input_password = input_password.encode('utf-8')
# MySQL DB에 해당 계정 정보가 있는지 확인
cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute('SELECT * FROM users WHERE username = %s', [input_username])
# 값이 유무 확인 결과값 account 변수로 넣기
account = cursor.fetchone()
check_password = bcrypt.checkpw(input_password, account['password'].encode('utf-8'))
return account, check_password
# ...
4. models.py의 User.login_check() 함수 return값 2개 가져오도록 수정하기
User.login_check() 함수 return 값을 위에서 2개로 증가시켜주었으니, 받는 변수도 2개로 증가시켜줍니다.
# vim app001/routes.py
# ...
# http://host:5005/login/ - this will be the login page, we need to use both GET and POST requests
@app.route('/login/', methods=['GET', 'POST'])
def login():
# ...
account, check_password = User.login_check(username, password)
# ...
5. DB password data & Login/Register 기능 확인
DB에 값도 잘 저장되어있고, 회원가입, 로그인 모두 정상임을 확인합니다.
6. 완성된 코드는 아래에서 다운로드 가능
'Development > Flask with Python' 카테고리의 다른 글
[Solved][Flask1.1] jsonify 한글 인코딩 변경되어 비정상 출력 문제 해결 방법 2가지 (1) | 2020.01.22 |
---|---|
[Flask1.1][Mysql] 실습 - 9 : jwt 활용하여 인증 기능 추가하기 (0) | 2020.01.17 |
[Flask1.1][Mysql] 실습 - 7 : 회원가입 기능 구현하기 (0) | 2020.01.16 |
[Flask1.1][Mysql] 실습 - 6 : 로그인시 접속한 기기의 IP 정보 받기 & 로그인 페이지 리다이렉트 기능 추가 (0) | 2020.01.06 |
[Flask1.1][Mysql] 실습 - 5 : routes와 models 파일 별도로 만들기 (0) | 2020.01.06 |