일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- RS-485
- 애플
- SK텔레콤
- 배당
- 파이썬
- raspberry pi
- 홈네트워크
- Espressif
- 매터
- Bestin
- MQTT
- 오블완
- 나스닥
- 코스피
- ConnectedHomeIP
- homebridge
- 티스토리챌린지
- Apple
- 힐스테이트 광교산
- 미국주식
- cluster
- 해외주식
- 월패드
- 국내주식
- 현대통신
- matter
- Home Assistant
- Python
- 공모주
- esp32
- Today
- Total
YOGYUI
Flask - extension을 이용한 HTTP 인증 절차 구현 본문
Flask web server 구현 시 인증 절차를 위해 데코레이터 함수를 직접 구현하는게 일반적이다
관련 링크: https://eddmann.com/posts/using-basic-auth-and-decorators-in-pythons-flask/
하지만 IoT 서버 구동과 같은 단순한 인증 절차만 필요할 경우 Flask_HTTPAuth같은 extension을 설치해 간단하게 해결할 수 있다 (로그아웃같은 기능은 session 별도 구현 필요)
본 포스팅에서는 Flask_HTTPAuth를 활용한 HTTP Basic 인증에 대한 예시만 다룬다
HTTP Digest 인증, (JWS/JWT) 토큰 인증 방식 / user-role 등에 대한 내용은 공식 페이지에서 참고하도록 한다
[Structure]
+ proj
+ templates
- index.html
- result.html
- app.py
1. Flask 서버 코드 구현
# app.py
from flask import Flask, render_template
from flask_httpauth import HTTPBasicAuth
from werkzeug.security import generate_password_hash, check_password_hash
app = Flask(__name__)
auth = HTTPBasicAuth()
users = {
"user1": generate_password_hash("password1")
}
@app.route('/')
def index():
return render_template('index.html')
@app.route('/login')
@auth.login_required
def login():
user = auth.current_user()
return render_template('result.html', user=user)
@auth.verify_password
def verify_password(username, password):
if username in users and check_password_hash(users.get(username), password):
print('verify_password success >> username: {}, password: {}'.format(username, password))
return username # If the credentials belong to a user, then the function should return the user object.
print('verify_password failed >> username: {}, password: {}'.format(username, password))
return None # If the credentials are invalid the functon can return None or False.
if __name__ == '__main__':
app.run(host='127.0.0.1', port=9999, debug=True)
2. HTML 코드 작성
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<h1>Authentication Test Module</h1>
<form method="get" action="/login" enctype="text/plain">
<input type="submit" value="LOGIN" name="">
</form>
</body>
</html>
<!-- result.html -->
<!DOCTYPE html>
<html>
<head>
<title>Result</title>
</head>
<body>
<h1>Result</h1>
<a>
Your Name is
{% if user %}
{{ user }}
{% else %}
?
{% endif %}
</a>
</body>
</html>
3. 테스트
브라우저 (크롬)을 통해 페이지 접속 (127.0.0.1:9999)
LOGIN 버튼을 클릭하면 (FTP 접속할때처럼) 로그인 창이 뜬다
extension에서 브라우저로 하여금 HTTP Basic Auth 호출 시 기본적으로 호출되는 인터페이스인듯
잘못된 로그인 정보를 기입하고 로그인 버튼을 클릭할 경우 로그인 창이 다시 뜨게 된다 (횟수 제한 없음)
서버 로그를 보면 루틴을 알 수 있다
verify_password failed >> username: user2, password: 1234
127.0.0.1 - - [08/Jan/2021 22:01:39] "GET /login HTTP/1.1" 401 -
verify_password failed >> username: user3, password: 12345
127.0.0.1 - - [08/Jan/2021 22:01:43] "GET /login HTTP/1.1" 401 -
verify_password failed >> username: user1, password: password2
127.0.0.1 - - [08/Jan/2021 22:01:48] "GET /login HTTP/1.1" 401 -
401 - Unauthorized 값을 /login 으로 다시 라우팅된다
로그인 횟수 제한을 두고자 한다면 해당 라우팅에서 구문을 추가해주면 될 것 같다
미리 정의해둔 users 내에 있는 사용자 정보로 로그인 성공하면 /result 로 라우팅되고 다음과 같은 결과를 볼 수 있다
서버 로그
verify_password success >> username: user1, password: password1
127.0.0.1 - - [08/Jan/2021 22:07:29] "GET /login HTTP/1.1" 200 -
200 - OK 결과와 함께 verify_password 데코레이터 통과 후 login 함수 내에서 result.html 템플릿 렌더링까지 이루어진다
HTTP Basic 인증의 특성상 인증 결과는 클라이언트 측의 브라우저 내부 쿠키로 남게 되어 다음번 로그인 호출 시 로그인 창 없이 바로 user1으로 인증이 이루어진다
(다시 한번 언급하자면, 로그아웃 등의 기능은 session을 이용해 구현해야 한다)
4. 정리
homebridge와 같은 IoT 허브 (브릿지)는 특수한 경우를 제외하고는 클라이언트(제어 디바이스, 센서 등)들은 1회성으로 접속 후 데이터 송/수신이 이루어 질 것이기 때문에 별도의 세션을 가지거나 로그아웃 프로세스가 필요하지 않다
이런 경우를 위해서는 충분히 활용가치가 높은 flask extension이라고 생각한다
'Software > Python' 카테고리의 다른 글
Python::구조적 패턴 매칭 - 파이썬에서 switch/case문을?! (0) | 2021.03.21 |
---|---|
Python으로 순서도 그리기 (schemdraw) (0) | 2021.01.27 |
Flask - Dynamic Page Update (Ajax) (0) | 2021.01.10 |
PyQt Serial Port List (0) | 2021.01.07 |
Pyserial 시리얼 통신 모듈 커스터마이징 (0) | 2021.01.01 |