Chrome扩展DevTools发凭证至Werkzeug服务器未被识别问题
问题原因
你这里存在两个核心认知偏差,直接导致服务端无法获取到传入的凭证:
XMLHttpRequest.open()方法的第5、6个位置参数(用户名、密码)是为HTTP认证框架(Basic、Digest认证等)预留的入参,浏览器不会在首次请求时主动携带这组凭证,只有当服务端先返回401 Unauthorized状态码、且携带WWW-Authenticate响应头明确要求认证时,浏览器才会自动重试请求,将这对凭证编码后放入Authorization请求头发送。你当前服务端收到请求后直接返回正常业务响应,没有触发认证质询流程,浏览器根本没有把传入的login、password写入请求内容,自然无法在请求对象中找到。- 就算触发了Basic认证流程,凭证也不会出现在URL参数、POST表单、请求体这类位置,而是存储在
Authorization请求头中,如果在Werkzeug的request.args、request.form、request.data字段中查找,必然拿不到对应值。
修正方案
根据业务场景二选一即可:
方案1:走标准HTTP Basic认证逻辑(匹配open方法参数的设计用途)
不要依赖open方法的入参等待服务端认证质询,直接在前端主动构造Authorization请求头,首次请求就携带凭证,省掉401重发的往返开销:
let xhr = new XMLHttpRequest(); let rType = "POST"; xhr.open(rType, loadPath, true); // 手动编码Basic认证头 const authValue = btoa(`${login}:${password}`); xhr.setRequestHeader("Authorization", `Basic ${authValue}`); xhr.withCredentials = true; xhr.send();
服务端Werkzeug不需要手动解析请求头,直接读取框架封装好的request.authorization属性即可,这是预解析完成的对象:
request.authorization.username对应传入的login值request.authorization.password对应传入的password值
注意请求是从chrome-extension://源发往本地服务的跨域请求,需要给Werkzeug服务配置正确的CORS响应头:
Access-Control-Allow-Credentials: trueAccess-Control-Allow-Origin不能设为通配符*,需要明确填写自身扩展对应的origin,格式为chrome-extension://<你的扩展32位ID>Access-Control-Allow-Headers需要包含Authorization,允许前端携带该自定义请求头
方案2:将凭证作为普通POST参数传递
如果不需要走HTTP认证逻辑,就不要把凭证传入open方法,直接放到POST请求体中发送即可,比如使用FormData格式:
let xhr = new XMLHttpRequest(); let rType = "POST"; xhr.open(rType, loadPath, true); xhr.withCredentials = true; const fd = new FormData(); fd.append("login", login); fd.append("password", password); xhr.send(fd);
服务端直接从POST表单字段中取值即可:
- 用户名:
request.form.get("login") - 密码:
request.form.get("password")
内容的提问来源于stack exchange,提问作者Kostiantyn Ivashchenko
相关产品推荐
相关产品推荐

