1つ、csrf検証
2.グラフィック検証コード
詳細については、以下を参照してください。フラスコプロジェクト1の実際の戦闘:2.2フラスコフレームワークの下で画像検証コードを使用する
3.SMS確認コード
詳細については、[フラスコプロジェクト1の実際の戦闘:2.3フラスコフレームワークでの画像検証コードの使用]を参照してください。
4、ユーザー登録
1.ユーザー登録ビジネスロジック分析
2.ユーザー登録インターフェースを設計する基本的な考え方
- インターフェイスの設計では、特定のビジネスロジックに従ってビジネスロジックに適したインターフェイスを設計する必要があります。
- インターフェイスを設計するためのアイデア:
2.1実装するビジネスロジックを分析します。
- いくつかの関連するサブビジネスがこのビジネスに関与していることは明らかです。
- 各サブビジネスをインターフェースとして設計します。
2.2インターフェースの機能タスクを分析し、インターフェースのアクセス方法と戻りデータを明確にします。
- リクエストメソッド(GET、POST、PUT、DELETEなど)。
- リクエストアドレス。
- リクエストパラメータ(パスパラメータ、クエリ文字列、フォーム、JSONなど)。
- 応答データ(HTML、JSONなど)。
3.ユーザー登録インターフェースの設計(整理予定)
3.1リクエスト方法
オプション | プログラム |
---|---|
リクエスト方法 | 役職 |
リクエストアドレス | / users |
3.2リクエストパラメータ:フォームパラメータ
パラメータ名 | の種類 | 合格する必要があります | 説明 |
---|---|---|---|
パスワード | ストリング | はい | パスワード |
password2 | ストリング | はい | パスワードを認証する |
モバイル | ストリング | はい | 電話番号 |
sms_code | ストリング | はい | SMS確認コード |
3.3応答結果
回答結果 | 回答内容 |
---|---|
登録に失敗しました | エラープロンプトに応答する |
登録完了 | ホームページにリダイレクトする |
4.ユーザー登録インターフェースの定義
- 受信パラメータ
- 検証パラメータ
- 必要なパラメーターが空かどうか
- 携帯電話番号が規制に準拠しているかどうか:r '1 [345678] \ d {9}'は、悪意のある登録を防止します
- 2つのパスワードが同じかどうか
- ビジネスロジックの検証
- SMS検証コードの正しさを確認します。グラフィック検証コードは検証されなくなります(テキスト検証コードは、グラフィック検証コードが正しい場合にのみ使用可能になります)
- 検証のためにredisからSMS検証コードを取得する
- SMS確認コードの有効期限が切れているかどうかを確認します
- SMS検証コードをredisから削除する:正しいか間違っているかに関係なく、ライブラリの衝突を防ぐために1回だけ使用できます
- ユーザーが入力したSMS検証が正しいかどうかを確認します
- 携帯電話番号が登録されているか確認してください。SMS確認コード送信時に確認済みであり、確認する必要はありません(フィールドが一意でない場合は確認することをお勧めします。今回はセグメントが一意。データを追加するときに、それを繰り返すとエラーが報告されるため、検証は不要で、データの保存時に例外がキャッチされます)
- 携帯電話番号が存在するかどうかを問い合わせ、記録がある場合は登録済みであることを意味し、プロンプトが表示されます。それ以外の場合は登録できます
- データベースのクエリでエラーが発生した場合、例外が直接返されます
- パスワードの暗号化:
- パスワードの平文を暗号化する:パスワード暗号化アルゴリズムを呼び出す
- SMS検証コードの正しさを確認します。グラフィック検証コードは検証されなくなります(テキスト検証コードは、グラフィック検証コードが正しい場合にのみ使用可能になります)
- データベースに登録情報を書き込む
- データモデルを介してデータを保存し、例外後のデータ送信とデータロールバックに注意を払います
- ログインステータスをセッションに保存します
- 結果を返す
@api.route("/users",methods=["POST"])
def register():
"""
注册
:param: 手机号 短信验证码 密码 确认密码
:return: json
"""
# 接收参数
request_dict = request.get_json()
mobile = request_dict.get("mobile")
sms_code = request_dict.get("sms_code")
password = request_dict.get("password")
password2 = request_dict.get("password2")
# 验证
if not all([mobile, sms_code, password, password2]):
return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')
# 判断手机号格式
if not re.match(r'1[345678]\d{9}', mobile):
return jsonify(errno=RET.PARAMERR, errmsg='手机号格式错误')
# 判断两次密码是否一致
if password != password2:
return jsonify(errno=RET.PARAMERR, errmsg='两次密码不一致')
# 业务逻辑
# 从redis取短信验证码
try:
real_sms_code = redis_store.get("sms_code_%s" % mobile)
except Exception as e:
logging.error(e)
return jsonify(errno=RET.DBERR, errmsg='读取短信验证码异常')
# 判断短信验证码是否过期
if real_sms_code is None:
return jsonify(errno=RET.NODATA, errmsg='短信验证码失效')
# 删除redis中的短信验证码
try:
redis_store.delete("sms_code_%s" % mobile)
except Exception as e:
logging.error(e)
# 判断用户填写的验证码的正确性
real_sms_code=real_sms_code.decode()
if sms_code.lower()!=real_sms_code:
return jsonify(errno=RET.DATAERR, errmsg='短信验证码错误')
# 判断手机号是否存在
try:
user = User.query.filter_by(mobile=mobile).first()
except Exception as e:
logging.error(e)
else:
if user is not None:
# 表示手机号已经被注册过
return jsonify(errno=RET.DATAEXIST, errmsg='手机号已经存在')
# 保存数据(同时检测手机是否被注册过)
user = User(name=mobile, mobile=mobile)
user.passwd_hash(password)
try:
db.session.add(user)
db.session.commit()
except IntegrityError as e:
db.session.rollback()
logging.error(e)
return jsonify(errno=RET.DATAEXIST, errmsg='手机号已经存在')
except Exception as e:
# 回滚
db.session.rollback()
logging.error(e)
return jsonify(errno=RET.DBERR, errmsg='插入数据库异常')
# 保存登录状态到session中
session["name"] = mobile
session["mobile"] = mobile
session["user_id"] = user.id
return jsonify(errno=RET.OK, errmsg='注册成功')
5、ユーザー登録の最適化
- 生産者/消費者開発モデルを使用して、SMS待機の送信を最適化します