JINIers
[GCP] flask로 rest api 구현하기 본문
[GCP] flask로 rest api 구현하기
참고자료
https://justkode.kr/python/flask-restapi-1
https://rekt77.tistory.com/104?category=825845
https://flask-docs-kr.readthedocs.io/ko/latest/ko/installation.html#installation
기초 뼈대 만들기
app.py 작성후 인스턴스의 external ip 클릭
* https:// ~ 말고 http:// 로 해야함
app2.py
from flask import Flask
from flask_restx import Api, Resource
app = Flask(__name__)
api = Api(app)
@api.route('/hello/<string:name>')
class HelloWorld(Resource):
def get(self, name):
return 'message : welcome, %s!' %name
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=80)
http://34.121.234.101/hello 경로로 들어갔을 때
get, post, put, delete 방식
- get : 브라우저가 서버에 요청, 서버가 정보를 보낸다.
일반적인 메소드
- post : 브라우저가 서버에게 정보를 '전송' 하도록 특정 url에 요청
전송된 정보가 한번 저장하는 것을 보장하는 데이터전송방식
- put : post와 유사
전송된 정보가 여러번 실행됨
브라우저와 서버 사이의 정보의 단절 없이 요청을 안전하게 받을 수 있다.
- delete : 주어진 위치에 있는 정보를 제거
app3.py
from flask import Flask, request
from flask_restx import Resource, Api
app = Flask(__name__)
api = Api(app)
todos = {}
count = 1
@api.route('/todos')
class TodoPost(Resource): // class 안써줘도 댐!!
def post(self):
global count
global todos
idx = count
count += 1
todos[idx] = request.json.get('data')
return { // 이부분에 pub/sub & BG 들어가는 거
'todo_id': idx,
'data': todos[idx]
}
@api.route('/todos/<int:todo_id>')
class TodoSimple(Resource):
def get(self, todo_id):
return {
'todo_id' : todo_id,
'data' : todos[todo_id]
}
def put(self, todo_id):
todos[todo_id] = request.joson.get('data')
return {
'todo_id' : todo_id,
'data' : todos[todo_id]
}
def delete(self, todoid):
del todos[todo_id]
return {
"delete" : "sucess"
}
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=80)
jwt로 사용자 인증하기
* jwt : Json Web Token, 유저정보를 서버나 세션에 담아두지 않음
header, payload, signature
각 부분 base64url로 인코딩
각 부분을 잇기 위해 '.' 사용하여 구분
* bcrypt : 암호화, 암호일치확인 (단방향 암호화)
설치가 되어있지 않으면 설치하자.
pip install bcrypt
pip install PyJWT
파일은 두개를 만들 것
vim appy4.py
vim auth.py
app4.py
from flask import Flask, request
from flask_restx import Resource, Api
from auth import Auth
app = Flask(__name__)
api = Api(
app,
version='0.1',
title="api server!",
description="todo api server!",
terms_url="/",
contact="ming406@gmail.com",
license="MIT"
)
api.add_namespace(Auth, '/auth')
todos = {}
count = 1
@api.route('/todos')
class TodoPost(Resource):
def post(self):
global count
global todos
idx = count
count += 1
todos[idx] = request.json.get('data')
return {
'todo_id': idx,
'data': todos[idx]
}
@api.route('/todos/<int:todo_id>')
class TodoSimple(Resource):
def get(self, todo_id):
return {
'todo_id' : todo_id,
'data' : todos[todo_id]
}
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=80)
auth.py
import jwt
import bcrypt
from flask import request
from flask_restx import Resource, Api, Namespace, fields
users = {} // 여길 지우고 여기에 db 연동
Auth = Namespace(
name="Auth",
description="user API",
)
user_fields = Auth.model('User', {
'name' : fields.String(description='a user name', required=True, example="song")
}
)
user_fields_auth = Auth.inherit('user auth', user_fields, {
'password' : fields.String(description='password', required=True, example="password")
}
)
jwt_fields = Auth.model('JWT', {
'authorization' : fields.String(description='authorization which you must inclued in header', required=True, example="eyJ0e19~~~~~~~~~~")
}
)
@Auth.route('/register')
class AuthRegister(Resource):
@Auth.expect(user_fields_auth)
@Auth.doc(responses={200: 'success'})
@Auth.doc(responses={500: 'register failed'})
def post(self):
name = request.json['name']
password = request.json['password']
if name in users:
return {
"message":"register failed"
}, 500
else:
users[name] = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt())
return {
'authorization': jwt.encode({'name': name}, "secret", algorithm="HS256")
}, 200
@Auth.route('/login')
class AuthLogin(Resource):
@Auth.expect(user_fields_auth)
@Auth.doc(responses={200: 'success'})
@Auth.doc(responses={404: 'user not found'})
@Auth.doc(responses={500: 'auth failed'})
def post(self):
name = request.json['name']
password = request.json['password']
if name not in users:
return {
"message" : "user not found"
}, 404
elif not bcrypt.checkpw(password.encode('utf-8'), users[name]):
return{
"messge" : "auth failed"
}, 500
else:
return {
'authorization':jwt.encode({'name':name}, "secrest", algorithm="HS256")
}, 200
@Auth.route('/get')
class AuthGet(Resource):
@Auth.doc(responses={200: 'success'})
@Auth.doc(responses={404: 'login failed'})
def get(self):
header = request.headers.get('authorization')
if header == None:
return {"message": "please login"}, 404
data = jwt.decode(header, "secret", algorithms="HS256")
return data, 200
post 방식으로 json을 통해 id, pw 등록
하지만 pw가 다르다면...?
'공부 > Python' 카테고리의 다른 글
[Python 100 day challenge ] Day 2 (1) | 2024.03.15 |
---|---|
[Python 100 day challenge ] Day 1 (0) | 2024.03.15 |
1장 파이썬 기초 연습문제 (0) | 2022.06.11 |
파이썬 함수 정리 1 (0) | 2022.04.11 |
파이썬&뮤 편집기 다운로드 및 설치 (0) | 2022.03.19 |