ã«ã¹ã¿ã ãã³ã¬ãŒã¿ãŒã䜿çšããŠFlaskãŠã§ãã¢ããªã±ãŒã·ã§ã³ãä¿è·ããæ¹æ³ãåŠã³ãŸããå®å šãªAPIãšãŠã§ãã€ã³ã¿ãŒãã§ãŒã¹ãæ§ç¯ããããã®å®çšçãªäŸããã¹ããã©ã¯ãã£ã¹ãã°ããŒãã«ãªèæ ®äºé ãæ¢æ±ããŸãã
Flaskã«ã¹ã¿ã ãã³ã¬ãŒã¿ãŒïŒå®å šãªãŠã§ãã¢ããªã±ãŒã·ã§ã³ã®ããã®ã«ãŒãä¿è·ã®å®è£
仿¥ã®çžäºæ¥ç¶ãããäžçã§ã¯ãå®å šãªãŠã§ãã¢ããªã±ãŒã·ã§ã³ã®æ§ç¯ãæãéèŠã§ãã軜éã§æ±çšæ§ã®é«ãPythonãŠã§ããã¬ãŒã ã¯ãŒã¯ã§ããFlaskã¯ãå ç¢ã§ã¹ã±ãŒã©ãã«ãªã¢ããªã±ãŒã·ã§ã³ãäœæããããã®æè»ãªãã©ãããã©ãŒã ãæäŸããŸããFlaskã¢ããªã±ãŒã·ã§ã³ã®ã»ãã¥ãªãã£ã匷åããããã®åŒ·åãªææ³ã®1ã€ã¯ãã«ãŒãä¿è·ã®ããã®ã«ã¹ã¿ã ãã³ã¬ãŒã¿ãŒã®äœ¿çšã§ãããã®ããã°æçš¿ã§ã¯ããããã®ãã³ã¬ãŒã¿ãŒã®å®è£ ã«ã€ããŠè©³ãã説æããéèŠãªæŠå¿µãå®éã®äŸãå®å šãªAPIãšãŠã§ãã€ã³ã¿ãŒãã§ãŒã¹ãæ§ç¯ããããã®ã°ããŒãã«ãªèæ ®äºé ã«ã€ããŠè§£èª¬ããŸãã
Pythonã§ã®ãã³ã¬ãŒã¿ãŒã®çè§£
Flaskåºæã®äŸã«å ¥ãåã«ãPythonã§ã®ãã³ã¬ãŒã¿ãŒã®çè§£ãæ·±ããŸãããããã³ã¬ãŒã¿ãŒã¯ã颿°ãšã¡ãœããã®åäœã倿ŽãŸãã¯æ¡åŒµããããã®åŒ·åãã€ãšã¬ã¬ã³ããªæ¹æ³ã§ããèªèšŒãèªå¯ããã®ã³ã°ãå ¥åæ€èšŒãªã©ã®äžè¬çãªæ©èœããå ã®é¢æ°ã®ã³ãŒããçŽæ¥å€æŽããã«é©çšããããã®ç°¡æœã§åå©çšå¯èœãªã¡ã«ããºã ãæäŸããŸãã
æ¬è³ªçã«ããã³ã¬ãŒã¿ãŒã¯å¥ã®é¢æ°ãå ¥åãšããŠåãåãããã®é¢æ°ã®å€æŽãããããŒãžã§ã³ãè¿ã颿°ã§ããã@ãèšå·ã¯ããã³ã¬ãŒã¿ãŒã颿°ã«é©çšããããã«äœ¿çšãããã³ãŒããããã¯ãªãŒã³ã§èªã¿ãããããŸããç°¡åãªäŸãèããŠã¿ãŸãããã
def my_decorator(func):
def wrapper():
print("Before function call.")
func()
print("After function call.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello() # Output: Before function call. \n Hello! \n After function call.
ãã®äŸã§ã¯ã`my_decorator`ã¯`say_hello`颿°ãã©ãããããã³ã¬ãŒã¿ãŒã§ãã`say_hello`ã®å®è¡ååŸã«æ©èœã远å ããŸããããã¯ãFlaskã§ã«ãŒãä¿è·ãã³ã¬ãŒã¿ãŒãäœæããããã®åºæ¬çãªæ§æèŠçŽ ã§ãã
Flaskã§ã®ã«ã¹ã¿ã ã«ãŒãä¿è·ãã³ã¬ãŒã¿ãŒã®æ§ç¯
ã«ã¹ã¿ã ãã³ã¬ãŒã¿ãŒã䜿çšããã«ãŒãä¿è·ã®èåŸã«ããäžå¿çãªã¢ã€ãã¢ã¯ããªã¯ãšã¹ãããã¥ãŒé¢æ°ïŒã«ãŒãïŒã«å°éããåã«ãªã¯ãšã¹ããã€ã³ã¿ãŒã»ããããããšã§ãããã³ã¬ãŒã¿ãŒã¯ç¹å®ã®åºæºïŒãŠãŒã¶ãŒèªèšŒãèªå¯ã¬ãã«ãªã©ïŒã確èªãããªã¯ãšã¹ãã®ç¶è¡ãèš±å¯ããããé©åãªãšã©ãŒå¿çïŒ401 Unauthorizedã403 Forbiddenãªã©ïŒãè¿ããŸãããããFlaskã§å®è£ ããæ¹æ³ãèŠãŠã¿ãŸãããã
1. èªèšŒãã³ã¬ãŒã¿ãŒ
èªèšŒãã³ã¬ãŒã¿ãŒã¯ããŠãŒã¶ãŒã®IDãæ€èšŒãã圹å²ãæ ããŸããäžè¬çãªèªèšŒæ¹æ³ã«ã¯ã次ã®ãã®ããããŸãã
- åºæ¬èªèšŒïŒãªã¯ãšã¹ãããããŒã§ãŠãŒã¶ãŒåãšãã¹ã¯ãŒãïŒéåžžã¯ãšã³ã³ãŒãæžã¿ïŒãéä¿¡ããŸããå®è£ ã¯ç°¡åã§ãããç¹ã«æå·åãããŠããªãæ¥ç¶ã§ã¯ãä»ã®æ¹æ³ãããå®å šæ§ãäœããšèããããŠããŸãã
- ããŒã¯ã³ããŒã¹èªèšŒïŒJWTãªã©ïŒïŒããŒã¯ã³ïŒå€ãã®å ŽåãJSON Web TokenãŸãã¯JWTïŒã䜿çšããŠããŠãŒã¶ãŒã®IDãæ€èšŒããŸããããŒã¯ã³ã¯éåžžããã°ã€ã³ãæåããåŸã«çæãããåŸç¶ã®ãªã¯ãšã¹ãïŒAuthorizationããããŒãªã©ïŒã«å«ãŸããŸãããã®ã¢ãããŒãã¯ãããå®å šã§ã¹ã±ãŒã©ãã«ã§ãã
- OAuth 2.0ïŒå§ä»»ãããèªå¯ã®ããã®åºã䜿çšãããŠããæšæºããŠãŒã¶ãŒã¯ãèªåã®è³æ Œæ å ±ãçŽæ¥å ±æããããšãªãããµãŒãããŒãã£ã¢ããªã±ãŒã·ã§ã³ã«èªåã®ãªãœãŒã¹ïŒãœãŒã·ã£ã«ã¡ãã£ã¢ãã©ãããã©ãŒã äžã®ããŒã¿ãªã©ïŒãžã®ã¢ã¯ã»ã¹ãèš±å¯ããŸãã
ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ã®ããã«ãããŒã¯ã³ïŒãã®å Žåã¯JWTïŒã䜿çšããåºæ¬çãªèªèšŒãã³ã¬ãŒã¿ãŒã®äŸã次ã«ç€ºããŸãããã®äŸã§ã¯ãJWTã©ã€ãã©ãªïŒPyJWTãªã©ïŒã䜿çšããããšãåæãšããŠããŸãã
import functools
import jwt
from flask import request, jsonify, current_app
def token_required(f):
@functools.wraps(f)
def decorated(*args, **kwargs):
token = None
if 'Authorization' in request.headers:
token = request.headers['Authorization'].split(' ')[1] # Extract token after 'Bearer '
if not token:
return jsonify({"message": "Token is missing!"}), 401
try:
data = jwt.decode(token, current_app.config['SECRET_KEY'], algorithms=['HS256'])
# You'll likely want to fetch user data here from a database, etc.
# For example: user = User.query.filter_by(id=data['user_id']).first()
# Then, you can pass the user object to your view function (see next example)
except jwt.ExpiredSignatureError:
return jsonify({"message": "Token has expired!"}), 401
except jwt.InvalidTokenError:
return jsonify({"message": "Token is invalid!"}), 401
return f(*args, **kwargs)
return decorated
説æïŒ
- `token_required(f)`ïŒããã¯ãã³ã¬ãŒã¿ãŒé¢æ°ã§ããã¥ãŒé¢æ°`f`ãåŒæ°ãšããŠåããŸãã
- `@functools.wraps(f)`ïŒãã®ãã³ã¬ãŒã¿ãŒã¯ãå ã®é¢æ°ã®ã¡ã¿ããŒã¿ïŒååãããã¥ã¡ã³ãæååãªã©ïŒãä¿æããŸãã
- `decorated(*args, **kwargs)`å ïŒ
- `Authorization`ããããŒã®ååšã確èªããããŒã¯ã³ïŒãBearerãããŒã¯ã³ãæ³å®ïŒãæœåºããŸãã
- ããŒã¯ã³ãæäŸãããŠããªãå Žåã¯ã401 Unauthorizedãšã©ãŒãè¿ããŸãã
- Flaskã¢ããªã±ãŒã·ã§ã³ã®æ§æãã`SECRET_KEY`ã䜿çšããŠJWTã®ãã³ãŒãã詊ã¿ãŸãã`SECRET_KEY`ã¯å®å šã«ä¿ç®¡ããå¿ èŠããããã³ãŒãã«çŽæ¥èšè¿°ããªãã§ãã ããã
- ããŒã¯ã³ãç¡å¹ãŸãã¯æéåãã®å Žåã¯ã401ãšã©ãŒãè¿ããŸãã
- ããŒã¯ã³ãæå¹ãªå Žåã¯ãåŒæ°ãšãšãã«å ã®ãã¥ãŒé¢æ°`f`ãå®è¡ããŸãããã³ãŒãããã`data`ãŸãã¯ãŠãŒã¶ãŒãªããžã§ã¯ãããã¥ãŒé¢æ°ã«æž¡ãããšãã§ããŸãã
äœ¿ãæ¹ïŒ
from flask import Flask, jsonify
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
@app.route('/protected')
@token_required
def protected_route():
return jsonify({"message": "This is a protected route!"}), 200
`/protected`ã«ãŒãã«ã¢ã¯ã»ã¹ããã«ã¯ãæå¹ãªJWTã`Authorization`ããããŒïŒäŸïŒ`Authorization: Bearer
2. èªå¯ãã³ã¬ãŒã¿ãŒ
èªå¯ãã³ã¬ãŒã¿ãŒã¯ãèªèšŒã«åºã¥ããŠæ§ç¯ããããŠãŒã¶ãŒãç¹å®ã®ãªãœãŒã¹ã«ã¢ã¯ã»ã¹ããããã«å¿ èŠãªæš©éãæã£ãŠãããã©ããã倿ããŸããããã¯éåžžããŠãŒã¶ãŒã®ããŒã«ãŸãã¯æš©éãäºåå®çŸ©ãããã«ãŒã«ã»ãããšç §åããããšã«ãã£ãŠè¡ãããŸããããšãã°ã管çè ã¯ãã¹ãŠã®ãªãœãŒã¹ã«ã¢ã¯ã»ã¹ã§ããäžæ¹ãäžè¬ãŠãŒã¶ãŒã¯èªåã®ããŒã¿ã«ã®ã¿ã¢ã¯ã»ã¹ã§ããå ŽåããããŸãã
ç¹å®ã®ãŠãŒã¶ãŒããŒã«ã確èªããèªå¯ãã³ã¬ãŒã¿ãŒã®äŸã次ã«ç€ºããŸãã
import functools
from flask import request, jsonify, current_app
def role_required(role):
def decorator(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
# Assuming you have a way to get the user object
# For example, if you're using the token_required decorator
# and passing the user object to the view function:
try:
user = request.user # Assume you've set the user object in a previous decorator
except AttributeError:
return jsonify({"message": "User not authenticated!"}), 401
if not user or user.role != role:
return jsonify({"message": "Insufficient permissions!"}), 403
return f(*args, **kwargs)
return wrapper
return decorator
説æïŒ
- `role_required(role)`ïŒããã¯ãã³ã¬ãŒã¿ãŒãã¡ã¯ããªã§ãå¿ èŠãªããŒã«ïŒäŸïŒ'admin'ã'editor'ïŒãåŒæ°ãšããŠåããŸãã
- `decorator(f)`ïŒããã¯å®éã®ãã³ã¬ãŒã¿ãŒã§ããã¥ãŒé¢æ°`f`ãåŒæ°ãšããŠåããŸãã
- `@functools.wraps(f)`ïŒå ã®é¢æ°ã®ã¡ã¿ããŒã¿ãä¿æããŸãã
- `wrapper(*args, **kwargs)`å ïŒ
- ãŠãŒã¶ãŒãªããžã§ã¯ããååŸããŸãïŒ`token_required`ãã³ã¬ãŒã¿ãŒãŸãã¯åæ§ã®èªèšŒã¡ã«ããºã ã«ãã£ãŠèšå®ãããŠãããšæ³å®ïŒãããã¯ãããŒã¯ã³ããæœåºããããŠãŒã¶ãŒæ å ±ã«åºã¥ããŠããŒã¿ããŒã¹ããããŒãããããšãã§ããŸãã
- ãŠãŒã¶ãŒãååšãããã®ããŒã«ãèŠæ±ãããããŒã«ãšäžèŽãããã©ããã確èªããŸãã
- ãŠãŒã¶ãŒãåºæºãæºãããŠããªãå Žåã¯ã403 Forbiddenãšã©ãŒãè¿ããŸãã
- ãŠãŒã¶ãŒãæ¿èªãããŠããå Žåã¯ãå ã®ãã¥ãŒé¢æ°`f`ãå®è¡ããŸãã
äœ¿ãæ¹ïŒ
from flask import Flask, jsonify
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
# Assume the token_required decorator sets request.user (as described above)
@app.route('/admin')
@token_required # Apply authentication first
@role_required('admin') # Then, apply authorization
def admin_route():
return jsonify({"message": "Welcome, admin!"}), 200
ãã®äŸã§ã¯ã`/admin`ã«ãŒãã¯`token_required`ïŒèªèšŒïŒããã³`role_required('admin')`ïŒèªå¯ïŒãã³ã¬ãŒã¿ãŒã«ãã£ãŠä¿è·ãããŠããŸãã'admin'ããŒã«ãæã€èªèšŒæžã¿ã®ãŠãŒã¶ãŒã®ã¿ãããã®ã«ãŒãã«ã¢ã¯ã»ã¹ã§ããŸãã
é«åºŠãªãã¯ããã¯ãšèæ ®äºé
1. ãã³ã¬ãŒã¿ãŒãã§ãŒã³
äžèšã§ç€ºããããã«ããã³ã¬ãŒã¿ãŒããã§ãŒã³ããŠãè€æ°ã®ã¬ãã«ã®ä¿è·ãé©çšã§ããŸããéåžžãèªèšŒã¯ãã§ãŒã³å ã§èªå¯ã®åã«å®è¡ãããå¿ èŠããããŸããããã«ããããŠãŒã¶ãŒã®èªå¯ã¬ãã«ããã§ãã¯ãããåã«ããŠãŒã¶ãŒãèªèšŒãããããšãä¿èšŒãããŸãã
2. ããŸããŸãªèªèšŒæ¹æ³ã®åŠç
ã¢ããªã±ãŒã·ã§ã³ã®èŠä»¶ã«åºã¥ããŠãOAuth 2.0ãåºæ¬èªèšŒãªã©ã®ããŸããŸãªèªèšŒæ¹æ³ããµããŒãããããã«èªèšŒãã³ã¬ãŒã¿ãŒã調æŽããŸãã䜿çšããèªèšŒæ¹æ³ã決å®ããããã«ãæ§æå¯èœãªã¢ãããŒãã®äœ¿çšãæ€èšããŠãã ããã
3. ã³ã³ããã¹ããšããŒã¿ã®åãæž¡ã
ãã³ã¬ãŒã¿ãŒã¯ãããŒã¿ããã¥ãŒé¢æ°ã«æž¡ãããšãã§ããŸããããšãã°ãèªèšŒãã³ã¬ãŒã¿ãŒã¯JWTããã³ãŒããããŠãŒã¶ãŒãªããžã§ã¯ãããã¥ãŒé¢æ°ã«æž¡ãããšãã§ããŸããããã«ããããã¥ãŒé¢æ°å ã§èªèšŒãŸãã¯ããŒã¿ååŸã³ãŒããç¹°ãè¿ãå¿ èŠããªããªããŸãããã³ã¬ãŒã¿ãŒãããŒã¿ã®åãæž¡ããé©åã«åŠçããŠãäºæããªãåäœãçºçããªãããã«ããŠãã ããã
4. ãšã©ãŒåŠçãšã¬ããŒã
ãã³ã¬ãŒã¿ãŒã«å æ¬çãªãšã©ãŒåŠçãå®è£ ããŸãããšã©ãŒããã°ã«èšé²ããæçãªãšã©ãŒå¿çãè¿ããåé¡ã®ç£èŠãšè¿œè·¡ã«åœ¹ç«ã€å°çšã®ãšã©ãŒã¬ããŒãã¡ã«ããºã ïŒSentryãªã©ïŒã®äœ¿çšãæ€èšããŠãã ãããæ©å¯æ å ±ãå ¬éããã«ããšã³ããŠãŒã¶ãŒã«åœ¹ç«ã€ã¡ãã»ãŒãžïŒç¡å¹ãªããŒã¯ã³ãæš©éã®äžè¶³ãªã©ïŒãæäŸããŸãã
5. ã¬ãŒãå¶é
ã¬ãŒãå¶éãçµ±åããŠãAPIãæªçšããµãŒãã¹æåŠïŒDoSïŒæ»æããä¿è·ããŸããç¹å®ã®IPã¢ãã¬ã¹ãŸãã¯ãŠãŒã¶ãŒããã®ç¹å®ã®æéæ å ã®ãªã¯ãšã¹ãæ°ã远跡ãããªã¯ãšã¹ãæ°ãå¶éãããã³ã¬ãŒã¿ãŒãäœæããŸããããŒã¿ããŒã¹ããã£ãã·ã¥ïŒRedisãªã©ïŒããŸãã¯ãã®ä»ã®ä¿¡é Œã§ãããœãªã¥ãŒã·ã§ã³ã®äœ¿çšãå®è£ ããŸãã
import functools
from flask import request, jsonify, current_app
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
# Initialize Limiter (ensure this is done during app setup)
limiter = Limiter(
app=current_app._get_current_object(),
key_func=get_remote_address,
default_limits=["200 per day", "50 per hour"]
)
def rate_limit(limit):
def decorator(f):
@functools.wraps(f)
@limiter.limit(limit)
def wrapper(*args, **kwargs):
return f(*args, **kwargs)
return wrapper
return decorator
# Example usage
@app.route('/api/resource')
@rate_limit("10 per minute")
def api_resource():
return jsonify({"message": "API resource"})
6. å ¥åæ€èšŒ
ãã³ã¬ãŒã¿ãŒå ã§ãŠãŒã¶ãŒå ¥åãæ€èšŒããŠãã¯ãã¹ãµã€ãã¹ã¯ãªããã£ã³ã°ïŒXSSïŒãSQLã€ã³ãžã§ã¯ã·ã§ã³ãªã©ã®äžè¬çãªè匱æ§ãé²ããŸããMarshmallowãPydanticãªã©ã®ã©ã€ãã©ãªã䜿çšããŠããŒã¿ã¹ããŒããå®çŸ©ããåä¿¡ãªã¯ãšã¹ãããŒã¿ãèªåçã«æ€èšŒããŸããããŒã¿åŠçã®åã«å æ¬çãªãã§ãã¯ãå®è£ ããŸãã
from functools import wraps
from flask import request, jsonify
from marshmallow import Schema, fields, ValidationError
# Define a schema for input validation
class UserSchema(Schema):
email = fields.Email(required=True)
password = fields.Str(required=True, min_length=8)
def validate_input(schema):
def decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
try:
data = schema.load(request.get_json())
except ValidationError as err:
return jsonify(err.messages), 400
request.validated_data = data # Store validated data in the request object
return f(*args, **kwargs)
return wrapper
return decorator
# Example Usage
@app.route('/register', methods=['POST'])
@validate_input(UserSchema())
def register_user():
# Access validated data from the request
email = request.validated_data['email']
password = request.validated_data['password']
# ... process registration ...
return jsonify({"message": "User registered successfully"})
7. ããŒã¿ã®ãµãã¿ã€ãº
ãã³ã¬ãŒã¿ãŒå ã§ããŒã¿ããµãã¿ã€ãºããŠãXSSããã®ä»ã®æœåšçãªã»ãã¥ãªãã£è匱æ§ãé²ããŸããHTMLæåããšã³ã³ãŒãããæªæã®ããã³ã³ãã³ãããã£ã«ã¿ãªã³ã°ããç¹å®ã®ããŒã¿ã®çš®é¡ãšãããããããããå¯èœæ§ã®ããè匱æ§ã«åºã¥ããŠãä»ã®ãã¯ããã¯ãæ¡çšããŸãã
ã«ãŒãä¿è·ã®ãã¹ããã©ã¯ãã£ã¹
- 匷åãªã·ãŒã¯ã¬ããããŒã䜿çšããïŒFlaskã¢ããªã±ãŒã·ã§ã³ã®`SECRET_KEY`ã¯ã»ãã¥ãªãã£ã«ãšã£ãŠéåžžã«éèŠã§ãã匷åãªã©ã³ãã ããŒãçæããå®å šã«ä¿ç®¡ããŸãïŒç°å¢å€æ°ãã³ãŒããªããžããªå€ã®æ§æãã¡ã€ã«ãªã©ïŒãã·ãŒã¯ã¬ããããŒãã³ãŒãã«çŽæ¥ããŒãã³ãŒãã£ã³ã°ããªãã§ãã ããã
- æ©å¯ããŒã¿ã®å®å šãªã¹ãã¬ãŒãžïŒåŒ·åãªããã·ã¥ã¢ã«ãŽãªãºã ãšå®å šãªã¹ãã¬ãŒãžã¡ã«ããºã ã䜿çšããŠããã¹ã¯ãŒããAPIããŒãªã©ã®æ©å¯ããŒã¿ãä¿è·ããŸãããã¹ã¯ãŒãããã¬ãŒã³ããã¹ãã§ä¿åããªãã§ãã ããã
- 宿çãªã»ãã¥ãªãã£ç£æ»ïŒå®æçãªã»ãã¥ãªãã£ç£æ»ãšäŸµå ¥ãã¹ãã宿œããŠãã¢ããªã±ãŒã·ã§ã³ã®æœåšçãªè匱æ§ãç¹å®ããŠå¯ŸåŠããŸãã
- äŸåé¢ä¿ãææ°ã®ç¶æ ã«ä¿ã€ïŒFlaskãã¬ãŒã ã¯ãŒã¯ãã©ã€ãã©ãªãããã³äŸåé¢ä¿ã宿çã«æŽæ°ããŠãã»ãã¥ãªãã£ããããšãã°ä¿®æ£ã«å¯ŸåŠããŸãã
- HTTPSã®å®è£ ïŒåžžã«HTTPSã䜿çšããŠãã¯ã©ã€ã¢ã³ããšãµãŒããŒéã®éä¿¡ãæå·åããŸããããã«ãããçèŽãé²ãã転éäžã®ããŒã¿ãä¿è·ããŸããTLS / SSLèšŒææžãæ§æããHTTPãã©ãã£ãã¯ãHTTPSã«ãªãã€ã¬ã¯ãããŸãã
- æå°ç¹æš©ã®ååã«åŸãïŒãŠãŒã¶ãŒã«ã¿ã¹ã¯ãå®è¡ããããã«å¿ èŠãªæå°éã®æš©éã®ã¿ãä»äžããŸãããªãœãŒã¹ãžã®éå°ãªã¢ã¯ã»ã¹ãèš±å¯ããªãã§ãã ããã
- ç£èŠãšãã°ïŒå æ¬çãªãã®ã³ã°ãšç£èŠãå®è£ ããŠããŠãŒã¶ãŒã¢ã¯ãã£ããã£ã远跡ããçãããåäœãæ€åºããåé¡ããã©ãã«ã·ã¥ãŒãã£ã³ã°ããŸããæœåšçãªã»ãã¥ãªãã£ã€ã³ã·ãã³ãããªããããã°ã宿çã«ç¢ºèªããŸãã
- Webã¢ããªã±ãŒã·ã§ã³ãã¡ã€ã¢ãŠã©ãŒã«ïŒWAFïŒã®æ€èšïŒWAFã¯ãäžè¬çãªWebæ»æïŒSQLã€ã³ãžã§ã¯ã·ã§ã³ãã¯ãã¹ãµã€ãã¹ã¯ãªããã£ã³ã°ãªã©ïŒããã¢ããªã±ãŒã·ã§ã³ãä¿è·ããã®ã«åœ¹ç«ã¡ãŸãã
- ã³ãŒãã¬ãã¥ãŒïŒå®æçãªã³ãŒãã¬ãã¥ãŒãå®è£ ããŠãæœåšçãªã»ãã¥ãªãã£è匱æ§ãç¹å®ããã³ãŒãå質ã確ä¿ããŸãã
- è匱æ§ã¹ãã£ããŒã®äœ¿çšïŒè匱æ§ã¹ãã£ããŒãéçºããã³å±éãã€ãã©ã€ã³ã«çµ±åããŠãã³ãŒãã®æœåšçãªã»ãã¥ãªãã£äžã®æ¬ é¥ãèªåçã«ç¹å®ããŸãã
å®å šãªã¢ããªã±ãŒã·ã§ã³ã«é¢ããã°ããŒãã«ãªèæ ®äºé
ã°ããŒãã«ãªãªãŒãã£ãšã³ã¹åãã®ã¢ããªã±ãŒã·ã§ã³ãéçºããå Žåã¯ãã»ãã¥ãªãã£ãšã³ã³ãã©ã€ã¢ã³ã¹ã«é¢é£ããããŸããŸãªèŠçŽ ãèæ ®ããããšãéèŠã§ãã
- ããŒã¿ãã©ã€ãã·ãŒèŠå¶ïŒãšãŒãããã®äžè¬ããŒã¿ä¿è·èŠåïŒGDPRïŒãç±³åœã®ã«ãªãã©ã«ãã¢å·æ¶è²»è ãã©ã€ãã·ãŒæ³ïŒCCPAïŒãªã©ãããŸããŸãªå°åã®é¢é£ããããŒã¿ãã©ã€ãã·ãŒèŠå¶ãèªèããéµå®ããŸããããã«ã¯ããŠãŒã¶ãŒããŒã¿ãä¿è·ããããã®é©åãªã»ãã¥ãªãã£å¯Ÿçã®å®æœãåæã®ååŸããŠãŒã¶ãŒã«èªåã®ããŒã¿ã«ã¢ã¯ã»ã¹ã倿Žãåé€ããæš©å©ã®æäŸãå«ãŸããŸãã
- ããŒã«ãªãŒãŒã·ã§ã³ãšåœéåïŒã¢ããªã±ãŒã·ã§ã³ã®ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ãšãšã©ãŒã¡ãã»ãŒãžãè€æ°ã®èšèªã«ç¿»èš³ããå¿ èŠæ§ãæ€èšããŸããèªèšŒãèªå¯ãªã©ã®ã»ãã¥ãªãã£å¯ŸçããããŒã«ã©ã€ãºãããã€ã³ã¿ãŒãã§ãŒã¹ãšé©åã«çµ±åãããŠããããšã確èªããŸãã
- ã³ã³ãã©ã€ã¢ã³ã¹ïŒã¢ããªã±ãŒã·ã§ã³ããã¿ãŒã²ããã«ããŠããç¹å®ã®æ¥çãŸãã¯å°åã®ã³ã³ãã©ã€ã¢ã³ã¹èŠä»¶ãæºãããŠããããšã確èªããŸããããšãã°ãéèååŒãåŠçããå Žåã¯ãPCI DSSæšæºã«æºæ ããå¿ èŠãããå ŽåããããŸãã
- ã¿ã€ã ãŸãŒã³ãšæ¥ä»åœ¢åŒïŒã¿ã€ã ãŸãŒã³ãšæ¥ä»åœ¢åŒãæ£ããåŠçããŸããççŸã¯ãã¹ã±ãžã¥ãŒã«èšå®ãããŒã¿åæãããã³èŠå¶ã®éµå®ã«ãããŠãšã©ãŒã«ã€ãªããå¯èœæ§ããããŸããã¿ã€ã ã¹ã¿ã³ããUTC圢åŒã§ä¿åãã衚瀺ã®ããã«ãŠãŒã¶ãŒã®ããŒã«ã«ã¿ã€ã ãŸãŒã³ã«å€æããããšãæ€èšããŠãã ããã
- æåçæåæ§ïŒã¢ããªã±ãŒã·ã§ã³ã§äžå¿«ãŸãã¯æåçã«äžé©åãªèšèªãŸãã¯ç»åã䜿çšããããšãé¿ããŠãã ãããã»ãã¥ãªãã£æ £è¡ã«é¢é£ããæåçãªéãã«æ³šæããŠãã ãããããšãã°ãããåœã§äžè¬çãªåŒ·åãªãã¹ã¯ãŒãããªã·ãŒã¯ãå¥ã®åœã§ã¯å¶éãå³ãããããšèŠãªãããå¯èœæ§ããããŸãã
- æ³çèŠä»¶ïŒéçšããããŸããŸãªåœã®æ³çèŠä»¶ãéµå®ããŸããããã«ã¯ãããŒã¿ã¹ãã¬ãŒãžãåæãããã³ãŠãŒã¶ãŒããŒã¿ã®åŠçãå«ãŸããå ŽåããããŸãã
- æ¯æãåŠçïŒã¢ããªã±ãŒã·ã§ã³ãæ¯æããåŠçããå Žåã¯ãçŸå°ã®æ¯æãåŠçèŠå¶ãéµå®ããããŸããŸãªé貚ããµããŒãããå®å šãªæ¯æãã²ãŒããŠã§ã€ã䜿çšããŠããããšã確èªããŸããããŸããŸãªåœãæåã倿§ãªæ¯æãæ¹æ³ã䜿çšããŠãããããçŸå°ã®æ¯æããªãã·ã§ã³ãæ€èšããŠãã ããã
- ããŒã¿ã¬ãžãã³ã·ãŒïŒäžéšã®åœã§ã¯ãç¹å®ã®çš®é¡ã®ããŒã¿ãåœå ã«ä¿åããããšã矩åä»ããèŠå¶ãããå ŽåããããŸããç¹å®ã®å°åã§ããŒã¿ã»ã³ã¿ãŒãæäŸãããã¹ãã£ã³ã°ãããã€ããŒãéžæããå¿ èŠãããå ŽåããããŸãã
- ã¢ã¯ã»ã·ããªãã£ïŒWCAGã¬ã€ãã©ã€ã³ã«åŸã£ãŠãé害ã®ãããŠãŒã¶ãŒãã¢ããªã±ãŒã·ã§ã³ã«ã¢ã¯ã»ã¹ã§ããããã«ããŸããã¢ã¯ã»ã·ããªãã£ã¯ã°ããŒãã«ãªåé¡ã§ããã身äœçãŸãã¯èªç¥èœåã«é¢ä¿ãªãããŠãŒã¶ãŒã«å¹³çãªã¢ã¯ã»ã¹ãæäŸããããã®åºæ¬çãªèŠä»¶ã§ãã
çµè«
ã«ã¹ã¿ã ãã³ã¬ãŒã¿ãŒã¯ãFlaskã¢ããªã±ãŒã·ã§ã³ã§ã«ãŒãä¿è·ãå®è£ ããããã®åŒ·åãã€ãšã¬ã¬ã³ããªã¢ãããŒããæäŸããŸããèªèšŒããã³èªå¯ãã³ã¬ãŒã¿ãŒã䜿çšããããšã«ãããå®å šã§å ç¢ãªAPIãšWebã€ã³ã¿ãŒãã§ã€ã¹ãæ§ç¯ã§ããŸãããã¹ããã©ã¯ãã£ã¹ã«åŸããå æ¬çãªãšã©ãŒåŠçãå®è£ ããã°ããŒãã«ãªãªãŒãã£ãšã³ã¹åãã®ã¢ããªã±ãŒã·ã§ã³ãéçºããéã«ã¯ãã°ããŒãã«ãªèŠçŽ ãèæ ®ããããšãå¿ããªãã§ãã ãããã»ãã¥ãªãã£ãåªå ããæ¥çæšæºãéµå®ããããšã§ãäžçäžã®ãŠãŒã¶ãŒããä¿¡é Œãããã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸãã
æäŸãããŠããäŸã¯ãäžå¯æ¬ ãªæŠå¿µã瀺ããŠããŸããå®éã®å®è£ ã¯ãç¹ã«æ¬çªç°å¢ã§ã¯ããè€éã«ãªãå¯èœæ§ããããŸããå€éšãµãŒãã¹ãããŒã¿ããŒã¹ãããã³é«åºŠãªã»ãã¥ãªãã£æ©èœãšã®çµ±åãæ€èšããŠãã ãããç¶ç¶çãªåŠç¿ãšé©å¿ã¯ãé²åããWebã»ãã¥ãªãã£ã®ç¶æ³ã«ãããŠäžå¯æ¬ ã§ãã宿çãªãã¹ããã»ãã¥ãªãã£ç£æ»ãããã³ææ°ã®ã»ãã¥ãªãã£ã®ãã¹ããã©ã¯ãã£ã¹ã®éµå®ã¯ãå®å šãªã¢ããªã±ãŒã·ã§ã³ãç¶æããããã«äžå¯æ¬ ã§ãã