Flaskプロジェクト1の実際の戦闘:3。ユーザーログイン(改善予定)

ここに画像の説明を挿入

(先生の生放送の内容によると)

1つは、ユーザーログイン

1.ユーザー名ログインの論理分析

ここに画像の説明を挿入

2.ユーザー名ログインインターフェイスの設計

2.1リクエスト方法

オプション プログラム
リクエスト方法 役職
リクエストアドレス / sessions

2.2リクエストパラメータ:フォーム

パラメータ名 の種類 合格する必要があります 説明
モバイル ストリング はい 電話番号
パスワード ストリング はい パスワード

2.3応答結果:HTML

フィールド 説明
ログインに失敗しました エラープロンプトに応答する
ログイン成功 ホームページにリダイレクトする

3.ユーザー名ログインインターフェイスの定義

  • 受信パラメータ
  • 検証パラメータ
    • パラメータが使用可能かどうかを確認します
    • 電話番号の形式は正しいですか?
  • ビジネスロジック処理を判断する
    • データベースから携帯電話番号が存在するか確認してください
    • パスワードを照合します
  • 状態を保存
  • 戻る
# lghome/api_1_0/passport.py
@api.route("/sessions", methods=["POST"])
def login():
    """
    用户登录
    :param: 手机号,密码
    :return: json
    """
    # 接收参数
    request_dict = request.get_json()
    mobile = request_dict.get('mobile')
    password = request_dict.get('password')

    print(mobile,password)
    # 校验参数
    if not all([mobile, password]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')

    # 判断手机号格式
    if not re.match(r'1[345678]\d{9}', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg='手机号格式错误')

    # 判断业务逻辑处理
    # 从数据库查询手机号是否存在
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.DBERR, errmsg='获取信息失败')

	# 验证密码
    if user is None or not user.check_pwd_hash(password):
        return jsonify(errno=RET.DATAERR, errmsg='帐号密码不匹配')

    # 保存登录状态
    session['name'] = user.name
    session['mobile'] = user.mobile
    session['user_id'] = user.id

    # 返回
    return jsonify(errno=RET.OK, errmsg='登录成功')

4.アルゴリズムの最適化

4.1エラーの数を制限する

  • エラーの数が制限されていない場合、アカウントのパスワードは悪意を持ってテストされます
  • 一定期間内のエラー数を制限し、制限を超えた後はログインできません
    • パラメータを受け取った後、最初にフロントエンドIPが制限を超えているかどうかを判断します
      • IPが誤ってアクセスされた回数をredisから取得します
      • エラーの数が空ではなく、制限以上の場合、エラーは直接返されます
    • 携帯電話番号が存在するか(登録ユーザーか)、パスワードが間違っているかどうかを確認し、
      • エラーが発生した場合、エラーの数は1増加し、redisに保存されます。
    # 判断业务逻辑处理
    # 判断错误次数是否超过限制,如果超过限制直接返回
    # redis 用户IP地址:次数
    user_ip = request.remote_addr
    print(user_ip)
    try:
        access_nums=redis_store.get("access_nums_%s"%user_ip)
        print("access_nums_%s"%user_ip,access_nums)
    except Exception as e:
        logging.error(e)
    else:
        if  access_nums is not None and int(access_nums)>=constants.LOGIN_ERROR_MAX_TIMES:
            return jsonify(errno=RET.REQERR, errmsg='错误次数太多,请稍后重试')

    # 验证密码
    # if user is None or not user.check_pwd_hash(password):
    #     return jsonify(errno=RET.DATAERR, errmsg='帐号密码不匹配')
    if user is None or not user.check_pwd_hash(password):
        try:
            redis_store.incr("access_nums_%s" % user_ip)
            redis_store.repire("access_nums_%s"%user_ip,constants.LOGIN_ERROR_FORBID_TIME)
        except Exception as e:
            logging.error(e)
        return jsonify(errno=RET.DATAERR, errmsg='帐号密码不匹配')

4.2エラー時間を節約するときにパイプラインを使用する

    # 验证密码
    # if user is None or not user.check_pwd_hash(password):
    #     return jsonify(errno=RET.DATAERR, errmsg='帐号密码不匹配')
    if user is None or not user.check_pwd_hash(password):
        try:
            # redis管道
            pl = redis_store.pipeline()
            pl.incr("access_nums_%s" % user_ip)
            pl.repire("access_nums_%s"%user_ip,constants.LOGIN_ERROR_FORBID_TIME)
            pl.execute()
        except Exception as e:
            logging.error(e)
        return jsonify(errno=RET.DATAERR, errmsg='帐号密码不匹配')

2、ログインを確認してください

  • ユーザーがログインした後、ページが更新されたときに、ログインステータスを判断する必要があります
  • 一部のページはログイン状態でしか使用できず、ログイン状態を判断する必要があります

1.インターフェースデザイン

1.1リクエスト方法

オプション プログラム
リクエスト方法 取得する
リクエストアドレス / sessions

1.2リクエストパラメータ:なし

1.3応答結果:json

ファーストネーム の種類 あなたはする必要がありますか 説明
errno ストリング はい エラーコード
errmsg ストリング はい エラー内容
データ 辞書 番号 _「名前」:ログイン名}

2.ログインチェックインターフェイスの定義

  • セッションユーザー情報を読む
  • 存在する場合は、ユーザーがログインしていることを意味します。存在しない場合は、ログインしていません。
  • 対応する結果を返す
def check_login():
    """
    检查登录状态
    :return: 用户的信息或者返回错误信息
    """
    name = session.get('name')
    if name is not None:
        return jsonify(errno=RET.OK, errmsg='true', data={
    
    "name": name})
    else:
        return jsonify(errno=RET.SESSIONERR, errmsg='false')

3、ログアウトします

1.インターフェースデザイン

1.1リクエスト方法

オプション プログラム
リクエスト方法 削除
リクエストアドレス / sessions

1.2リクエストパラメータ:なし

1.3応答結果:HTML

フィールド 説明
正常にサインアウトする ホームページにリダイレクトする

2.ログインチェックインターフェイスの定義

  • セッション情報をクリアする
  • 対応する結果を返す
def logout():
    """退出登录"""
    # 清空session
    session.clear()
    return jsonify(errno=RET.OK, errmsg='OK')

おすすめ

転載: blog.csdn.net/laoluobo76/article/details/110558201