昨天是簡單的API範例,今天要實現更進階的 API 應用,擴展 API 功能,並使用 Ngrok 將它公開給其他用戶。進階應用包括 API 的多路由、身份驗證,以及與第三方服務的集成。
以下是一個進階的 API 應用示例,結合 Flask 和 Ngrok,並展示如何進行身份驗證、處理不同的 HTTP 請求方法,以及利用 Ngrok 讓外部用戶可以訪問 API。
pip install flask ngrok pyngrok
from flask import Flask, jsonify, request, abort
from pyngrok import ngrok
app = Flask(__name__)
# 模擬數據庫
users = {
"user1": {"name": "Alice", "age": 30},
"user2": {"name": "Bob", "age": 25}
}
# 身份驗證
def check_auth(token):
# 假設的 API token 驗證
return token == "secret-token"
@app.route('/api/users', methods=['GET'])
def get_users():
token = request.headers.get('Authorization')
if not check_auth(token):
return abort(401) # Unauthorized
return jsonify(users)
# 查詢特定用戶資料
@app.route('/api/users/<username>', methods=['GET'])
def get_user(username):
token = request.headers.get('Authorization')
if not check_auth(token):
return abort(401)
user = users.get(username)
if user:
return jsonify(user)
else:
return abort(404) # Not Found
# 新增用戶資料
@app.route('/api/users', methods=['POST'])
def add_user():
token = request.headers.get('Authorization')
if not check_auth(token):
return abort(401)
if not request.json or not 'name' in request.json:
return abort(400) # Bad Request
new_user = {
"name": request.json["name"],
"age": request.json.get("age", 0)
}
user_id = f"user{len(users) + 1}"
users[user_id] = new_user
return jsonify({user_id: new_user}), 201 # Created
# 啟動 ngrok 並公開 API
if __name__ == "__main__":
# 啟動 Ngrok 隧道
public_url = ngrok.connect(5000)
print(" * Public URL:", public_url)
# 運行 Flask 應用
app.run(port=5000)
Authorization
標頭中的 token,如果不匹配將返回 401 Unauthorized
狀態碼。/api/users
支持 GET
和 POST
方法。/api/users/<username>
支持 GET
方法,來查詢特定用戶資料。400 Bad Request
或 404 Not Found
錯誤,來處理無效的請求。運行這個 Python 應用後,你會在終端中看到此輸出:
* Public URL: http://xxxxxxxx.ngrok-free.app
此時,Ngrok 已經為你的本地 API 創建了一個公開的 URL。你可以將這個 URL 發送給外部用戶,讓他們訪問 API。
你可以使用 Postman 或curl
來進行測試:
如果你正在使用 Postman 來測試這個 API,設置如下:
GET
或 POST
)。http://xxxxxxxx.ngrok-free.app/api/users
Authorization
。secret-token
。curl
發送請求在這個請求中,Authorization
標頭包含了 secret-token
,這樣伺服器端的 Flask 應用就能識別這個請求來自於管理員,並根據管理員的角色授予相應的權限。
curl -H "Authorization: secret-token" http://xxxxxxxx.ngrok-free.app/api/users
基於角色的權限控制,讓不同的用戶具有不同的 API 使用權限,例如:
def check_auth(token, required_role=None):
# 根據 token 驗證用戶角色
if token == "admin-token":
return required_role in ["admin", "user"]
elif token == "user-token":
return required_role == "user"
return False
使用 Flask-RESTful
和 flasgger
生成 Swagger 文檔,讓使用者可以通過網頁介面直接查看和測試 API。
安裝必要套件:
pip install flask-restful flasgger
集成 Flask-RESTful
和 flasgger
:
from flask import Flask
from flask_restful import Api, Resource
from flasgger import Swagger
app = Flask(__name__)
api = Api(app)
swagger = Swagger(app)
class HelloWorld(Resource):
def get(self):
"""
This is an example endpoint.
---
responses:
200:
description: A successful response
"""
return {'hello': 'world'}
api.add_resource(HelloWorld, '/')
if __name__ == '__main__':
app.run(debug=True)
訪問 Swagger 文檔:
在啟動 Flask 應用後,你可以在瀏覽器中打開 http://127.0.0.1:5000/apidocs
來查看 Swagger 自動生成的 API 文檔。這將顯示所有已定義的 API 路徑以及它們的描述,讓你可以測試不同的 API 調用。
你可以使用 Authlib
來集成 OAuth 2.0,為你的 API 提供更高的安全性。
Authlib
pip install authlib
from authlib.integrations.flask_oauth2 import AuthorizationServer, ResourceProtector
from authlib.oauth2.rfc6749 import grants
from flask import Flask
app = Flask(__name__)
# 假設你已經有一個 Authorization Server 設定
server = AuthorizationServer(app)
@app.route('/api/protected')
def protected():
# 需要 OAuth 認證
return {'message': 'This is a protected route'}
if __name__ == '__main__':
app.run(debug=True)
為了防止 API 被濫用,你可以使用 Flask-Limiter 來限制每個 IP 的請求次數。
安裝 Flask-Limiter
:
pip install Flask-Limiter
集成 Flask-Limiter
:
from flask import Flask
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
app = Flask(__name__)
limiter = Limiter(app, key_func=get_remote_address)
@app.route('/api')
@limiter.limit("5 per minute")
def index():
return 'This route is limited to 5 requests per minute'
if __name__ == '__main__':
app.run(debug=True)
這樣可以限制每個 IP 每分鐘只能訪問 5 次,防止濫用。