Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
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
Tags
more
Archives
Today
Total
관리 메뉴

JINIers

[GCP] flask로 rest api 구현하기 본문

공부/Python

[GCP] flask로 rest api 구현하기

JINIers 2022. 5. 9. 16:30

[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)




 

app.py 정상적으로 실행 시

 

http://34.121.234.101/hello 경로로 들어갔을 때

정상적인 구현

 

 

http://34.121.234.101/hello 경로로 들어갔을 때

 

app2.py 실행

 

 

app2.py 실행
app2.py 실행완료

 

 

 


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 등록


 

 

 

 

get, post, put, delete 구현

 

 

post 요청

 

 

 

auth 요청

 

 

이렇게 인증코드를 띄워줌

 

auth/login 에서도 똑같이 확인할 수 있다.

 

하지만 pw가 다르다면...?

 

 

인증 반환

 

 

 

get 반환

 

 

 

'공부 > 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
Comments