目录
- 前言
- 一、金融行业特殊要求
- 二、金融认证前端架构
- 三、前端身份认证流程
- 四、金融身份认证的完整业务生命周期
-
- 1、用户初始身份建立(KYC)
- [2、登录认证(Login Authentication)](#2、登录认证(Login Authentication))
- [3、会话与持续认证(Session / Token)](#3、会话与持续认证(Session / Token))
- [4、高风险操作的二次认证(Step-Up Auth)](#4、高风险操作的二次认证(Step-Up Auth))
- 5、设备与环境认证(金融必备)
- 6、行为认证(隐形认证)
- 五、前端核心技术实现
-
- [1、HTTPS + 前端加密(双重保护)](#1、HTTPS + 前端加密(双重保护))
-
- [(1)、「HTTPS + 前端加密」概念](#(1)、「HTTPS + 前端加密」概念)
- [(2)、为什么 HTTPS 在金融系统里"不够用"?](#(2)、为什么 HTTPS 在金融系统里“不够用”?)
- (3)、前端加密在金融系统中的真实定位
- [(4)、HTTPS + 前端加密的分层模型(核心)](#(4)、HTTPS + 前端加密的分层模型(核心))
- (5)、金融系统里"前端加密"一般加密什么?
- (6)、金融系统中常见的前端加密方案
- [(7)、企业级实践:HTTPS + 前端加密(完整示例)](#(7)、企业级实践:HTTPS + 前端加密(完整示例))
-
- ①、服务端:下发公钥(示意)
- ②、前端:加密工具封装(企业级)
- [③、登录请求(HTTPS + 加密)](#③、登录请求(HTTPS + 加密))
- ④、登录流程中的关键控制点(金融级)
- (8)、这套方案解决了哪些金融风险?
- (9)、金融系统中必须补充的"防重放设计"
- [2、KYC 采集](#2、KYC 采集)
-
- [(1)、KYC 采集概念](#(1)、KYC 采集概念)
- [(2)、KYC 采集 ≠ 表单填写(这是第一个认知分水岭)](#(2)、KYC 采集 ≠ 表单填写(这是第一个认知分水岭))
- [(3)、金融系统中 KYC 采集的分层模型(非常重要)](#(3)、金融系统中 KYC 采集的分层模型(非常重要))
- (4)、各层采集内容详解(前端视角)
-
- ①、基础身份信息采集(最低层)
- ②、证件材料采集(核心)
- [③、生物特征采集(强 KYC)](#③、生物特征采集(强 KYC))
- [④、行为 & 环境信息采集(风控配合)](#④、行为 & 环境信息采集(风控配合))
- ⑤、合规授权与审计(不能省)
- [(5)、金融系统中 KYC 采集的核心原则(背下来)](#(5)、金融系统中 KYC 采集的核心原则(背下来))
- [(6)、KYC 采集状态机(文字版)](#(6)、KYC 采集状态机(文字版))
- [(7)、一个简单但企业级的 KYC 采集实践示例](#(7)、一个简单但企业级的 KYC 采集实践示例)
-
- [①、前端 KYC 数据结构(企业级)](#①、前端 KYC 数据结构(企业级))
- [②、身份证图片采集 + OCR](#②、身份证图片采集 + OCR)
- [③、KYC 提交逻辑(核心)](#③、KYC 提交逻辑(核心))
- [④、KYC 页面核心流程(简化)](#④、KYC 页面核心流程(简化))
- 3、表单安全
-
- (1)、表单安全概念
- (2)、为什么金融系统对表单安全要求极高?
- (3)、金融系统里的「表单安全」和普通系统的本质区别
- (4)、金融系统表单安全的「六大防线」(核心框架)
-
- ①、输入真实性校验(你是不是"人")
- ②、输入完整性保护(你有没有"少交/多交")
- [③、防篡改 & 防重放(这一条非常金融)](#③、防篡改 & 防重放(这一条非常金融))
- ④、自动化攻击防护(刷接口)
- ⑤、提交链路安全(你"怎么提交"的)
- ⑥、审计与可追溯(金融系统的底线)
- (5)、金融表单安全的一个"核心认知误区"
- (6)、一个「简单但企业级」的表单安全实践示例
- 4、多因子认证(MFA)
- 5、设备指纹技术
-
- (1)、设备指纹概念
- [(2)、设备指纹 ≠ 认证(这是最重要的边界)](#(2)、设备指纹 ≠ 认证(这是最重要的边界))
- (3)、金融系统为什么"必须"要设备指纹?
- (4)、金融级设备指纹的分层模型(非常重要)
- (5)、各层特征详解(前端视角)
-
- ①、基础环境特征(必采,但不可靠)
- [②、硬件 / 渲染特征(核心)](#②、硬件 / 渲染特征(核心))
- [③、行为 & 使用特征(金融系统非常看重)](#③、行为 & 使用特征(金融系统非常看重))
- ④、风控增强信号(辅助判断)
- ⑤、指纹聚合(这是后端的事)
- (6)、设备指纹在金融系统中的典型使用场景
- (7)、金融系统中设备指纹的关键设计原则
- (8)、一个简单但企业级的设备指纹实践示例
-
- ①、设备指纹数据结构(企业级)
- [②、Canvas 指纹采集(核心示例)](#②、Canvas 指纹采集(核心示例))
- [③、WebGL 指纹采集(简化)](#③、WebGL 指纹采集(简化))
- [④、聚合并生成指纹 ID](#④、聚合并生成指纹 ID)
- ⑤、登录时上报设备指纹
- 6、行为认证技术(隐形安全)
-
- (1)、行为认证技术概念
- [(2)、行为认证 ≠ MFA / 设备指纹](#(2)、行为认证 ≠ MFA / 设备指纹)
- (3)、金融系统中行为认证的典型采集维度(前端侧)
- (4)、行为认证在金融系统中的典型使用场景
- (5)、金融系统行为认证的关键原则
- (6)、行为认证技术典型流程(文字版)
- (7)、一个简单但企业级的前端实践示例
-
- ①、前端数据结构
- [②、核心采集逻辑(React + TS)](#②、核心采集逻辑(React + TS))
- ③、登录/提交时上传行为数据
- ④、企业级特性说明
- ⑤、金融系统行为认证的注意点
- 7、认证流程编排(状态机)
- 8、策略模式(风险驱动)
- [9、Token & 会话管理](#9、Token & 会话管理)
-
- [(1)、Token & 会话管理概念](#(1)、Token & 会话管理概念)
- [(2)、金融系统为什么必须重视 Token & 会话管理?](#(2)、金融系统为什么必须重视 Token & 会话管理?)
- (3)、核心概念
- [(4)、Token & 会话管理策略(金融系统实践)](#(4)、Token & 会话管理策略(金融系统实践))
-
- [①、Access Token & Refresh Token 分层](#①、Access Token & Refresh Token 分层)
- ②、会话生命周期管理
- [③、Token 安全增强措施](#③、Token 安全增强措施)
- ④、会话状态同步机制
- (5)、一个简单但企业级前端实践示例
-
- [①、Token 类型定义](#①、Token 类型定义)
- ②、前端会话管理类(企业级简化示例)
- ③、登录时使用示例
- [④、API 调用示例(带 Token 自动刷新)](#④、API 调用示例(带 Token 自动刷新))
- ⑤、企业级特性说明
- 10、防攻击技术(金融高频)
- [11、防调试 & 反篡改(进阶)](#11、防调试 & 反篡改(进阶))
-
- [(1)、金融系统为什么必须做「防调试 & 反篡改」](#(1)、金融系统为什么必须做「防调试 & 反篡改」)
-
- ①、金融系统面临的真实威胁
- [②、防调试 & 反篡改在整体安全体系中的位置](#②、防调试 & 反篡改在整体安全体系中的位置)
- [(2)、防调试 & 反篡改的核心目标(金融级)](#(2)、防调试 & 反篡改的核心目标(金融级))
- [(3)、金融系统防调试 & 反篡改的技术拆解(前端重点)](#(3)、金融系统防调试 & 反篡改的技术拆解(前端重点))
- [(4)、金融系统防调试 & 反篡改设计原则(非常重要)](#(4)、金融系统防调试 & 反篡改设计原则(非常重要))
- (5)、一个「简单但企业级」的前端实践示例
-
- [①、DevTools 打开检测(简化版)](#①、DevTools 打开检测(简化版))
- ②、函数完整性检测
- ③、关键状态防篡改(闭包)
- ④、风险信号采集与上报
- ⑤、在关键操作前调用
- ⑥、企业级实践补充
- 12、审计与合规技术
-
- (1)、审计与合规技术概念
- (2)、金融系统审计与合规的整体技术架构(文字版)
- (3)、金融系统审计的"五大核心维度"(非常关键)
-
- [①、用户行为审计(Who & What)](#①、用户行为审计(Who & What))
- [②、时间 & 顺序审计(When & Order)](#②、时间 & 顺序审计(When & Order))
- [③、环境与设备审计(Where & With What)](#③、环境与设备审计(Where & With What))
- ④、决策与策略审计(Why)
- ⑤、结果与责任审计(Outcome)
- (4)、前端在审计与合规中扮演什么角色?
- (5)、金融前端常见的审计采集内容
- (6)、审计数据的几个金融级技术要求
- (7)、一个「简单但企业级」的审计实践示例
- 六、常见前端「认证」方式
-
- 1、如何做「账号+密码」认证?
-
- (1)、认清"账号+密码"认证
- (2)、金融系统「账号」的设计原则
- (3)、金融系统「密码」的真实安全模型
- [(4)、金融级「账号 + 密码」认证流程(核心)](#(4)、金融级「账号 + 密码」认证流程(核心))
- (5)、金融系统必须额外叠加的安全策略
-
- ①、登录失败策略(极其重要)
- [②、设备 & 环境校验(前端强相关)](#②、设备 & 环境校验(前端强相关))
- [③、登录成功 ≠ 认证完成](#③、登录成功 ≠ 认证完成)
- (6)、前端「账号+密码」认证典例(企业级)
- 2、如何做「短信/邮件验证码」认证?
-
- (1)、认清"短信/邮件验证码"认证
- (2)、金融级验证码的核心安全要求
- (3)、前端在验证码认证中的真实职责
- [(4)、短信 vs 邮件验证码(金融视角对比)](#(4)、短信 vs 邮件验证码(金融视角对比))
- (5)、金融系统中验证码的典型使用模式
- (6)、前端「短信/邮件验证码」认证典例(企业级)
- 3、如何做「图形验证码」认证?
- 4、如何做「动态令牌(TOTP)」认证?
-
- (1)、认清"动态令牌(TOTP)"认证
- [(2)、TOTP 的典型场景(金融系统)](#(2)、TOTP 的典型场景(金融系统))
- [(3)、TOTP 的原理(金融视角重点)](#(3)、TOTP 的原理(金融视角重点))
- [(4)、金融系统 TOTP 的前端职责](#(4)、金融系统 TOTP 的前端职责)
- [(5)、金融系统 TOTP 的完整流程](#(5)、金融系统 TOTP 的完整流程)
- (6)、金融级最佳实践
- (7)、前端「动态令牌(TOTP)」认证典例(企业级)
-
- ①、接口约定(金融实践)
- ②、前端展示二维码示例
- [③、登录使用 OTP 示例](#③、登录使用 OTP 示例)
- 5、如何做「人脸/指纹/声纹」认证?
-
- (1)、认清"人脸/指纹/声纹"认证
- (2)、三类生物识别详细解析
-
- ①、指纹识别(Fingerprint)
- [②、人脸识别(Face Recognition)](#②、人脸识别(Face Recognition))
- [③、声纹识别(Voice Recognition)](#③、声纹识别(Voice Recognition))
- (3)、金融系统生物认证流程(以移动端为例)
- (4)、金融级前端注意事项
- (5)、前端「生物」认证典例(企业级)
- [6、如何做「身份证 + 活体检测」认证?](#6、如何做「身份证 + 活体检测」认证?)
-
- [(1)、认清"身份证 + 活体检测"认证](#(1)、认清“身份证 + 活体检测”认证)
- (2)、为什么金融系统必须做这一步?
- (3)、认证的核心拆解(金融视角)
- (4)、活体检测为什么是"关键中的关键"
- [(5)、前端在「身份证 + 活体检测」中的真实职责](#(5)、前端在「身份证 + 活体检测」中的真实职责)
- (6)、金融系统完整认证流程(标准)
- (7)、金融级关键设计原则(非常重要)
- [(8)、前端「身份证 + 活体检测」认证典例(企业级)](#(8)、前端「身份证 + 活体检测」认证典例(企业级))
- [七、金融身份认证 vs 普通互联网对比](#七、金融身份认证 vs 普通互联网对比)
- [八、在 web3 中如何做「金融系统的身份认证」?](#八、在 web3 中如何做「金融系统的身份认证」?)
-
- [1、金融身份认证:Web3 vs Web2(全面对比)](#1、金融身份认证:Web3 vs Web2(全面对比))
-
- (1)、整体架构对比(本质层面)
- (2)、身份模型对比
-
- [①、Web2:账户模型(Account-based Identity)](#①、Web2:账户模型(Account-based Identity))
- [②、Web3:密钥模型(Key-based Identity)](#②、Web3:密钥模型(Key-based Identity))
- (3)、认证方式对比(核心)
- [(4)、KYC & 合规对比(金融关键)](#(4)、KYC & 合规对比(金融关键))
- (5)、安全模型对比
- (6)、攻击面差异
- (7)、金融级「真实落地形态」
- (8)、适用场景对比
- [(9)、Web2 和 Web3 对比总结(金融视角)](#(9)、Web2 和 Web3 对比总结(金融视角))
- [2、在 web3 中做身份认证](#2、在 web3 中做身份认证)
-
- [(1)、web3 身份认证的概念](#(1)、web3 身份认证的概念)
- [(2)、Web3 金融身份认证的本质拆解](#(2)、Web3 金融身份认证的本质拆解)
-
- [①、Web3 身份的三大核心元素](#①、Web3 身份的三大核心元素)
- [②、为什么金融 Web3 必须做"身份认证"?](#②、为什么金融 Web3 必须做“身份认证”?)
- [(3)、Web3 金融身份认证的主流技术路径](#(3)、Web3 金融身份认证的主流技术路径)
-
- ①、路径一:钱包签名认证(最基础)
- [②、路径二:SIWE(Sign-In With Ethereum)](#②、路径二:SIWE(Sign-In With Ethereum))
- ③、路径三:DID(去中心化身份)
- [④、路径四:Web3 + KYC(合规金融必备)](#④、路径四:Web3 + KYC(合规金融必备))
- [(4)、Web3 金融身份认证的整体架构(文字版)](#(4)、Web3 金融身份认证的整体架构(文字版))
- [(5)、一个「简单但企业级」Web3 身份认证示例](#(5)、一个「简单但企业级」Web3 身份认证示例)
-
- [①、前端:请求 challenge](#①、前端:请求 challenge)
- ②、前端:钱包签名
- ③、前端:提交签名
- ④、后端(逻辑说明)
- ⑤、企业级增强点(金融必备)
- [(6)、Web3 金融身份认证的"真实落地形态"](#(6)、Web3 金融身份认证的“真实落地形态”)
前言
用户身份认证(User Authentication)是指验证用户身份是否合法的过程,是登录、支付、敏感操作等的前置环节。它与授权(Authorization)不同,前者是确认"你是谁",后者是确认"你能做什么"。
- 身份认证 ≠ 登录,而是:资金安全、合规责任、风险控制的第一道防线
金融身份认证不是"你能不能登录",而是"在任何时刻你是否仍然可信"。
一、金融行业特殊要求
在金融行业,用户身份认证尤其关键,因为涉及资金安全、合规要求、反洗钱(AML)等。
金融系统必须满足:
- 资金不可逆风险
- 监管合规(KYC / AML / 等保 / PCI-DSS)
- 高频攻击目标(撞库 / 钓鱼 / 脚本 / 内鬼)
- 所有操作可审计、可追责
所以,金融认证具备 4 个核心目标:
| 目标 | 说明 |
|---|---|
| 真实性 | 你是不是你(人、证、账号绑定) |
| 持续性 | 登录后"你一直是你" |
| 可追溯 | 出事后能完整复盘 |
| 可风控 | 风险升高 → 动态加严认证 |
二、金融认证前端架构
typescript
┌───────────────────────────────────────────────────────────┐
│ 业务层(App / Web) │
│ 登录 / 转账 / 提现 / 修改设置 / 高风险操作 │
│ │
│ 只调用:authSDK.authenticate(scene, options) │
└───────────────┬───────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────┐
│ 认证编排层(Auth SDK Core) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Context 管理 │ │ 状态机引擎 │ │ 策略选择器 │ │
│ │ (身份/设备) │ │ (流程可控) │ │ (风险驱动) │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 认证流程编排器(Auth Engine) │ │
│ │ - 认证步骤排序 │ │
│ │ - Step-Up 插入 │ │
│ │ - 失败熔断 │ │
│ └──────────────┬──────────────────────────────────────┘ │
│ │
│ ▼
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 认证插件层(可插拔) │ │
│ │ PASSWORD / OTP / TOTP / 生物识别 / 图形验证码 │ │
│ └──────────────┬──────────────────────────────────────┘ │
│ │
│ ▼
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 安全与合规模块(内建) │ │
│ │ - 设备指纹 │ │
│ │ - 行为采集 │ │
│ │ - Token 绑定 │ │
│ │ - 审计日志 │ │
│ └─────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────┐
│ 后端 / 风控 / 身份服务 │
│ Auth API / Risk API / KYC API / Token Service │
└───────────────────────────────────────────────────────────┘
前端横跨全部层级,不是"只负责 UI"。
三、前端身份认证流程
typescript
进入系统
↓
环境与设备采集(无感)
↓
基础登录认证
↓
风险评估(实时)
↓
是否需要升级认证(Step-Up)
↓
会话建立与绑定
↓
持续认证 & 高风险操作再认证
金融前端身份认证是"先无感、再显式、持续校验、动态加严"的过程。
四、金融身份认证的完整业务生命周期
- 用户初始身份建立(KYC)
- 登录认证(Login Authentication)
- 会话与持续认证(Session / Token)
- 高风险操作的二次认证(Step-Up Auth)
- 设备与环境认证(金融必备)
- 行为认证(隐形认证)
1、用户初始身份建立(KYC)
这是金融与普通互联网最大的分水岭。
典型 KYC 认证流程:
- 采集基础信息(姓名 / 证件号)
- 证件拍摄(身份证 / 护照)
- 活体检测(眨眼 / 点头 / 视频)
- 第三方公安/权威机构校验
- 建立"可信身份档案"
前端关键职责:
- 摄像头调用(Web / App)
- 图片/视频采集与压缩
- 加密上传(HTTPS + 业务加密)
- 防篡改(禁止本地文件上传)
- 异常环境拦截(模拟器 / Hook)
⚠️ 金融前端绝不信任用户输入的身份信息
2、登录认证(Login Authentication)
金融登录 ≠ 账号密码:
| 风险等级 | 认证方式 |
|---|---|
| 低风险 | 密码 / 短信 |
| 中风险 | 密码 + 验证码 |
| 高风险 | MFA(OTP / 生物) |
登录真实流程(简化):
typescript
输入账号
↓
图形验证码
↓
密码(前端加密)
↓
设备风险评估
↓
是否触发 MFA
↓
下发会话凭证
金融前端登录特性:
- 密码永不明文传输
- 验证码强制防刷
- 异常设备自动加严
- 失败次数风控联动
3、会话与持续认证(Session / Token)
金融系统关注的不是"登录成功",而是:
- 你在整个会话中是否一直可信
会话安全策略:
| 机制 | 目的 |
|---|---|
| 短 Access Token | 降低泄露风险 |
| Refresh Token | 无感续期 |
| Token 绑定设备 | 防盗用 |
| 活跃心跳 | 防挂机 |
| 空闲自动登出 | 防旁路攻击 |
前端要点:
- Token 不落地或 HttpOnly Cookie
- 自动刷新但感知风险
- 环境变化 → 强制重新认证
4、高风险操作的二次认证(Step-Up Auth)
这是金融系统的核心设计。
典型高风险操作:
- 大额转账
- 修改银行卡
- 提现
- 修改登录凭证
- 解绑设备
风控驱动认证升级:
typescript
操作发起
↓
实时风控评分
↓
是否超过阈值
↓
触发二次认证
二次认证手段:
- 短信 OTP
- TOTP
- 生物识别
- 动态口令卡
前端必须支持动态插入认证流程,而不是写死。
5、设备与环境认证(金融必备)
金融系统不仅认人,也认设备。
设备指纹构成:
- UA / 屏幕 / 字体
- Canvas / WebGL
- 时区 / 语言
- 存储能力
- App 安装签名(移动端)
前端职责:
- 指纹采集与上报
- 异常环境检测
- 设备绑定 / 解绑流程
金融系统里,账号 + 设备 + 行为 才是完整身份。
6、行为认证(隐形认证)
这是高级金融系统的杀手锏。
行为维度:
- 点击节奏
- 输入速度
- 页面停留时间
- 操作路径稳定性
特点:
- 用户无感知
- 与显式认证互补
- 风险升高 → 提权失败
前端负责行为数据采集 + 实时上报。
五、前端核心技术实现
核心技术一览(分层):
| 层级 | 核心技术 |
|---|---|
| 安全基础 | HTTPS / TLS / 前端加密 |
| 身份采集 | 表单安全 / KYC 采集 |
| 认证方式 | 密码 / OTP / TOTP / 生物 |
| 风控 | 设备指纹 / 行为分析 |
| 编排 | 状态机 / 策略模式 |
| 会话 | Token / Cookie / CSRF |
| 防攻击 | 防刷 / 防重放 / 防调试 |
| 合规 | 审计 / 追踪 / 日志 |
下面将逐项地深入研究这些核心技术(金融视角)。
1、HTTPS + 前端加密(双重保护)
- HTTPS 解决"路上不被偷",
- 前端加密解决"起点不裸奔",
- 后端哈希解决"终点不存明文"。
(1)、「HTTPS + 前端加密」概念
HTTPS + 前端加密不是"重复加密",而是"分层防御(Defense in Depth)"。
- HTTPS 解决"链路安全"
- 前端加密解决"终端与信任边界问题"
(2)、为什么 HTTPS 在金融系统里"不够用"?
HTTPS(TLS)解决的是:
typescript
浏览器 ↔ 服务端
但金融系统真正担心的是:
| 风险点 | HTTPS 能否解决 |
|---|---|
| 浏览器被注入脚本 | ❌ |
| 前端代码被篡改 | ❌ |
| 恶意插件读取表单 | ❌ |
| 调试工具抓取明文 | ❌ |
| 终端被攻陷 | ❌ |
❗️ HTTPS 只保护"传输链路",不保护"数据产生点"
(3)、前端加密在金融系统中的真实定位
前端加密 = 在"不可信终端"中,尽可能提前保护敏感数据
(4)、HTTPS + 前端加密的分层模型(核心)
typescript
用户输入密码
↓
【前端加密】← 保护终端 & JS 运行环境
↓
HTTPS(TLS)← 保护网络链路
↓
后端解密
↓
后端加盐哈希(最终存储)
每一层失守,下一层兜底
(5)、金融系统里"前端加密"一般加密什么?
不是所有字段都加密,只加高价值敏感数据:
| 字段 | 是否前端加密 |
|---|---|
| 登录密码 | ✅ 必须 |
| 交易密码 | ✅ 必须 |
| 短信验证码 | ⚠️ 视情况 |
| 身份证号 | ✅ 常见 |
| 银行卡号 | ⚠️ 常见 |
| 普通表单 | ❌ |
(6)、金融系统中常见的前端加密方案
非对称加密(最常见):
| 算法 | 场景 |
|---|---|
| RSA | Web 最常见 |
| SM2 | 国密合规系统 |
前端用公钥,加密;后端用私钥,解密
对称 + 非对称混合(高级):
typescript
前端生成随机 AES Key
↓
用 RSA 加密 AES Key
↓
用 AES 加密数据
- 优点:性能更好
- 缺点:实现复杂(常用于交易接口)
(7)、企业级实践:HTTPS + 前端加密(完整示例)
技术栈:React + TypeScript
加密:RSA
目标:金融登录密码保护
①、服务端:下发公钥(示意)
typescript
// GET /api/auth/public-key
{
"key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkq...\n-----END PUBLIC KEY-----"
}
⚠️ 注意:
- 公钥 定期轮换
- 可与 session / nonce 绑定
②、前端:加密工具封装(企业级)
typescript
// utils/rsa.ts
import JSEncrypt from 'jsencrypt';
let encryptor: JSEncrypt | null = null;
export function initEncrypt(publicKey: string) {
encryptor = new JSEncrypt();
encryptor.setPublicKey(publicKey);
}
export function encrypt(value: string): string {
if (!encryptor) {
throw new Error('Encryptor not initialized');
}
const result = encryptor.encrypt(value);
if (!result) {
throw new Error('Encryption failed');
}
return result;
}
③、登录请求(HTTPS + 加密)
typescript
// services/auth.ts
import axios from 'axios';
import { encrypt } from '@/utils/rsa';
export async function login(
account: string,
password: string
) {
return axios.post('/api/auth/login', {
account,
password: encrypt(password),
});
}
④、登录流程中的关键控制点(金融级)
typescript
页面加载
↓
拉取 RSA 公钥
↓
初始化加密器
↓
用户输入
↓
前端加密
↓
HTTPS 发送
任一步失败 → 禁止登录
(8)、这套方案解决了哪些金融风险?
| 风险 | 是否覆盖 |
|---|---|
| 明文抓包 | ✅ |
| 中间人攻击 | ✅ |
| JS 调试查看密码 | ✅ |
| 日志误打印 | ✅ |
| 重放攻击 | ⚠️(需 nonce) |
(9)、金融系统中必须补充的"防重放设计"
前端加密 ≠ 安全完成,必须配合 nonce / timestamp:
typescript
{
password: encrypt(password),
nonce: encrypt(random()),
timestamp: Date.now()
}
后端校验:
- nonce 是否使用过
- 时间窗口是否合法
2、KYC 采集
KYC 采集不是填资料,而是在合规边界内,为"信任建立"提供可验证证据。
(1)、KYC 采集概念
KYC 采集(Know Your Customer Collection)是指:
- 在合法授权前提下,采集用于"识别、核验、评估客户风险"的必要信息与材料。
关键词只有三个:
- 合法
- 必要
- 可核验
(2)、KYC 采集 ≠ 表单填写(这是第一个认知分水岭)
普通表单采集:
- 用户随便填
- 可重复
- 错了可以改
金融 KYC 采集:
- 一次性
- 强约束
- 强审
- 不可随意修改
👉 所以金融 KYC 采集,本质是受监管的数据采集流程。
(3)、金融系统中 KYC 采集的分层模型(非常重要)
标准分层(你以后可以直接画架构图):
typescript
KYC 采集
├─ 基础身份信息采集
├─ 证件材料采集
├─ 生物特征采集
├─ 行为与环境信息采集
└─ 合规授权与留痕
(4)、各层采集内容详解(前端视角)
①、基础身份信息采集(最低层)
| 信息 | 说明 |
|---|---|
| 姓名 | 必填 |
| 证件类型 | 身份证 / 护照 |
| 证件号码 | 不直接展示 |
| 手机号 | 绑定账户 |
📌 特点:
- 表单形式
- 强校验
- 不可随意编辑
②、证件材料采集(核心)
常见形式:
- 身份证正反面拍照
- OCR 自动识别
- 用户二次确认
📌 金融要求:
- 原图上传
- 禁止相册篡改(App 端)
- 强制清晰度校验
③、生物特征采集(强 KYC)
| 类型 | 示例 |
|---|---|
| 人脸 | 活体检测 |
| 指纹 | App 登录 |
| 声纹 | 电话银行 |
📌 特点:
- 强交互
- 高失败率
- 强隐私提示
④、行为 & 环境信息采集(风控配合)
前端无感采集:
- 设备指纹
- IP / 地区
- 操作节奏
- 页面轨迹
这一步用户几乎无感,但对风控极其重要
⑤、合规授权与审计(不能省)
必须明确展示:
- 隐私政策
- 数据用途
- 数据保存期限
并记录:
- 用户确认行为
- 时间
- 版本号
(5)、金融系统中 KYC 采集的核心原则(背下来)
- 最小必要原则:不采与业务无关的信息
- 分级采集原则:不同业务 → 不同 KYC 等级
- 可中断 / 可恢复:允许失败,不允许跳过
- 状态驱动: KYC 必须是状态机
(6)、KYC 采集状态机(文字版)
typescript
INIT
↓
COLLECTING
↓
SUBMITTED
↓
VERIFYING
↓
PASSED / REJECTED / RETRY
前端一定要"围绕状态写代码"
(7)、一个简单但企业级的 KYC 采集实践示例
场景:互联网金融平台开户 KYC-L3(身份证 OCR)
①、前端 KYC 数据结构(企业级)
typescript
// types/kyc.ts
export interface KycPayload {
name: string;
idType: 'ID_CARD';
idNumber: string;
idFrontImage: string;
idBackImage: string;
deviceFingerprint: string;
consentVersion: string;
}
②、身份证图片采集 + OCR
typescript
// components/IdCardUpload.tsx
export function IdCardUpload({ onChange }: { onChange: (v: string) => void }) {
return (
<input
type="file"
accept="image/*"
onChange={e => {
const file = e.target.files?.[0];
if (!file) return;
// 实际项目中这里会先上传 OSS
const fakeUrl = URL.createObjectURL(file);
onChange(fakeUrl);
}}
/>
);
}
③、KYC 提交逻辑(核心)
typescript
// services/kyc.ts
import axios from 'axios';
export function submitKyc(data: KycPayload) {
return axios.post('/api/kyc/submit', data);
}
④、KYC 页面核心流程(简化)
typescript
export function KycPage() {
const [payload, setPayload] = useState<Partial<KycPayload>>({});
const handleSubmit = async () => {
await submitKyc(payload as KycPayload);
alert('KYC 已提交,等待审核');
};
return (
<>
<input
placeholder="姓名"
onChange={e => setPayload(p => ({ ...p, name: e.target.value }))}
/>
<IdCardUpload
onChange={url => setPayload(p => ({ ...p, idFrontImage: url }))}
/>
<button onClick={handleSubmit}>提交认证</button>
</>
);
}
- 有明确 KYC 等级
- 采集字段可审计
- 支持后续活体 / 风控扩展
- 前端不做"通过判断"
- 所有决策在后端
3、表单安全
表单安全不是"不让你乱填",而是"即使你乱来,系统也不会被你骗"。
(1)、表单安全概念
金融系统中的「表单安全」不是"防止用户乱填",而是:
- 在不可信终端中,确保关键业务输入"真实、完整、未被篡改、可追溯"。
关键词请记住这 4 个:
- 真实
- 完整
- 未被篡改
- 可追溯
(2)、为什么金融系统对表单安全要求极高?
因为在金融系统中:
- 几乎所有高风险业务,都是从表单开始的
比如:
- 登录
- KYC 采集
- 转账
- 提现
- 修改关键信息
表单 = 攻击入口 = 责任起点
(3)、金融系统里的「表单安全」和普通系统的本质区别
| 维度 | 普通系统 | 金融系统 |
|---|---|---|
| 信任前端 | 部分信任 | 完全不信任 |
| 校验 | 前端为主 | 后端为准,前端辅助 |
| 防刷 | 可选 | 必须 |
| 防篡改 | 少 | 强制 |
| 审计 | 少 | 必须 |
(4)、金融系统表单安全的「六大防线」(核心框架)
这是真正的金融级拆法👇
typescript
金融表单安全
├─ 输入真实性校验
├─ 输入完整性保护
├─ 防篡改与防重放
├─ 自动化攻击防护
├─ 提交链路安全
├─ 审计与可追溯
下面逐条拆。
①、输入真实性校验(你是不是"人")
解决什么问题?
- 机器人
- 脚本
- 批量攻击
常见手段:
- 图形验证码
- 行为验证码
- 操作节律分析
📌 特点:
- 发生在"填写阶段"
- 不影响业务逻辑
②、输入完整性保护(你有没有"少交/多交")
金融系统最怕的不是填错,而是:
- 少字段
- 多字段
- 伪造字段
实践原则:
- 前端"白名单提交",而不是"整个对象 submit"
❌ 错误示例:
typescript
axios.post('/api/submit', formData);
✅ 正确示例:
typescript
axios.post('/api/submit', {
amount,
accountId,
otp
});
③、防篡改 & 防重放(这一条非常金融)
真实攻击方式:
- DevTools 改值
- 抓包重放
- 多次提交同一请求
常见金融手段:
| 手段 | 说明 |
|---|---|
| nonce | 一次性随机数 |
| timestamp | 时间窗口 |
| 签名 | 参数不可改 |
| token 绑定 | 与会话绑定 |
④、自动化攻击防护(刷接口)
场景:
- 短信验证码表单
- 登录表单
- 提现申请
- 前端参与点
- 提交按钮冷却
- 防重复点击
- 行为异常上报
⑤、提交链路安全(你"怎么提交"的)
必须具备:
- HTTPS
- 敏感字段前端加密
- Content-Type 限制
- CSRF 防护
⑥、审计与可追溯(金融系统的底线)
每一次表单提交,至少要能回答:
- 谁
- 何时
- 从哪里
- 提交了什么
- 结果如何
前端必须参与"行为标记"和"上下文采集"
(5)、金融表单安全的一个"核心认知误区"
❌ "前端校验能提高安全性"
✅ 正确说法是:
- 前端校验提升的是"攻击成本"和"用户体验",
- 安全性必须由后端兜底。
(6)、一个「简单但企业级」的表单安全实践示例
场景:金融系统中的「登录表单」
①、表单数据白名单构造(关键)
typescript
// services/login.ts
export function buildLoginPayload(
account: string,
password: string,
nonce: string
) {
return {
account,
password,
nonce,
timestamp: Date.now()
};
}
②、提交前加密(敏感字段)
typescript
import { encrypt } from '@/utils/rsa';
export function secureLoginPayload(payload: any) {
return {
...payload,
password: encrypt(payload.password)
};
}
③、防重复提交(前端必须做)
typescript
const [submitting, setSubmitting] = useState(false);
const handleSubmit = async () => {
if (submitting) return;
setSubmitting(true);
try {
await login(payload);
} finally {
setSubmitting(false);
}
};
④、提交请求(最终形态)
typescript
axios.post('/api/auth/login', securePayload, {
headers: {
'X-Form-Type': 'LOGIN'
}
});
- 参数白名单
- nonce / timestamp
- 前端加密
- 防重复提交
- 可审计字段
- 后端可风控接入
4、多因子认证(MFA)
MFA(Multi-Factor Authentication)的定义:
- 同时使用"不同类型"的两种或以上认证因子,对同一用户身份进行确认。
MFA 的本质:不是增加步骤,而是用"不同类型因子"提高身份确认的可信度。
MFA 的三大因子类型:
| 因子类型 | 核心含义 | 典型示例 |
|---|---|---|
| 知识因子(Something you know) | 你知道的 | 密码、PIN |
| 持有因子(Something you have) | 你持有的 | 手机、U盾、令牌 |
| 生物因子(Something you are) | 你自身的 | 指纹、人脸、声纹 |
真正的 MFA 必须跨类型组合
(同类因子叠加 ≠ MFA)
金融系统中的 MFA 强度分级(常用):
| 强度 | 组合方式 |
|---|---|
| 低 | 密码 + 短信 |
| 中 | 密码 + TOTP |
| 高 | 密码 + 硬件 Key |
| 极高 | 生物识别 + 硬件 |
金融系统里的一个关键原则(非常重要):
- MFA 不是"越多越好",而是"按风险动态触发"。
也就是:
- 低风险 → 不触发
- 中风险 → 短信 / TOTP
- 高风险 → 生物 / 硬件
这些 MFA 的具体实现,请看下文的:「六、常见前端「认证」方式」
5、设备指纹技术
(1)、设备指纹概念
设备指纹(Device Fingerprint)是指:
- 在不可信终端环境中,通过多维稳定特征组合,持续识别"是否为同一设备"的风控技术。
注意关键词:
- 不是精确识别某个人
- 而是稳定识别某一设备
- 结果用于风控,不是认证
(2)、设备指纹 ≠ 认证(这是最重要的边界)
| 维度 | 设备指纹 | 身份认证 |
|---|---|---|
| 回答的问题 | "像不像这台设备" | "是不是这个人" |
| 是否能单独放行 | ❌ | ✅ |
| 是否有法律效力 | ❌ | ✅ |
| 是否用户可感知 | ❌(无感) | ✅(有感) |
设备指纹永远只能作为"辅助信号"
(3)、金融系统为什么"必须"要设备指纹?
因为金融攻击的真实形态是:
- 账号泄露 + 新设备登录
- 批量注册 / 撞库
- 脚本模拟人类操作
- 分布式代理攻击
账号维度已经不够了,必须引入"设备维度"
(4)、金融级设备指纹的分层模型(非常重要)
typescript
设备指纹
├─ 基础环境特征(低稳定)
├─ 硬件 / 渲染特征(中稳定)
├─ 行为 & 使用特征(高稳定)
├─ 风控增强信号(辅助)
└─ 指纹聚合 & 评分
(5)、各层特征详解(前端视角)
①、基础环境特征(必采,但不可靠)
| 特征 | 说明 |
|---|---|
| User-Agent | 可伪造 |
| OS / 浏览器 | 易变 |
| 语言 / 时区 | 易改 |
| 分辨率 | 易变 |
只能当"维度",不能当"ID"
②、硬件 / 渲染特征(核心)
这是浏览器指纹的核心价值:
- Canvas 指纹
- WebGL 指纹
- AudioContext 指纹
- 字体列表
- GPU 渲染差异
📌 特点:
- 稳定性高
- 用户难以伪造
- 跨 session 识别能力强
③、行为 & 使用特征(金融系统非常看重)
不是"行为认证",而是设备使用模式:
- 页面访问顺序
- 操作间隔分布
- 输入节奏统计(非内容)
- 鼠标轨迹统计特征
增强"同设备"的置信度
④、风控增强信号(辅助判断)
- IP / ASN
- 代理 / VPN 特征
- 网络抖动特征
- 是否无头浏览器
⑤、指纹聚合(这是后端的事)
前端只负责采集 & 上报:
typescript
设备特征集合
↓
hash / embedding
↓
设备指纹 ID
↓
风险评分
(6)、设备指纹在金融系统中的典型使用场景
| 场景 | 作用 |
|---|---|
| 登录 | 新设备识别 |
| MFA | 是否触发 |
| KYC | 风险加权 |
| 提现 | 二次校验 |
| 风控 | 黑设备库 |
(7)、金融系统中设备指纹的关键设计原则
- 不依赖单一特征
- 不追求"100% 唯一"
- 可变化、可演进
- 合规可解释
- 不影响用户体验
(8)、一个简单但企业级的设备指纹实践示例
场景:金融系统登录前的设备指纹采集(前端)
①、设备指纹数据结构(企业级)
typescript
// types/deviceFingerprint.ts
export interface DeviceFingerprint {
ua: string;
language: string;
timezone: string;
screen: string;
canvas: string;
webgl: string;
}
②、Canvas 指纹采集(核心示例)
typescript
// utils/canvasFingerprint.ts
export function getCanvasFingerprint(): string {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
if (!ctx) return '';
ctx.textBaseline = 'top';
ctx.font = '14px Arial';
ctx.fillText('finance-security', 2, 2);
return canvas.toDataURL();
}
③、WebGL 指纹采集(简化)
typescript
// utils/webglFingerprint.ts
export function getWebGLFingerprint(): string {
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
if (!gl) return '';
const vendor = gl.getParameter(gl.VENDOR);
const renderer = gl.getParameter(gl.RENDERER);
return `${vendor}~${renderer}`;
}
④、聚合并生成指纹 ID
typescript
// utils/deviceFingerprint.ts
import { sha256 } from './hash';
import { getCanvasFingerprint } from './canvasFingerprint';
import { getWebGLFingerprint } from './webglFingerprint';
export function collectDeviceFingerprint() {
const raw = {
ua: navigator.userAgent,
language: navigator.language,
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
screen: `${screen.width}x${screen.height}`,
canvas: getCanvasFingerprint(),
webgl: getWebGLFingerprint()
};
return sha256(JSON.stringify(raw));
}
⑤、登录时上报设备指纹
typescript
// services/login.ts
import { collectDeviceFingerprint } from '@/utils/deviceFingerprint';
export function login(account: string, password: string) {
return axios.post('/api/auth/login', {
account,
password,
deviceId: collectDeviceFingerprint()
});
}
- 多特征聚合
- 指纹不可逆
- 不存原始特征
- 与业务解耦
- 可风控评分
- 可演进扩展
6、行为认证技术(隐形安全)
行为认证技术是一种"隐形安全感知",通过前端采集用户操作模式,为风控系统提供动态风险评分,用于触发 MFA 或阻断高风险操作。
(1)、行为认证技术概念
行为认证技术(Behavioral Authentication / Invisible Security)是指:
- 在不打扰用户体验的前提下,通过采集和分析用户操作行为及环境特征,对操作是否可信、是否存在异常进行判断的技术。
关键点:
- 隐形:用户几乎无感
- 风险识别:不是身份认证本身,而是辅助触发 MFA / 风控
- 动态:行为特征可随时间演变
(2)、行为认证 ≠ MFA / 设备指纹
| 维度 | 行为认证 | 设备指纹 | MFA |
|---|---|---|---|
| 核心问题 | "像不像这个用户" | "像不像这台设备" | "是不是本人" |
| 用户可感知 | ❌ 无感 | ❌ 无感 | ✅ 有交互 |
| 前端参与度 | 高(采集) | 高(采集) | 高(交互) |
| 输出 | 风险评分 / 异常标记 | 风险评分 | 通过/拒绝 |
行为认证主要用于"动态风险分析",是风控信号之一
(3)、金融系统中行为认证的典型采集维度(前端侧)
①、交互行为特征
| 维度 | 说明 |
|---|---|
| 鼠标轨迹 | 移动速度、点击分布、轨迹曲线 |
| 滑动行为 | 速度、加速度、停留点 |
| 输入节奏 | 键盘输入速度、间隔、错误率 |
| 页面操作序列 | 打开顺序、表单填写顺序 |
②、会话行为特征
| 维度 | 说明 |
|---|---|
| 页面停留时间 | 过快或过慢异常 |
| 点击密度 | 高频点击可疑 |
| 滚动深度 | 页面访问习惯 |
| 操作时间段 | 非典型时间操作 |
③、环境特征(辅助)
| 维度 | 说明 |
|---|---|
| IP / 地理位置 | 突然异地 |
| 设备 ID | 与设备指纹结合 |
| 浏览器特征 | UA、渲染差异 |
(4)、行为认证在金融系统中的典型使用场景
| 场景 | 作用 |
|---|---|
| 登录 | 异常行为触发 MFA |
| 转账 / 提现 | 异常行为触发二次验证 |
| KYC / 注册 | 防批量注册 / 机器人 |
| 敏感操作 | 动态评分 + 风控决策 |
(5)、金融系统行为认证的关键原则
- 隐形采集:不打扰用户体验
- 动态风险评分:风控系统决定是否触发 MFA
- 可持续更新:行为模型可随用户演变
- 多信号融合:与设备指纹、位置、MFA组合使用
- 合规可解释:采集的数据必须遵守隐私政策和监管要求
(6)、行为认证技术典型流程(文字版)
typescript
用户操作 → 前端采集行为特征 →
行为特征加密/打包 → 上传风控系统 →
风控评分计算 → 输出风险等级 →
触发策略:无感通过 / 异常触发 MFA / 阻断
(7)、一个简单但企业级的前端实践示例
场景:金融系统登录 / 转账行为采集
①、前端数据结构
typescript
// types/behavior.ts
export interface BehaviorPayload {
mouseMovements: { x: number; y: number; t: number }[];
keyPresses: { key: string; t: number }[];
scrolls: { scrollTop: number; t: number }[];
pageStayTime: number;
}
②、核心采集逻辑(React + TS)
typescript
import { useEffect, useRef } from 'react';
export function useBehaviorCollector() {
const mouseMovements = useRef<{ x: number; y: number; t: number }[]>([]);
const keyPresses = useRef<{ key: string; t: number }[]>([]);
const scrolls = useRef<{ scrollTop: number; t: number }[]>([]);
const startTime = useRef(Date.now());
useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
mouseMovements.current.push({ x: e.clientX, y: e.clientY, t: Date.now() });
};
const handleKeyPress = (e: KeyboardEvent) => {
keyPresses.current.push({ key: e.key, t: Date.now() });
};
const handleScroll = () => {
scrolls.current.push({ scrollTop: window.scrollY, t: Date.now() });
};
window.addEventListener('mousemove', handleMouseMove);
window.addEventListener('keypress', handleKeyPress);
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('mousemove', handleMouseMove);
window.removeEventListener('keypress', handleKeyPress);
window.removeEventListener('scroll', handleScroll);
};
}, []);
const collectBehaviorPayload = (): BehaviorPayload => {
return {
mouseMovements: mouseMovements.current,
keyPresses: keyPresses.current,
scrolls: scrolls.current,
pageStayTime: Date.now() - startTime.current,
};
};
return { collectBehaviorPayload };
}
③、登录/提交时上传行为数据
typescript
import axios from 'axios';
import { useBehaviorCollector } from './useBehaviorCollector';
function LoginForm() {
const { collectBehaviorPayload } = useBehaviorCollector();
const handleSubmit = async () => {
const behaviorData = collectBehaviorPayload();
await axios.post('/api/auth/login', {
account,
password,
behavior: behaviorData, // 上传给风控评分
});
};
return <button onClick={handleSubmit}>登录</button>;
}
④、企业级特性说明
- 数据采集无感知,不影响 UX
- 多信号融合:鼠标、键盘、滚动、停留时间
- 可扩展:未来可加触摸轨迹、手势等
- 后端可生成 行为风险评分
- 与设备指纹 / MFA 联动,提高安全性
⑤、金融系统行为认证的注意点
- 隐私合规:必须告知用户,并在隐私条款中说明
- 数据量控制:前端采集不宜过大,避免影响性能
- 防篡改:行为数据可加密签名
- 动态策略:风险评分阈值可调整
- 与 MFA / 风控决策解耦:前端只负责采集和上传
7、认证流程编排(状态机)
认证流程状态机是金融前端身份认证的"大脑",用明确状态和事件驱动,让复杂认证流程可控、安全、可扩展,同时与后端风控和 MFA 协同。
(1)、认证流程状态机概念
认证流程状态机(Authentication Flow State Machine)是指:
- 将用户身份认证的全流程拆解为明确的状态和状态转移规则,通过状态机管理各环节逻辑、异常和分支,实现前后端可控、安全、可扩展的认证编排。
关键词:
- 全流程管理:从登录到 MFA、KYC、风险评估
- 状态明确:每个节点有唯一标识
- 可控:异常、重试、分支、取消都有明确处理
- 可扩展:新增 MFA / KYC / 行为认证容易接入
(2)、为什么金融系统必须用状态机?
业务复杂度高
金融系统认证流程通常涉及:
- 密码登录
- 图形验证码
- 短信/邮箱验证码
- TOTP 动态口令
- 生物认证(人脸/指纹/声纹)
- KYC / 活体检测
- 行为认证 & 风控评分
这些环节有多分支、多条件、可重试,纯 if/else 会变得不可维护。
安全与合规要求:
- 每一步必须可审计
- 异常必须可追踪
- 用户状态必须明确(不能绕过某个环节)
(3)、金融系统认证状态机设计核心
①、核心状态分类
| 状态类型 | 说明 |
|---|---|
| 初始状态 INIT | 用户尚未认证 |
| 验证状态 VERIFYING | 用户在认证流程中 |
| 完成状态 PASSED | 认证成功 |
| 拒绝状态 REJECTED | 认证失败 |
| 异常状态 BLOCKED / RETRY | 异常或可重试 |
| 特殊状态 MFA_PENDING / KYC_PENDING | MFA 或 KYC 进行中 |
②、状态转移原则
- 单向流:状态必须有清晰的前后依赖
- 可回退 / 可重试:对于验证码失败或 MFA 失败
- 风险触发分支:风控评分高 → 强制 MFA 或阻断
- 事件驱动:每个状态变化都由事件触发
③、典型状态机(文字版)
typescript
INIT
├─(输入账号密码)→ VERIFYING_PASSWORD
│ ├─(密码正确)→ VERIFYING_MFA
│ │ ├─(MFA成功)→ PASSED
│ │ └─(MFA失败,可重试)→ RETRY
│ └─(密码错误)→ RETRY / BLOCKED
└─(未输入或异常)→ INIT
④、风控与动态分支
- 登录设备异常 → MFA_PENDING
- 风险评分高 → 强制 KYC
- MFA 超过次数 → BLOCKED
- 用户中途退出 → CANCELLED / INIT
所有这些都可以通过状态机可视化、可控地处理
⑤、状态机设计的原则
- 状态最小化:不要无意义拆分
- 事件清晰化:每个状态变化必须由事件触发
- 幂等与重试:状态切换必须可幂等处理
- 可扩展:新增认证手段不破坏原状态机
- 前后端一致:前端状态机只做 UI & 流程控制,后端决定最终认证结果
(4)、一个简单但企业级的前端状态机实践示例
场景:金融系统登录 + MFA 状态机
①、定义状态枚举
typescript
export enum AuthState {
INIT = 'INIT',
VERIFYING_PASSWORD = 'VERIFYING_PASSWORD',
VERIFYING_MFA = 'VERIFYING_MFA',
PASSED = 'PASSED',
RETRY = 'RETRY',
BLOCKED = 'BLOCKED'
}
export enum AuthEvent {
SUBMIT_PASSWORD = 'SUBMIT_PASSWORD',
PASSWORD_SUCCESS = 'PASSWORD_SUCCESS',
PASSWORD_FAILED = 'PASSWORD_FAILED',
MFA_SUCCESS = 'MFA_SUCCESS',
MFA_FAILED = 'MFA_FAILED'
}
②、状态机逻辑(简单实现)
typescript
interface Transition {
from: AuthState;
event: AuthEvent;
to: AuthState;
}
const transitions: Transition[] = [
{ from: AuthState.INIT, event: AuthEvent.SUBMIT_PASSWORD, to: AuthState.VERIFYING_PASSWORD },
{ from: AuthState.VERIFYING_PASSWORD, event: AuthEvent.PASSWORD_SUCCESS, to: AuthState.VERIFYING_MFA },
{ from: AuthState.VERIFYING_PASSWORD, event: AuthEvent.PASSWORD_FAILED, to: AuthState.RETRY },
{ from: AuthState.VERIFYING_MFA, event: AuthEvent.MFA_SUCCESS, to: AuthState.PASSED },
{ from: AuthState.VERIFYING_MFA, event: AuthEvent.MFA_FAILED, to: AuthState.RETRY }
];
export class AuthStateMachine {
state: AuthState = AuthState.INIT;
dispatch(event: AuthEvent) {
const transition = transitions.find(t => t.from === this.state && t.event === event);
if (transition) {
this.state = transition.to;
} else {
console.warn(`No transition for event ${event} from state ${this.state}`);
}
}
}
③、前端调用示例
typescript
const authSM = new AuthStateMachine();
// 用户提交密码
authSM.dispatch(AuthEvent.SUBMIT_PASSWORD);
// 后端返回密码成功
authSM.dispatch(AuthEvent.PASSWORD_SUCCESS);
// 前端显示 MFA UI
console.log(authSM.state); // VERIFYING_MFA
// 用户提交 MFA 成功
authSM.dispatch(AuthEvent.MFA_SUCCESS);
console.log(authSM.state); // PASSED
④、企业级特性说明
- 状态明确,可审计
- 可处理密码失败、MFA 失败等重试
- 可扩展:增加 KYC_PENDING、BLOCKED 等状态
- 前端 UI 完全由状态驱动
- 后端最终结果决定 PASSED / BLOCKED
- 支持风控动态触发 MFA / KYC 分支
8、策略模式(风险驱动)
策略模式(风险驱动)是金融前端风控的"大脑决策模块",它根据风险评分动态选择认证策略,实现安全与用户体验的平衡,并支持可扩展和可审计的认证流程。
(1)、策略模式(风险驱动)概念
策略模式(风险驱动,Risk-Driven Strategy Pattern)是指:
- 根据用户当前风险评分和环境信息,在前端动态选择不同的认证或操作策略,实现安全与用户体验的动态平衡。
关键词:
- 动态策略:不是固定认证流程,而是可变流程
- 风险驱动:策略由风险评分触发
- 前端参与:前端控制 UI / 流程,但决策可由后端风控校验
- 可扩展:新增认证手段可直接接入策略体系
(2)、为什么金融系统必须用策略模式?
业务场景复杂:
- 登录、转账、提现、KYC 注册、敏感操作
- 每个操作都有不同的风控要求
- 用户风险等级动态变化
用户体验与安全的平衡:
- 高风险用户 → 强化 MFA / 风控
- 低风险用户 → 简化流程,提升体验
策略模式能够把"风险 → 流程分支"抽象出来,避免硬编码 if/else
(3)、金融系统策略模式设计核心
①、核心组成
| 组件 | 功能 |
|---|---|
| 风控评分 | 根据设备指纹、行为认证、地理、账号历史计算风险分 |
| 策略定义 | 根据风险等级定义可用认证手段 / 流程 |
| 策略引擎 | 根据评分选择策略执行 |
| 执行器 | 前端根据策略控制 UI 流程、触发 MFA、KYC 等 |
②、策略抽象(文字版)
typescript
风险评分 → 策略选择 → 执行流程
LOW → 简化认证流程(密码 + 隐形风控)
MEDIUM → 强化 MFA(密码 + MFA)
HIGH → 强化 MFA + KYC(密码 + MFA + KYC)
BLOCK → 阻断操作
③、策略模式的关键原则
- 策略可扩展:新增认证方式不改核心逻辑
- 风险驱动:策略随评分动态变化
- 幂等安全:策略执行必须可重复,不破坏状态机
- 前后端分工明确:前端展示策略,后端最终验证安全
- 审计可追溯:每次策略选择和执行都有日志
④、前端策略与状态机结合
- 状态机管理认证流程
- 策略模式动态选择状态机分支或触发事件
- 风控评分 = 策略模式的输入
- 执行器 = 前端展示 + 表单 + MFA + KY
typescript
风险评分变化
↓
策略模式选定认证策略
↓
状态机根据策略驱动 UI / 流程
↓
前端采集行为 & 设备指纹上传风控
(4)、一个简单但企业级前端策略模式示例
场景:金融系统登录策略
①、定义策略接口
typescript
interface AuthStrategy {
execute(): void;
}
②、定义不同策略
typescript
class LowRiskStrategy implements AuthStrategy {
execute() {
console.log('低风险用户: 密码 + 隐形风控');
// 前端只展示密码输入表单
}
}
class MediumRiskStrategy implements AuthStrategy {
execute() {
console.log('中风险用户: 密码 + MFA');
// 展示密码 + MFA UI
}
}
class HighRiskStrategy implements AuthStrategy {
execute() {
console.log('高风险用户: 密码 + MFA + KYC');
// 展示密码 + MFA + KYC UI
}
}
class BlockStrategy implements AuthStrategy {
execute() {
console.log('阻断操作: 高风险用户');
// 禁用表单,显示阻断提示
}
}
③、策略选择器(风险驱动)
typescript
enum RiskLevel {
LOW,
MEDIUM,
HIGH,
BLOCK
}
function selectStrategy(risk: RiskLevel): AuthStrategy {
switch (risk) {
case RiskLevel.LOW:
return new LowRiskStrategy();
case RiskLevel.MEDIUM:
return new MediumRiskStrategy();
case RiskLevel.HIGH:
return new HighRiskStrategy();
case RiskLevel.BLOCK:
return new BlockStrategy();
default:
return new LowRiskStrategy();
}
}
④、前端执行策略示例
typescript
// 模拟从后端获取风险评分
const riskScore = RiskLevel.HIGH;
const strategy = selectStrategy(riskScore);
strategy.execute(); // 执行对应策略 UI / 流程
输出:
typescript
高风险用户: 密码 + MFA + KYC
⑤、企业级特性说明
- 风险评分驱动,策略动态可切换
- 策略独立,实现解耦,便于新增 MFA / KYC
- 前端执行策略只做 UI 控制,不做安全决策
- 可结合状态机驱动认证流程
- 可扩展为策略组合(低风险密码 + 行为认证 + MFA 等)
9、Token & 会话管理
Token & 会话管理是金融系统前端安全的核心中枢,通过短期 Access Token、长期 Refresh Token 和状态管理,实现安全、可控、可审计的用户会话,同时支持风控动态策略和多终端管理。
(1)、Token & 会话管理概念
Token & 会话管理是指:
- 在金融系统中,前端通过安全令牌(Token)和会话机制维护用户认证状态、授权状态及敏感操作控制,确保会话安全、可控、可审计,同时支持多设备、多终端和动态风控策略。
关键词:
- 安全令牌:访问 API / 业务操作的凭证
- 会话状态:前端感知和控制用户状态
- 多终端支持:手机端、Web 端、桌面端
- 风险可控:结合设备指纹、行为认证、风控策略
(2)、金融系统为什么必须重视 Token & 会话管理?
高价值账户:
- 金融账户信息和资金操作高度敏感
多通道访问:
- Web、App、微服务 API
多风险场景:
- 会话劫持(Session Hijacking)
- Token 泄露 / 重放攻击
- 并发登录控制
- 会话超时 / 风控冻结
合规要求:
- 必须可追溯操作历史
- 必须支持单点登出 / 多终端管理
- 必须支持 MFA / 风控触发的动态会话控制
(3)、核心概念
| 名称 | 功能 | 特点 |
|---|---|---|
| Access Token | 访问 API 的短生命周期令牌 | 短期有效,防泄露 |
| Refresh Token | 刷新 Access Token 的长期令牌 | 存储安全,支持续期 |
| 会话状态 | 前端持有的登录状态 | 结合 localStorage / cookie / memory |
| 会话策略 | 会话超时、并发限制 | 可动态调整,支持风控 |
| Token 绑定 | 绑定设备 / IP / MFA | 防止重放 / 劫持 |
(4)、Token & 会话管理策略(金融系统实践)
①、Access Token & Refresh Token 分层
- Access Token:短期有效(如 5~15 分钟),用于业务 API 调用
- Refresh Token:长期有效(如 7~30 天),可刷新 Access Token
原则:Access Token 在前端存内存或安全 HttpOnly Cookie;Refresh Token 高度保密,放后端或安全 HttpOnly Cookie
②、会话生命周期管理
| 场景 | 做法 |
|---|---|
| 超时 | 访问接口超过一定时间未操作 → 自动登出 |
| 异地登录 | 检测到新设备 / 高风险 IP → 可踢掉旧会话或 MFA |
| 风控触发 | 高风险操作 → 暂停会话 / 强制 MFA |
| 多终端 | 支持并发或限制单终端 |
③、Token 安全增强措施
- HTTPS 传输
- HttpOnly & Secure Cookie
- Token 签名(JWT / HMAC)
- Token 加密敏感字段(如用户ID、会话ID)
- Token 绑定设备指纹 / 风控评分
④、会话状态同步机制
- 前端维持状态机 / Redux / React Context
- Token 过期或刷新 → 自动更新状态
- 风控事件 → 更新会话状态(LOCKED / MFA_PENDING)
- 支持全局登出 / 单设备登出
(5)、一个简单但企业级前端实践示例
场景:Web 端登录 + Token & 会话管理
①、Token 类型定义
typescript
export interface AuthTokens {
accessToken: string;
refreshToken: string;
expiresAt: number; // Access Token 到期时间
}
②、前端会话管理类(企业级简化示例)
typescript
class SessionManager {
private tokens: AuthTokens | null = null;
private refreshTimer: number | null = null;
setTokens(tokens: AuthTokens) {
this.tokens = tokens;
localStorage.setItem('refreshToken', tokens.refreshToken);
this.scheduleRefresh();
}
getAccessToken(): string | null {
if (!this.tokens) return null;
if (Date.now() > this.tokens.expiresAt) {
return null; // Access Token 过期
}
return this.tokens.accessToken;
}
scheduleRefresh() {
if (!this.tokens) return;
if (this.refreshTimer) clearTimeout(this.refreshTimer);
const expiresIn = this.tokens.expiresAt - Date.now();
this.refreshTimer = window.setTimeout(() => this.refreshToken(), expiresIn - 3000); // 提前3秒刷新
}
async refreshToken() {
const refreshToken = localStorage.getItem('refreshToken');
if (!refreshToken) return this.clearSession();
try {
const res = await axios.post('/api/auth/refresh', { refreshToken });
this.setTokens(res.data); // 更新 Access Token
} catch (err) {
this.clearSession(); // 刷新失败 → 登出
}
}
clearSession() {
this.tokens = null;
localStorage.removeItem('refreshToken');
if (this.refreshTimer) clearTimeout(this.refreshTimer);
}
}
export const sessionManager = new SessionManager();
③、登录时使用示例
typescript
async function login(account: string, password: string) {
const res = await axios.post('/api/auth/login', { account, password });
sessionManager.setTokens(res.data.tokens);
}
④、API 调用示例(带 Token 自动刷新)
typescript
async function secureApiCall() {
let token = sessionManager.getAccessToken();
if (!token) {
await sessionManager.refreshToken();
token = sessionManager.getAccessToken();
if (!token) throw new Error('会话已过期');
}
return axios.get('/api/user/info', {
headers: { Authorization: `Bearer ${token}` }
});
}
⑤、企业级特性说明
- Access Token / Refresh Token 分层管理
- 自动刷新 & 过期处理
- 可扩展风控事件处理(LOCKED / MFA_PENDING)
- 多终端与单终端策略可结合状态机或策略模式
- 前端状态与 Token 完全解耦,支持审计与会话控制
10、防攻击技术(金融高频)
(1)、防攻击技术概念
金融系统 ≠ 普通互联网系统,攻击特征有明显差异:
-
攻击目标价值极高
- 账户资金
- 身份信息
- 授权 Token
- 接口额度
-
攻击是高频 + 自动化
- 暴力撞库(credential stuffing)
- 短信验证码轰炸
- 接口刷请求(薅羊毛 / 探测风控)
- Token 重放 / 会话劫持
- 业务逻辑绕过(不是漏洞,是流程被玩坏)
-
前端是第一攻击入口
- 90% 攻击都从前端进来,但90% 防御不该只靠前端
- 所以金融系统防攻击遵循一句话:
- 前端负责"阻断成本 + 风险信号采集",后端负责"裁决与封禁"。
(2)、金融系统防攻击的整体分层架构(文字版)
typescript
┌─────────────┐
│ 用户行为 │
└──────┬──────┘
↓
┌────────────────────┐
│ 前端防攻击层 │
│ - 表单安全 │
│ - 行为采集 │
│ - 设备指纹 │
│ - 限流与校验 │
└──────┬─────────────┘
↓
┌────────────────────┐
│ 风控 & 策略层 │
│ - 风险评分 │
│ - 攻击识别规则 │
│ - 策略模式 │
└──────┬─────────────┘
↓
┌────────────────────┐
│ 后端防护层 │
│ - 接口限流 │
│ - Token 校验 │
│ - 会话控制 │
│ - 封禁/降级 │
└────────────────────┘
这其中涉及的很多技术在本文上下文中已有详解,故不再赘述。
11、防调试 & 反篡改(进阶)
⚠️ 防调试 & 反篡改 ≠ 绝对安全
它的目标是:
- 提高逆向与攻击成本 + 延迟攻击 + 暴露攻击者行为
- 而不是"永远不被破解"。
(1)、金融系统为什么必须做「防调试 & 反篡改」
①、金融系统面临的真实威胁
- 浏览器 DevTools 调试
- Hook / 篡改 JS 变量、函数
- 注入脚本(Tampermonkey / 插件)
- 重放 / 构造请求
- 修改前端校验逻辑绕过风控
- 分析接口 & 业务流程(不是漏洞,是"逻辑被看穿")
②、防调试 & 反篡改在整体安全体系中的位置
typescript
用户
↓
前端(防调试 / 反篡改)
↓
行为 & 设备信号采集
↓
风控 / 策略 / 状态机
↓
后端裁决(真正安全)
前端防护是"延缓 + 暴露",不是最终防线
(2)、防调试 & 反篡改的核心目标(金融级)
| 目标 | 说明 |
|---|---|
| 提高攻击成本 | 让攻击者花更多时间 |
| 干扰逆向分析 | 隐藏关键逻辑 |
| 检测异常环境 | DevTools / Hook |
| 上报风险信号 | 给风控系统 |
| 联动策略 | 触发验证码 / MFA / 封禁 |
(3)、金融系统防调试 & 反篡改的技术拆解(前端重点)
①、防调试(Anti-Debugging)
DevTools 检测(最基础)
常见信号:
- debugger 执行异常
- console 被打开
- window.outerWidth - innerWidth 异常
- 执行时间异常(断点暂停)
⚠️ 注意:不要"直接阻断业务",而是上报风险
调试干扰(反分析)
- 动态插入 debugger
- 定时函数检测执行延迟
- 递归 / 闭包混淆执行路径
②、反篡改(Anti-Tampering)
关键函数完整性校验
- 检测函数是否被重写
- 检测 toString() 是否被污染
关键变量防篡改
- 使用闭包隐藏状态
- Object.freeze / seal
- 关键数据只读
运行时一致性校验
- 同一逻辑多路径计算
- 校验结果不一致 → 风险信号
③、代码层保护(不是"安全",是"门槛")
| 技术 | 作用 |
|---|---|
| 混淆 | 提高阅读难度 |
| 变量重命名 | 降低可读性 |
| 控制流平坦化 | 干扰逆向 |
| 动态加载 | 隐藏关键模块 |
④、与风控体系联动(非常关键)
typescript
检测到调试 / 篡改
→ 上报 risk signal
→ 风控评分上升
→ 策略模式升级
→ MFA / 验证码 / 阻断
(4)、金融系统防调试 & 反篡改设计原则(非常重要)
❌ 错误做法:
- 在前端"自以为安全"
- 检测到调试直接 alert / 崩溃
- 把所有安全逻辑放前端
- 影响正常用户(误伤)
✅ 正确做法:
- 静默检测
- 多信号组合
- 只上报,不裁决
- 和风控 / 状态机 / 策略模式联动
(5)、一个「简单但企业级」的前端实践示例
场景:登录 / 资金操作前的防调试 & 反篡改检测
①、DevTools 打开检测(简化版)
typescript
function detectDevTools(): boolean {
const start = Date.now();
debugger;
return Date.now() - start > 100;
}
②、函数完整性检测
typescript
function isFunctionTampered(fn: Function): boolean {
return !/\[native code\]/.test(fn.toString());
}
③、关键状态防篡改(闭包)
typescript
const createSecureState = () => {
let token: string | null = null;
return {
set(v: string) {
token = v;
},
get() {
return token;
}
};
};
const secureToken = createSecureState();
④、风险信号采集与上报
typescript
function collectAntiTamperSignals() {
return {
devtoolsOpen: detectDevTools(),
consoleTampered: isFunctionTampered(console.log),
timestamp: Date.now()
};
}
async function reportRisk(signal: any) {
await fetch('/api/risk/report', {
method: 'POST',
body: JSON.stringify(signal)
});
}
⑤、在关键操作前调用
typescript
async function beforeSensitiveAction() {
const signals = collectAntiTamperSignals();
if (signals.devtoolsOpen || signals.consoleTampered) {
reportRisk(signals);
}
// 继续正常流程(是否阻断由后端决定)
}
⑥、企业级实践补充
防调试 & 反篡改不是为了"不可破解",而是通过前端多层检测与干扰,把攻击行为暴露给风控系统,并在成本、时间和成功率上全面压制攻击。
- 防调试逻辑 分散在多个模块
- 同一检测 多实现
- 检测逻辑 定期变更
- 与 设备指纹、行为认证 联合评分
- 风控侧可动态下发策略(开/关某些检测)
12、审计与合规技术
(1)、审计与合规技术概念
审计与合规技术是指:
- 对用户行为、系统决策、风险处置、权限使用等全过程进行可追溯、可还原、可解释、可证明的技术体系,用于满足监管、内控、仲裁与风险复盘要求。
关键词不是"日志",而是:
- 可追溯
- 可还原
- 可解释
- 不可抵赖
为什么金融系统"必须"重审计?
金融系统面对的是:
- 监管机构(央行 / 证监会 / 银保监)
- 内控 / 风险委员会
- 仲裁 / 法务
- 安全事件调查
一句话总结:功能可以下线,审计不能丢。
(2)、金融系统审计与合规的整体技术架构(文字版)
typescript
用户操作
↓
前端审计采集层
(行为、环境、设备、流程)
↓
认证 / 风控 / 策略 / 状态机
↓
后端审计中台
(事件归档 / 关联 / 固化)
↓
审计存储 & 合规系统
(不可篡改 / 可回放)
(3)、金融系统审计的"五大核心维度"(非常关键)
①、用户行为审计(Who & What)
- 记录什么?
- 用户是谁(userId / accountId)
- 做了什么操作(login / transfer / changePassword)
- 操作结果(成功 / 失败 / 拒绝)
这是最基础,但远远不够
②、时间 & 顺序审计(When & Order)
- 精确时间戳(毫秒级)
- 操作顺序
- 是否有重试
- 是否超时
用于还原完整时间线
③、环境与设备审计(Where & With What)
- IP / 地区
- 设备指纹
- 浏览器 / OS
- 是否调试 / 篡改环境
用于判断是否存在攻击 / 冒用
④、决策与策略审计(Why)
金融系统最容易被忽视,但监管最关心的一点:
- ❗ "为什么允许 / 拒绝这次操作?"
必须能回答:
- 当时的风险评分是多少?
- 触发了哪些规则?
- 使用了哪条策略?
- 是否要求 MFA / KYC?
- 是否人为干预?
⑤、结果与责任审计(Outcome)
- 操作最终结果
- 哪个系统 / 哪个策略做的决定
- 是否可复现
(4)、前端在审计与合规中扮演什么角色?
❌ 一个非常重要的认知纠正:
- 审计是后端的事,前端不用管
✅ 正确理解:
- 前端是"事实发生地",是审计第一现场
- 前端必须参与审计的原因:
- 行为发生在前端
- 风险信号(调试 / 行为 / 设备)只在前端可见
- 用户真实操作路径前端最清楚
(5)、金融前端常见的审计采集内容
| 类别 | 示例 |
|---|---|
| 行为 | 点击、输入、提交、取消 |
| 流程 | 当前认证状态、步骤 |
| 风控 | 风险评分、命中规则 |
| 策略 | 使用的认证策略 |
| 环境 | 设备ID、浏览器、IP |
| 安全 | 是否调试、是否异常 |
⚠️ 注意:前端只采集 & 上报,不负责"定罪"。
(6)、审计数据的几个金融级技术要求
-
不可抵赖
- 每个事件有唯一 ID
- 事件与会话 / Token 绑定
- 时间不可伪造(后端校准)
-
不可篡改
- 前端不上"最终日志"
- 后端写入 只增不改
- 可用链式 hash / WORM 存储
-
可关联
typescript
一次转账
= 多个前端事件
+ 多个风控决策
+ 多个系统响应
必须能串成一条链
- 可回放 / 可解释
- 还原用户当时看到的流程
- 还原系统当时的判断依据
(7)、一个「简单但企业级」的审计实践示例
场景:登录 + MFA 的审计采集(前端)
①、定义统一审计事件结构
typescript
interface AuditEvent {
eventId: string;
eventType: string;
userId?: string;
sessionId: string;
timestamp: number;
data: Record<string, any>;
}
②、前端审计事件生成
typescript
function createAuditEvent(
type: string,
data: Record<string, any>
): AuditEvent {
return {
eventId: crypto.randomUUID(),
eventType: type,
sessionId: getSessionId(),
timestamp: Date.now(),
data
};
}
③、登录过程审计示例
typescript
// 用户提交登录
reportAudit(
createAuditEvent('LOGIN_SUBMIT', {
deviceId: getDeviceId(),
behaviorScore: getBehaviorScore()
})
);
// 登录成功
reportAudit(
createAuditEvent('LOGIN_SUCCESS', {
riskScore: 32,
strategy: 'PASSWORD+MFA'
})
);
// MFA 通过
reportAudit(
createAuditEvent('MFA_SUCCESS', {
mfaType: 'TOTP'
})
);
④、审计上报(异步、低干扰)
typescript
function reportAudit(event: AuditEvent) {
navigator.sendBeacon(
'/api/audit/collect',
JSON.stringify(event)
);
}
- 不阻塞主流程
- 页面关闭也能发
- 金融系统常用做法
⑤、企业级进阶做法(你在大厂一定会见到)
- 审计事件 分级
- 普通操作
- 敏感操作
- 风控决策
- 审计与 状态机 / 策略模式强绑定
- 审计 ID 贯穿全链路(前端 → 风控 → 后端)
- 支持 审计回放 UI
- 审计系统与业务系统完全解耦
六、常见前端「认证」方式
| 类型 | 前端涉及特点 | 金融行业特点 |
|---|---|---|
| 账号+密码 | 表单输入、密码加密传输 | 密码复杂度、加密传输、登录尝试限制 |
| 短信/邮件验证码 | 前端需要倒计时、输入校验、请求防刷 | 短信验证码防刷、防攻击 |
| 图形验证码 | 前端渲染验证码、验证输入 | 防止脚本自动化攻击 |
| 动态令牌(TOTP) | 前端可展示二维码、输入六位数 | 多因子认证(MFA) |
| 人脸/指纹/声纹 | 前端 SDK 或浏览器 API 调用 | 银行业尤其重视生物认证 |
| 身份证+活体检测 | 前端需采集身份证信息、拍摄照片或视频 | 金融合规要求(KYC) |
接下来深入研究下这些「多因子认证(MFA)」方式:
- 如何做「账号+密码」认证?
- 如何做「短信/邮件验证码」认证?
- 如何做「图形验证码」认证?
- 如何做「动态令牌(TOTP)」认证?
- 如何做「人脸/指纹/声纹」认证?
- 如何做「身份证 + 活体检测」认证?
1、如何做「账号+密码」认证?
(1)、认清"账号+密码"认证
金融系统的"账号 + 密码"认证,本质是:
- 一套围绕"身份可信度"的安全协议体系,而不是一个登录表单。
在金融系统中:
- "账号 + 密码"只是第一道门,而不是全部安全性来源
(2)、金融系统「账号」的设计原则
账号 ≠ 用户名
金融系统中的账号通常具备:
- 唯一性(不可复用)
- 可冻结 / 可注销
- 可关联多身份
常见账号类型:
| 类型 | 示例 |
|---|---|
| 登录账号 | 手机号 / 客户号 |
| 内部主键 | user_id |
| 外部标识 | 证件号(不直接用于登录) |
❗ 前端原则:登录只用"最小暴露账号",不要展示真实内部标识
(3)、金融系统「密码」的真实安全模型
密码 ≠ "字符串"
金融系统中,一个密码至少经历:
typescript
用户输入
→ 前端加密
→ 网络传输
→ 后端加盐哈希
→ 安全存储
前端为什么必须处理密码安全?
很多人误以为:"HTTPS 已经足够了"
- 金融系统答案:不够!推荐使用 「HTTPS + 前端加密」处理。
前端必须做的 3 件事:
- 防明文抓取
- 防中间人降级攻击
- 降低终端泄露风险
📌 所以金融系统普遍做:
- 前端 RSA / SM2 加密
- 后端 BCrypt / PBKDF2
(4)、金融级「账号 + 密码」认证流程(核心)
标准流程(简化):
- 输入账号 + 密码
- 前端加密密码
- 后端校验账号状态
- 校验密码哈希
- 风控评估(IP / 设备 / 行为)
- 返回认证结果 or MFA 升级
(5)、金融系统必须额外叠加的安全策略
①、登录失败策略(极其重要)
| 策略 | 金融要求 |
|---|---|
| 错误次数限制 | 必须 |
| 冷却时间 | 必须 |
| 账号冻结 | 必须 |
| 风险告警 | 必须 |
②、设备 & 环境校验(前端强相关)
前端参与的风控信号包括:
- UA
- 设备指纹
- 分辨率
- 时区
- 浏览器特征
③、登录成功 ≠ 认证完成
金融系统中:
- 账号 + 密码 通过 ≠ 最终登录成功
可能触发:
- 短信 OTP
- 动态口令
- 人脸识别
(6)、前端「账号+密码」认证典例(企业级)
技术栈:采用 React + TypeScript 。
目标:前端加密
①、密码加密工具:
typescript
// utils/encrypt.ts
import JSEncrypt from 'jsencrypt';
const PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...
-----END PUBLIC KEY-----`;
export function encryptPassword(password: string): string {
const encryptor = new JSEncrypt();
encryptor.setPublicKey(PUBLIC_KEY);
return encryptor.encrypt(password) || '';
}
②、登录请求封装
typescript
// services/auth.ts
import axios from 'axios';
import { encryptPassword } from '../utils/encrypt';
export async function login(
account: string,
password: string
) {
return axios.post('/api/auth/login', {
account,
password: encryptPassword(password)
});
}
③、登录组件(简化版)
typescript
// pages/Login.tsx
import { useState } from 'react';
import { login } from '../services/auth';
export function Login() {
const [account, setAccount] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = async () => {
try {
const res = await login(account, password);
if (res.data.needMfa) {
// 跳转 MFA
window.location.href = '/mfa';
return;
}
// 登录成功
window.location.href = '/dashboard';
} catch (e) {
alert('账号或密码错误');
}
};
return (
<>
<input
value={account}
onChange={e => setAccount(e.target.value)}
placeholder="账号"
/>
<input
type="password"
value={password}
onChange={e => setPassword(e.target.value)}
placeholder="密码"
/>
<button onClick={handleSubmit}>登录</button>
</>
);
}
这个例子为什么是「企业级」?
因为它已经满足金融系统的最低合规线:
- 密码不明文传输
- 登录流程可中断(支持 MFA)
- 不暴露内部账号结构
- 登录逻辑可接风控引擎
- 可扩展为多因子认证
2、如何做「短信/邮件验证码」认证?
(1)、认清"短信/邮件验证码"认证
短信 / 邮件验证码在金融系统中,本质是:
- 一个"短生命周期的一次性持有因子(OTP)",用于补强身份可信度,而不是替代密码。
金融系统里验证码的「真实定位」:
| 系统类型 | 验证码定位 |
|---|---|
| 普通系统 | 主认证方式 |
| 金融系统 | 辅助认证 / 二次确认 / 风控补强 |
在金融系统中,验证码通常只用于:
- 登录后的二次校验
- 高风险操作确认
- 账号找回 / 解锁
- 首次设备 / 异地登录
很少用于:
- 单因子直接登录(除非低风险场景)
(2)、金融级验证码的核心安全要求
验证码不是"6 位数字"那么简单
金融系统中的验证码,必须具备:
| 属性 | 金融要求 |
|---|---|
| 一次性 | 用完即失效 |
| 短时效 | 30s ~ 120s |
| 强绑定 | 账号 + 场景 |
| 可追溯 | 可审计 |
| 可限流 | 防撞库 |
验证码必须绑定「业务场景」:
❌ 错误做法:
- "给你发个验证码,什么都能用"
✅ 金融正确做法:
typescript
login_sms
change_password
transfer_confirm
unbind_device
每个场景 验证码互不通用。
金融系统的验证码生命周期:
typescript
请求发送
→ 风控评估
→ 生成 OTP
→ 下发(SMS / Email)
→ 用户输入
→ 校验
→ 立即失效
(3)、前端在验证码认证中的真实职责
前端不是"展示输入框",而是验证码安全链条的一环
前端必须承担:
- 发送前校验(防刷)
- 倒计时控制
- 重发限制
- 场景绑定
- 错误态引导
- MFA 状态衔接
(4)、短信 vs 邮件验证码(金融视角对比)
| 维度 | 短信 | 邮件 |
|---|---|---|
| 到达速度 | 快 | 中 |
| 安全性 | 中 | 中 |
| 劫持风险 | SIM 劫持 | 邮箱被盗 |
| 使用频率 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 金融现状 | 正在降级 | 作为补充 |
📌 最佳实践
- 短信 + 邮件 并行兜底,但不并行校验
(5)、金融系统中验证码的典型使用模式
①、登录流程(MFA)
typescript
账号 + 密码
→ 风控评估
→ 需要验证码
→ SMS / Email OTP
→ 登录完成
②、高危操作确认(核心)
typescript
发起转账
→ 校验交易密码
→ 下发验证码
→ OTP 校验
→ 执行交易
(6)、前端「短信/邮件验证码」认证典例(企业级)
技术栈:React + TypeScript
目标:登录后的短信验证码校验(金融最常见)
①、接口约定(金融常见)
发送验证码:
typescript
POST /api/auth/otp/send
typescript
{
"scene": "login_sms",
"receiver": "138****8888"
}
校验验证码:
typescript
POST /api/auth/otp/verify
typescript
{
"scene": "login_sms",
"code": "839204"
}
②、前端服务封装
typescript
// services/otp.ts
import axios from 'axios';
export function sendOtp(scene: string) {
return axios.post('/api/auth/otp/send', { scene });
}
export function verifyOtp(scene: string, code: string) {
return axios.post('/api/auth/otp/verify', { scene, code });
}
③、验证码组件(金融级关键点)
typescript
// components/OtpInput.tsx
import { useEffect, useState } from 'react';
import { sendOtp, verifyOtp } from '../services/otp';
export function OtpInput({ scene, onSuccess }: any) {
const [code, setCode] = useState('');
const [countdown, setCountdown] = useState(0);
const handleSend = async () => {
await sendOtp(scene);
setCountdown(60);
};
useEffect(() => {
if (countdown <= 0) return;
const timer = setInterval(() => {
setCountdown(c => c - 1);
}, 1000);
return () => clearInterval(timer);
}, [countdown]);
const handleVerify = async () => {
await verifyOtp(scene, code);
onSuccess();
};
return (
<>
<input
value={code}
onChange={e => setCode(e.target.value)}
placeholder="输入验证码"
/>
<button onClick={handleVerify}>确认</button>
<button onClick={handleSend} disabled={countdown > 0}>
{countdown > 0 ? `${countdown}s 后重发` : '发送验证码'}
</button>
</>
);
}
为什么这个例子是「企业级」?
它已经具备金融系统最低标准能力:
- 场景绑定(scene)
- 防重复发送(倒计时)
- 可接风控(send 前)
- 一次性校验
- 可嵌入 MFA 流程
3、如何做「图形验证码」认证?
(1)、认清"图形验证码"认证
图形验证码在金融系统中的本质是:
- 一种「人机区分 + 攻击阻断」机制,而不是身份认证本身。
它不证明你是谁,只证明:
- "你大概率是人,而不是自动化攻击程序"
为什么不能一上来就发短信验证码?
金融系统绝不会这么做,原因:
- 短信有成本
- 会被刷爆
- 会被利用做短信轰炸
- 会成为攻击通道
金融系统面对的不是"误操作",而是有组织攻击:
| 攻击类型 | 目的 |
|---|---|
| 撞库 | 批量试账号密码 |
| 爆破 | 穷举验证码 / 密码 |
| 爬虫 | 获取账户状态 |
| 脚本登录 | 绕过登录限制 |
图形验证码 = 所有"可触发外部资源"的前置门槛
(2)、图形验证码在金融认证体系中的位置
标准金融认证链路(简化):
typescript
访问登录页
→ 图形验证码(人机校验)
→ 账号 + 密码
→ 风控评估
→ 短信 / MFA
→ 登录完成
❗ 重点:
- 图形验证码一定在"最前面"
- 它是防护体系,不是认证体系
(3)、金融系统对图形验证码的核心要求
安全要求(必须满足):
| 要求 | 说明 |
|---|---|
| 一次性 | 用完立即失效 |
| 短生命周期 | 通常 < 2 分钟 |
| 强绑定 | session / requestId |
| 不可预测 | 随机生成 |
| 防重放 | 不可重复使用 |
体验要求(金融同样重要):
- 不能太复杂(防用户流失)
- 支持刷新
- 支持无障碍 / 兜底
- 支持多种类型切换
(4)、金融系统中常见的图形验证码类型
①、传统字符型(仍然存在)
typescript
A 7 K 9 Z
用途:
- 后台管理系统
- 内部系统
- 风险不高场景
②、点击型 / 行为型(主流)
| 类型 | 示例 |
|---|---|
| 点击文字 | "请点击所有'猫'" |
| 顺序点击 | "按顺序点数字" |
| 拖动拼图 | 滑块拼图 |
✅ 金融前端主流选择
③、无感验证码(风控驱动)
- 行为轨迹
- 鼠标路径
- 访问节奏
通常作为第一层隐形校验
(5)、前端视角:图形验证码的真实职责
前端不是"展示图片",而是风控参与者
前端必须:
- 正确拉取验证码 challenge
- 携带校验凭证提交
- 支持失败重试
- 支持类型升级 / 降级
- 不缓存、不复用
(6)、前端「图形验证码」认证典例(企业级)
场景:登录前的人机校验(最典型)
技术栈:React + TypeScript
类型:图片字符验证码(便于理解)
①、接口约定(金融常见)
获取验证码:
typescript
GET /api/captcha/image
typescript
{
"captchaId": "cpt_8f29a",
"imageBase64": "data:image/png;base64,iVBORw0KGgo..."
}
登录时校验验证码:
typescript
{
"account": "user001",
"password": "ENCRYPTED",
"captchaId": "cpt_8f29a",
"captchaCode": "A7K9Z"
}
②、前端服务封装
typescript
// services/captcha.ts
import axios from 'axios';
export function getCaptcha() {
return axios.get('/api/captcha/image');
}
③、图形验证码组件(企业级最小实现)
typescript
// components/Captcha.tsx
import { useEffect, useState } from 'react';
import { getCaptcha } from '../services/captcha';
export function Captcha({ onChange }: any) {
const [img, setImg] = useState('');
const [captchaId, setCaptchaId] = useState('');
const [code, setCode] = useState('');
const loadCaptcha = async () => {
const res = await getCaptcha();
setImg(res.data.imageBase64);
setCaptchaId(res.data.captchaId);
setCode('');
onChange('', res.data.captchaId);
};
useEffect(() => {
loadCaptcha();
}, []);
const handleInput = (v: string) => {
setCode(v);
onChange(v, captchaId);
};
return (
<div>
<img
src={img}
alt="captcha"
onClick={loadCaptcha}
style={{ cursor: 'pointer' }}
/>
<input
value={code}
onChange={e => handleInput(e.target.value)}
placeholder="请输入验证码"
/>
</div>
);
}
④、登录页集成(关键)
typescript
// pages/Login.tsx
const [captchaCode, setCaptchaCode] = useState('');
const [captchaId, setCaptchaId] = useState('');
<Captcha
onChange={(code: string, id: string) => {
setCaptchaCode(code);
setCaptchaId(id);
}}
/>
<button
onClick={() =>
login({
account,
password,
captchaId,
captchaCode
})
}
>
登录
</button>
这个例子为什么是「企业级」?
因为它已经满足金融系统的最低合规线:
- 验证码一次一取
- 强绑定 captchaId
- 支持刷新
- 登录强依赖验证码
- 可接入风控升级
4、如何做「动态令牌(TOTP)」认证?
(1)、认清"动态令牌(TOTP)"认证
TOTP = 一种"基于时间同步的动态一次性密码",属于「持有因子(Possession)」
它保证:
- 用户在物理设备上生成 OTP
- 每次密码有效期极短(通常 30 秒)
- 后端通过共享密钥验证一次性密码
❗️核心优势:防止重放、防撞库、抗中间人
(2)、TOTP 的典型场景(金融系统)
| 场景 | 描述 |
|---|---|
| 登录 MFA | 密码 + TOTP |
| 高额转账 | TOTP + 交易密码 |
| 账户敏感修改 | TOTP + 图形验证码 |
| 设备绑定确认 | TOTP + 设备校验 |
(3)、TOTP 的原理(金融视角重点)
算法基础:
- TOTP 基于 HMAC-SHA1
- 输入:secretKey + 当前时间片(Unix timestamp / 30s)
- 输出:6~8 位一次性密码
特性:
- 短时效(通常 30s)
- 不可预测
- 与设备绑定
安全优势:
- 攻击者无法凭账号/密码生成 OTP
- 即使截获一次 OTP,也过期失效
- 支持脱机生成(用户 App / 硬件 Token)
(4)、金融系统 TOTP 的前端职责
前端并不生成 OTP,而是承载"用户输入 + 验证接口调用 + 风控接入"
主要职责:
- 显示绑定二维码 / secretKey(首次启用 TOTP)
- 采集用户输入的 OTP
- 调用后端校验接口
- 处理失败 / 过期 / 重试
- 触发风控策略(连续失败、异常设备)
(5)、金融系统 TOTP 的完整流程
- 用户选择绑定 TOTP
- 后端生成 secretKey
- 前端展示二维码(Google Authenticator / App 扫码)
- 用户在 App 或 Token 生成 OTP
- 用户输入 OTP 到前端
- 前端提交后端校验
- 校验成功后完成绑定
- 登录或敏感操作时使用 OTP 校验
关键点:前端全程不保存 secretKey
- secretKey 一旦泄露,TOTP 安全性丧失
(6)、金融级最佳实践
| 要点 | 金融实践 |
|---|---|
| OTP 位数 | 6~8 位,30 秒有效期 |
| 首次绑定 | 需双重验证(密码 + OTP 或密码 + 图形验证码) |
| 尝试次数限制 | 3~5 次失败立即冻结或提示 |
| 绑定设备 | 可选择白名单 |
| 异地登录 | 必须重新校验 OTP |
| 安全传输 | HTTPS + 防重放 token |
(7)、前端「动态令牌(TOTP)」认证典例(企业级)
技术栈:React + TypeScript
场景:登录二因子认证 / 首次绑定二维码展示
①、接口约定(金融实践)
获取绑定 QRCode(二维码):
typescript
GET /api/mfa/totp/setup
返回:
typescript
{
"secret": "JBSWY3DPEHPK3PXP",
"qrCodeUrl": "otpauth://totp/BankApp:user001?secret=JBSWY3DPEHPK3PXP&issuer=BankApp"
}
验证 OTP(一次性密码):
typescript
POST /api/mfa/totp/verify
请求:
typescript
{
"otpCode": "123456"
}
返回:
typescript
{
"success": true
}
②、前端展示二维码示例
typescript
// components/TotpSetup.tsx
import { useEffect, useState } from 'react';
import axios from 'axios';
import QRCode from 'qrcode.react';
export function TotpSetup({ onVerifySuccess }: any) {
const [qrUrl, setQrUrl] = useState('');
const [otp, setOtp] = useState('');
useEffect(() => {
const fetchQr = async () => {
const res = await axios.get('/api/mfa/totp/setup');
setQrUrl(res.data.qrCodeUrl);
};
fetchQr();
}, []);
const handleVerify = async () => {
const res = await axios.post('/api/mfa/totp/verify', { otpCode: otp });
if (res.data.success) onVerifySuccess();
else alert('OTP 校验失败,请重试');
};
return (
<div>
<h3>请用 Google Authenticator 扫描二维码绑定 TOTP</h3>
<QRCode value={qrUrl} />
<input
value={otp}
onChange={e => setOtp(e.target.value)}
placeholder="请输入 6 位 OTP"
/>
<button onClick={handleVerify}>确认绑定</button>
</div>
);
}
③、登录使用 OTP 示例
typescript
// pages/LoginOtp.tsx
import { useState } from 'react';
import axios from 'axios';
export function LoginOtp({ onSuccess }: any) {
const [otp, setOtp] = useState('');
const handleLoginOtp = async () => {
const res = await axios.post('/api/mfa/totp/verify', { otpCode: otp });
if (res.data.success) onSuccess();
else alert('OTP 错误或过期');
};
return (
<div>
<input
value={otp}
onChange={e => setOtp(e.target.value)}
placeholder="请输入 TOTP"
/>
<button onClick={handleLoginOtp}>登录</button>
</div>
);
}
这个例子为什么是「企业级」?
因为它已经满足金融系统的最低合规线:
- 支持首次绑定二维码
- 前端不存 secretKey
- OTP 一次性,过期即失效
- 可接入风控策略(连续失败冻结)
- 可扩展到登录 MFA / 高风险操作
5、如何做「人脸/指纹/声纹」认证?
(1)、认清"人脸/指纹/声纹"认证
生物识别认证(Biometric Authentication) = 使用用户的生物特征(身体或行为特征)进行身份验证的技术手段
在金融系统中属于 "Inherence 因子"(MFA 三大类之一),常用于:
- 高风险操作(转账、提现、修改绑定)
- 登录 MFA(尤其移动端)
- 首次设备绑定或 KYC(Know Your Customer,身份核验)
核心特点:
| 特性 | 金融实践说明 |
|---|---|
| 唯一性 | 指纹/人脸/声纹基本唯一 |
| 高安全性 | 不易被窃取或重放 |
| 用户体验好 | 移动端可快速完成 |
| 需活体检测 | 防照片、录音、深度伪造攻击 |
(2)、三类生物识别详细解析
①、指纹识别(Fingerprint)
| 适用场景 | 技术实现 | 金融实践注意点 |
|---|---|---|
| App 登录 | 手机内置指纹模块(iOS TouchID / Android Fingerprint) | 手机端 SDK 调用;后台不保存原始指纹,只保存 hash/模板 |
| 高风险操作确认 | 转账 / 提现 | 配合交易密码或 TOTP 形成 MFA |
⚠️ 注意:前端仅采集设备认证结果(是否通过),不处理原始指纹数据。
②、人脸识别(Face Recognition)
| 适用场景 | 技术实现 | 金融实践注意点 |
|---|---|---|
| 登录 | 手机/PC摄像头 | 活体检测(眨眼/微表情/红外) |
| 高风险操作确认 | 提现、大额转账 | 与用户照片模板比对;后端存模板 hash |
| KYC / 远程开户 | 银行开户、金融App注册 | 符合监管要求,防深度伪造(deepfake) |
⚠️ 注意:前端只负责采集图片或视频流 + 活体检测,敏感比对在后端完成。
③、声纹识别(Voice Recognition)
| 适用场景 | 技术实现 | 金融实践注意点 |
|---|---|---|
| 电话银行身份核验 | 用户语音输入指定短语 | 前端采集语音流,发送至后端比对模板 |
| 客服验证 | 高频操作 | 活体检测(防录音重放) |
⚠️ 前端采集 + 简单降噪处理,复杂比对完全由后端完成。
(3)、金融系统生物认证流程(以移动端为例)
- 用户选择生物识别绑定(首次使用)
- 前端调用系统/SDK采集生物特征
- SDK 返回验证成功结果 + 安全 token
- 前端将 token 提交后端
- 后端校验 token 与风控策略
- 绑定完成
- 日常登录或敏感操作时可直接触发生物认证
❗️ 核心思想:前端不存储生物数据,只承担采集和验证触发
(4)、金融级前端注意事项
| 关键点 | 金融实践 |
|---|---|
| 原始数据不存储 | 只传设备/SDK生成的安全 token |
| 活体检测 | 必须;防照片、视频、录音攻击 |
| 多因子组合 | 必须与密码/OTP/设备绑定组合使用 |
| 失败策略 | 多次失败 -> MFA 升级 / 风控冻结 |
| 隐私合规 | GDPR/中国金融监管要求,敏感数据严格加密 |
(5)、前端「生物」认证典例(企业级)
场景:移动端人脸/指纹认证登录
①、接口约定
触发生物认证:
typescript
POST /api/mfa/biometric/auth
请求体(前端只发送安全 token,不传原始数据):
typescript
{
"biometricType": "face", // fingerprint / voice
"deviceToken": "device123",
"authResultToken": "sdk-generated-token"
}
返回:
typescript
{
"success": true
}
②、前端组件示例
typescript
// components/BiometricLogin.tsx
import { useState } from 'react';
import axios from 'axios';
declare const window: any; // 假设移动端 SDK 暴露在 window 对象
export function BiometricLogin({ onSuccess }: any) {
const [error, setError] = useState('');
const handleBiometric = async (type: 'face' | 'fingerprint') => {
try {
// 调用移动端 SDK / 原生能力
const authResultToken = await window.BiometricSDK.authenticate(type);
const res = await axios.post('/api/mfa/biometric/auth', {
biometricType: type,
deviceToken: 'device123',
authResultToken
});
if (res.data.success) onSuccess();
else setError('认证失败,请重试');
} catch (e: any) {
setError(e.message || '认证异常');
}
};
return (
<div>
<button onClick={() => handleBiometric('face')}>人脸认证</button>
<button onClick={() => handleBiometric('fingerprint')}>指纹认证</button>
{error && <p style={{ color: 'red' }}>{error}</p>}
</div>
);
}
这个例子为什么是「企业级」?
因为它已经满足金融系统的最低合规线:
- 前端不存生物数据,仅采集 SDK token:
- 支持多种生物因子(可扩展)
- 可与账号/密码、TOTP、短信 OTP 组合
- 支持失败策略 + 风控升级
- 可直接嵌入 MFA / 高风险操作流程
6、如何做「身份证 + 活体检测」认证?
「身份证 + 活体检测」≠ 完整 KYC:
- 它是的"身份核验阶段",而不是全部。
- 是 KYC 最核心、等级最高的一类采集(Strong KYC / eKYC)。
(1)、认清"身份证 + 活体检测"认证
「身份证 + 活体检测」不是登录手段,
而是金融系统"确认你是合法自然人"的终极武器。
「身份证 + 活体检测」认证 = 对"你是否是真实存在的、与证件一致的自然人"的远程强认证机制
它解决的不是"你有没有账号",而是:
- 你是不是这个人
- 这个人是不是活的
- 是不是在此时此刻操作
❗️ 这是 KYC(Know Your Customer) 的核心环节。
(2)、为什么金融系统必须做这一步?
✅ 这是"合规底线",不是产品选择(不做 = 违规)。
法定以下业务必须做实名认证:
| 业务 | 是否强制 |
|---|---|
| 银行开户 | ✅ |
| 券商开户 | ✅ |
| 支付账户升级 | ✅ |
| 提现 / 大额转账 | ✅ |
| 信贷 / 放款 | ✅ |
(3)、认证的核心拆解(金融视角)
认证必须同时满足 3 件事:
- 证件是真实的
- 证件属于这个人
- 操作的人是活体本人
对应三层校验:
| 层级 | 校验内容 |
|---|---|
| 身份证 OCR | 姓名 / 证号 |
| 人证比对 | 证件照 vs 当前人脸 |
| 活体检测 | 防照片 / 视频 / AI |
(4)、活体检测为什么是"关键中的关键"
没有活体检测会发生什么?
- 打印身份证照片
- 播放自拍视频
- AI 换脸
- 视频通话翻拍
❗️ 没有活体 = 100% 会被绕过
常见活体检测方式(金融真实使用):
| 类型 | 示例 |
|---|---|
| 动作活体 | 眨眼 / 摇头 / 张嘴 |
| 随机指令 | "向左看""读数字" |
| 光照活体 | 反射变化 |
| 行为活体 | 微表情、轨迹 |
金融系统通常 组合使用 ≥ 2 种
(5)、前端在「身份证 + 活体检测」中的真实职责
前端不是"拍照工具",而是"采集 + 约束 + 防作弊入口"
前端必须承担:
- 摄像头权限管理
- 拍照 / 视频流采集
- 动作引导(活体)
- 数据加密上传
- 流程状态控制
- 失败重试 & 升级
❗ 前端不做任何"身份判断"
(6)、金融系统完整认证流程(标准)
typescript
进入实名认证
→ OCR 证件(正反面)
→ 证件信息结构化
→ 进入活体检测
→ 采集视频 / 图片
→ 提交后端
→ 第三方/自研引擎校验
→ 返回结果
→ 通过 / 拒绝 / 人工复核
(7)、金融级关键设计原则(非常重要)
| 原则 | 说明 |
|---|---|
| 异步 | 可能进入人工审核 |
| 不可复用 | 每次认证一次性 |
| 强审计 | 可追溯、可回放 |
| 可中断 | 支持失败重试 |
| 合规提示 | 明确隐私授权 |
(8)、前端「身份证 + 活体检测」认证典例(企业级)
目标:远程实名认证(Web / App 通用思想)
技术栈:React + TypeScript
说明:简化版,不绑定具体厂商 SDK
①、接口约定(金融常见)
创建实名认证任务:
typescript
POST /api/ekyc/session
返回:
typescript
{
"sessionId": "ekyc_9823",
"livenessActions": ["blink", "turn_head"]
}
提交认证数据:
typescript
POST /api/ekyc/submit
typescript
{
"sessionId": "ekyc_9823",
"idCardFront": "base64",
"idCardBack": "base64",
"livenessVideo": "base64"
}
②、前端采集核心逻辑(示意)
摄像头采集工具:
typescript
// utils/camera.ts
export async function captureImage(): Promise<string> {
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
const video = document.createElement('video');
video.srcObject = stream;
await video.play();
const canvas = document.createElement('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext('2d')!.drawImage(video, 0, 0);
stream.getTracks().forEach(t => t.stop());
return canvas.toDataURL('image/jpeg');
}
简化实名认证组件:
typescript
// pages/Ekyc.tsx
import { useState } from 'react';
import axios from 'axios';
import { captureImage } from '../utils/camera';
export function Ekyc() {
const [sessionId, setSessionId] = useState('');
const start = async () => {
const res = await axios.post('/api/ekyc/session');
setSessionId(res.data.sessionId);
};
const submit = async () => {
const idFront = await captureImage();
const idBack = await captureImage();
const liveVideo = 'base64-video-placeholder';
await axios.post('/api/ekyc/submit', {
sessionId,
idCardFront: idFront,
idCardBack: idBack,
livenessVideo: liveVideo
});
alert('已提交实名认证,请等待结果');
};
return (
<div>
<button onClick={start}>开始实名认证</button>
{sessionId && <button onClick={submit}>提交认证</button>}
</div>
);
}
这个例子为什么是「企业级」?
因为它已经满足金融系统的最低合规线:
- 会话化(sessionId)
- 一次性认证
- 支持动作活体扩展
- 数据采集与判断解耦
- 可接第三方 / 自研引擎
- 可进入人工审核
七、金融身份认证 vs 普通互联网对比
| 维度 | 普通互联网 | 金融系统 |
|---|---|---|
| 登录 | 账号密码 | 多因子 |
| KYC | 无 | 强制 |
| 设备 | 可忽略 | 强绑定 |
| 风控 | 弱 | 强实时 |
| 会话 | 长期 | 短期 |
| 操作授权 | 静态 | 动态 |
| 审计 | 很少 | 全量 |
八、在 web3 中如何做「金融系统的身份认证」?
Web3 金融中的身份认证,本质是用"私钥签名"证明身份控制权,再通过 Token、DID 与合规系统,把去中心化身份安全地接入现实金融体系。
1、金融身份认证:Web3 vs Web2(全面对比)
🔥 核心差异:
- Web2 身份认证 = 平台中心化的「账号信任」
- Web3 身份认证 = 用户主权化的「密钥信任」
(1)、整体架构对比(本质层面)
| 维度 | Web2 金融身份认证 | Web3 金融身份认证 |
|---|---|---|
| 信任中心 | 平台 / 金融机构 | 用户私钥 |
| 身份载体 | 账号(用户名 / 手机号 / ID) | 钱包地址 |
| 认证凭证 | 密码 / Token / Session | 私钥签名 |
| 身份控制权 | 平台 | 用户 |
| 认证失败风险 | 数据库泄露、撞库 | 私钥丢失 |
| 可撤销性 | 可冻结 / 重置 | 不可撤销(链上) |
| 合规能力 | 强(KYC/AML 内建) | 弱(需额外绑定) |
(2)、身份模型对比
①、Web2:账户模型(Account-based Identity)
typescript
用户 → 注册账号
→ 绑定手机号 / 邮箱
→ KYC 认证
→ 账号 = 身份
特点:
- 身份是平台分配的
- 可以冻结 / 找回 / 重置
- 非常适合 传统金融监管体系
②、Web3:密钥模型(Key-based Identity)
typescript
用户 → 生成私钥
→ 派生钱包地址
→ 地址 = 身份
特点:
- 身份是数学证明
- 不依赖平台
- 丢私钥 = 永久失去身份
(3)、认证方式对比(核心)
①、登录认证
| 项 | Web2 | Web3 |
|---|---|---|
| 登录方式 | 账号 + 密码 | 钱包签名 |
| 安全依赖 | HTTPS + 后端校验 | 非对称加密 |
| 凭证存储 | 数据库存 hash | 本地私钥 |
| 风险点 | 撞库、钓鱼 | 私钥泄露 |
Web3 登录本质:
- 不是"登录",而是 「我证明我控制这个私钥」
②、会话管理
| 维度 | Web2 | Web3 |
|---|---|---|
| 会话凭证 | Session / JWT | JWT(绑定地址) |
| 过期策略 | 可控 | 可控 |
| 强制下线 | 支持 | 部分支持 |
| Token 续期 | Refresh Token | 重新签名 |
⚠️ 注意:
Web3 并不是不需要 Token,只是 Token 的"身份来源"变了
(4)、KYC & 合规对比(金融关键)
①、Web2(天然合规)
typescript
账号
+ 实名信息
+ 证件
+ 人脸
+ 行为
= 合规身份
✔ 满足:
- KYC
- AML
- CTF
- 审计
②、Web3(合规困难)
钱包地址 ≠ 真实身份
解决方案(现实金融中):
| 方案 | 说明 |
|---|---|
| 地址绑定 KYC | Web3 + Web2 混合 |
| DID | 去中心化身份 |
| ZK-KYC | 零知识证明 |
| 白名单地址 | 合规地址池 |
结论:真正金融级 Web3,一定会引入 Web2 KYC
(5)、安全模型对比
Web2 安全模型
- 密码强度
- MFA
- 风控策略
- 行为识别
- 设备指纹
安全靠"层层防护"
Web3 安全模型
- 私钥安全
- 硬件钱包
- 多签
- 合约权限控制
安全靠"密钥不可破"
(6)、攻击面差异
| 攻击类型 | Web2 | Web3 |
|---|---|---|
| 撞库 | ❌ | ❌ |
| 钓鱼 | ✅ | ✅(更严重) |
| 中间人 | ❌ | ❌ |
| 社工 | ✅ | ✅ |
| 私钥泄露 | N/A | 灾难级 |
| 合约漏洞 | N/A | 灾难级 |
⚠️ Web3 单点失败成本极高
(7)、金融级「真实落地形态」
Web2 金融系统(银行 / 证券)
typescript
账号
→ 密码
→ 短信
→ TOTP
→ 行为风控
→ Token
Web3 金融系统(合规交易所 / RWA)
typescript
钱包签名
→ 地址绑定账号
→ KYC 校验
→ 风险策略
→ Token 会话
👉 几乎全部是「Web2 + Web3 混合架构」
(8)、适用场景对比
| 场景 | 更适合 |
|---|---|
| 银行 / 证券 | Web2 |
| 支付 | Web2 |
| DeFi | Web3 |
| NFT | Web3 |
| 合规交易所 | 混合 |
| RWA | 混合 |
| CBDC | Web2 + 密钥 |
(9)、Web2 和 Web3 对比总结(金融视角)
金融级真相:
- 监管 → Web2
- 资产控制 → Web3
- 未来 → Web2 + Web3 融合
2、在 web3 中做身份认证
(1)、web3 身份认证的概念
❗ Web3 里的"身份认证" ≠ Web2 的"账号密码登录"
在 Web3 金融系统中:
- 身份 = 私钥控制权,而不是账号字符串
❌ 没有:
- "用户名 / 密码"
- 中心化 Session
✅ 有:
- 钱包地址
- 私钥签名
- 链上 / 链下可验证声明
(2)、Web3 金融身份认证的本质拆解
①、Web3 身份的三大核心元素
| 元素 | 作用 |
|---|---|
| 钱包地址 | 身份标识(Who) |
| 私钥签名 | 身份证明(Proof) |
| 可验证声明 | 身份属性(KYC / 资质) |
一句话总结:
- Web3 身份认证 = 证明"你控制这个地址",而不是"你记得一个密码"
②、为什么金融 Web3 必须做"身份认证"?
即使是去中心化金融(DeFi / Web3 金融),也绕不开:
- 反洗钱(AML)
- KYC / KYB
- 合规准入
- 风险控制
- 黑名单 / 制裁地址
所以现实中的 Web3 金融系统通常是:
- "去中心化身份 + 中心化合规模块" 的混合模式
(3)、Web3 金融身份认证的主流技术路径
①、路径一:钱包签名认证(最基础)
核心思路:
- 地址 ≠ 身份
- 签名 ≠ 授权
- 签名 + 随机挑战 = 身份认证
认证流程(文字版):
typescript
1. 前端请求 challenge
2. 用户钱包签名 challenge
3. 后端验证签名
4. 签发登录 Token / 会话
❗️ 这是 Web3 版的"登录"
②、路径二:SIWE(Sign-In With Ethereum)
Web3 金融的事实标准
特点:
- 明确定义签名消息结构
- 防重放
- 绑定域名 / 时间
- 可审计
很多金融级 Web3 项目都采用 SIWE
③、路径三:DID(去中心化身份)
DID 做什么?
- 地址是"你是谁"
- DID 是"你拥有什么身份属性"
例如:
- 已通过 KYC
- 是机构用户
- 是合格投资者
DID 本身 不负责登录 ,而是负责 身份声明
④、路径四:Web3 + KYC(合规金融必备)
现实中的金融 Web3 通常:
typescript
钱包认证
→ DID 绑定
→ 链下 KYC
→ 策略控制访问权限
(4)、Web3 金融身份认证的整体架构(文字版)
typescript
用户钱包
↓(签名)
前端 DApp
↓
身份验证服务
(验证签名 / SIWE)
↓
合规 & 风控系统
(KYC / 风险策略)
↓
Token / Session
↓
金融业务系统
(5)、一个「简单但企业级」Web3 身份认证示例
场景:Web3 金融平台登录(钱包签名)
①、前端:请求 challenge
typescript
async function getChallenge(address: string) {
const res = await fetch('/api/auth/challenge', {
method: 'POST',
body: JSON.stringify({ address })
});
return res.text();
}
②、前端:钱包签名
typescript
import { ethers } from 'ethers';
async function signChallenge(challenge: string) {
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
return signer.signMessage(challenge);
}
③、前端:提交签名
typescript
async function loginWithWallet() {
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const address = await signer.getAddress();
const challenge = await getChallenge(address);
const signature = await signChallenge(challenge);
await fetch('/api/auth/verify', {
method: 'POST',
body: JSON.stringify({
address,
signature,
challenge
})
});
}
④、后端(逻辑说明)
typescript
verify(address, signature, challenge):
recoveredAddress = recoverSigner(challenge, signature)
if recoveredAddress !== address → reject
if challenge used before → reject
→ 创建登录会话 / Token
⑤、企业级增强点(金融必备)
- challenge 一次性使用(防重放)
- 绑定域名 / 时间 / 链ID
- 登录后仍使用 Token / Session
- 与 KYC / 风控系统联动
- 可触发 MFA / 行为认证
- 审计全链路记录
(6)、Web3 金融身份认证的"真实落地形态"
🔥 99% 的金融级 Web3 项目不是纯 Web3
而是:
typescript
钱包认证(去中心化)
+ Token 会话(中心化)
+ KYC / 风控(合规)
+ 策略控制(访问)
这是现实合规世界下的最优解。