You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Flask的人脸识别二次登录:识别通过后如何跳转页面?

解决方案:人脸识别认证后停止流并跳转页面

问题核心在于Flask的流式Response是单向推送,后端无法主动通知前端跳转,必须通过前端轮询状态+后端标记认证结果的配合来实现。以下是具体改造步骤:


1. 后端改造:生成器终止时标记认证状态

修改人脸识别生成器函数,添加匹配计数逻辑,达到指定次数后标记Session状态并终止生成器,同时释放摄像头资源:

def facerec(self, capture, model, encodings, username):
    match_count = 0
    required_matches = 3  # 设定需要匹配的次数
    while True:
        ret, frame = capture.read()
        if not ret:
            break
        
        # 此处替换为你的人脸识别匹配逻辑,返回True/False表示是否匹配
        match_result = self._compare_face_encodings(frame, encodings, model)
        
        if match_result:
            match_count += 1
            if match_count >= required_matches:
                # 标记认证通过
                from flask import session
                session['auth_passed'] = True
                # 释放摄像头资源
                capture.release()
                cv2.destroyAllWindows()
                break  # 终止生成器
        
        # 编码并返回帧(保留原逻辑)
        start_time = time.time()
        ret, buffer = cv2.imencode('.jpg', frame)
        end = time.time()
        print(end-start_time,'---encoding image TIME')
        
        start_time = time.time()
        yield(b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + bytearray(buffer) + b'\r\n')
        cv2.waitKey(25)
        end = time.time()
        print(end-start_time,'---yield image TIME')

2. 简化流式路由逻辑

原路由中的while r: return r完全多余,Response会自动迭代生成器,直接返回即可:

@app.route('/clean_feed', methods = ['GET'])
def clean_feed():
    face_rec = Face_rec(0)
    capture = cv2.VideoCapture(0)
    model = "large"
    cursor = mysql.connection.cursor()
    cursor.execute('SELECT face_encodings FROM account WHERE username = %s',(session['username'],))
    account = cursor.fetchone()               
    if account:
        encodings = convert_encodings_to_intlist(account)
        username = [session['username']]
        # 初始化认证状态
        session['auth_passed'] = False
        # 直接返回流式Response
        return Response(face_rec.facerec(capture, model, encodings, username), 
                        mimetype='multipart/x-mixed-replace; boundary=frame')   
            
    return render_template('login.html')

3. 添加认证状态检查接口

供前端轮询查询是否完成认证:

@app.route('/check_auth_status')
def check_auth_status():
    return {'passed': session.get('auth_passed', False)}

4. 前端页面:监听状态并跳转

在显示视频流的页面(如verify.html)中,通过JS定时轮询状态,检测到认证通过后跳转至目标页面:

<!DOCTYPE html>
<html>
<head>
    <title>人脸二次验证</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
    <img id="video-feed" src="{{ url_for('clean_feed') }}">
    <script>
        // 每500ms检查一次认证状态
        const checkTimer = setInterval(() => {
            $.get('/check_auth_status', function(res) {
                if (res.passed) {
                    clearInterval(checkTimer);
                    // 跳转至认证后的目标页面
                    window.location.href = '/dashboard';
                }
            });
        }, 500);

        // 额外监听视频流加载失败(生成器终止后可能触发)
        document.getElementById('video-feed').addEventListener('error', function() {
            $.get('/check_auth_status', function(res) {
                if (res.passed) {
                    window.location.href = '/dashboard';
                }
            });
        });
    </script>
</body>
</html>

关键注意点

  • 确保Flask已开启Session(需设置SECRET_KEY)
  • 匹配计数可添加时间窗口限制(如10秒内完成3次匹配),避免误判
  • 生成器终止时必须释放摄像头,防止设备占用

内容的提问来源于stack exchange,提问作者Mikołaj Ładny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 04:55:37