BenChuat

Background
跳过正文

PicGo 配置兰空图床上传失败报错`unable to verify the first certificat`

·2675 字·6 分钟
作者
BenChuat
A little bit about BenChuat.
目录

PicGo 配置兰空图床上传失败报错unable to verify the first certificat
#

问题背景
#

在使用 PicGo 配置兰空图床(Lankong/Lsky Pro)时,遇到了上传失败的问题。本文记录了完整的问题排查和解决过程。

问题一:HTTPS 上传失败 - SSL 证书验证错误
#

错误现象
#

首次配置 PicGo 时,使用 HTTPS 协议上传图片,遇到了 SSL 证书验证失败的错误。

开了Ignore certificate error依然不行,一直上传失败,打开日志检查:

一直报的是unable to verify the first certificat这个错误,应该是证书问题,Ignore certificate error这个开关好像没用。

错误日志
#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2025-12-05 17:21:23 [PicGo INFO] [PicGo Server] is listening at 36677 

2025-12-05 17:21:23 [PicGo INFO] register builtin shortKey command: [picgo:upload] - [CommandOrControl+Shift+P] 

2025-12-05 17:21:23 [PicGo INFO] register builtin shortKey command: [picgo:upload] - [CommandOrControl+Shift+P] successfully 

2025-12-05 17:21:54 [PicGo INFO] Before transform 

2025-12-05 17:21:54 [PicGo INFO] Transforming... Current transformer is [path] 

2025-12-05 17:21:54 [PicGo INFO] Before upload 

2025-12-05 17:21:54 [PicGo INFO] beforeUploadPlugins: renameFn running 

2025-12-05 17:21:54 [PicGo INFO] Uploading... Current uploader is [lankong] 

2025-12-05 17:21:55 [PicGo WARN] failed 

2025-12-05 17:21:55 [PicGo ERROR] {

  "method": "POST",

  "url": "https://*************/api/v1/upload",

  "statusCode": 0,

  "message": "unable to verify the first certificate",

  "stack": "Error: unable to verify the first certificate\n    at TLSSocket.onConnectSecure (node:_tls_wrap:1530:34)\n    at TLSSocket.emit (node:events:394:28)\n    at TLSSocket._finishInit (node:_tls_wrap:944:8)\n    at TLSWrap.ssl.onhandshakedone (node:_tls_wrap:725:12)",

  "response": {

    "status": 0,

    "statusCode": 0,

    "body": ""

  }

} 

问题分析
#

错误信息显示:

  • 使用的 URL:https://**********/upload
  • 错误原因:unable to verify the first certificate(无法验证第一个证书)

这是典型的 SSL/TLS 证书验证失败问题,可能是:

  1. 服务器使用的是自签名证书
  2. 证书已过期
  3. 证书链不完整

初步解决方案
#

尝试将协议从 HTTPS 改为 HTTP,并修正端口号。

问题二:HTTP 上传失败 - CSRF Token 错误
#

错误现象
#

将配置改为 HTTP 协议后,仍然上传失败,这次出现了不同的错误。

错误日志
#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
2025-12-05 17:25:18 [PicGo INFO] [PicGo Server] is listening at 36677 

2025-12-05 17:25:18 [PicGo INFO] register builtin shortKey command: [picgo:upload] - [CommandOrControl+Shift+P] 

2025-12-05 17:25:18 [PicGo INFO] register builtin shortKey command: [picgo:upload] - [CommandOrControl+Shift+P] successfully 

2025-12-05 17:26:06 [PicGo INFO] Before transform 

2025-12-05 17:26:06 [PicGo INFO] Transforming... Current transformer is [path] 

2025-12-05 17:26:06 [PicGo INFO] Before upload 

2025-12-05 17:26:06 [PicGo INFO] beforeUploadPlugins: renameFn running 

2025-12-05 17:26:06 [PicGo INFO] Uploading... Current uploader is [lankong] 

2025-12-05 17:26:06 [PicGo INFO] [Lankong] 当前配置 - Server: http://********, Version: V2 

2025-12-05 17:26:06 [PicGo INFO] [Lankong] 上传 URL: http://********/api/v1/upload 

2025-12-05 17:26:06 [PicGo WARN] failed 

2025-12-05 17:26:06 [PicGo ERROR] {

  "method": "POST",

  "url": "http://********/api/v1/upload",

  "statusCode": 419,

  "message": "Request failed with status code 419",

  "stack": {},

  "response": {

    "status": 419,

    "statusCode": 419,

    "body": {

      "message": "CSRF token mismatch."

    }

  }

} 

问题分析
#

错误信息显示:

  • 使用的 URL:http://********/api/v1/upload
  • 错误原因:CSRF token mismatch(CSRF 令牌不匹配)
  • 状态码:419(Laravel 框架的 CSRF 保护错误)

这说明:

  1. 协议和端口已经正确(HTTP,8089)
  2. 但是使用的路径 /upload 是前端路由,受到 CSRF 保护
  3. 需要使用标准的 API 路径来绕过 CSRF 验证

验证服务器是否正常
#

为了确认问题是否出在服务器端,我直接在浏览器中访问 http://********/api/v1/upload,登录后通过网页界面上传图片,上传成功

image-20251205210615044

这说明:

  • 服务器本身是正常的
  • 问题出在 PicGo 的配置或插件代码上
  • 需要找到正确的 API 路径和认证方式

问题排查
#

发现关键问题
#

通过对比发现:

  1. 服务端网页上传:使用路径 /upload(前端路由,需要 CSRF token)
  2. PicGo 应该使用:标准 API 路径 /api/v1/upload(API 路由,使用 Bearer Token 认证,可绕过 CSRF)

需要修改的文件
#

需要修改 picgo-plugin-lankong 插件的代码文件。

文件位置:

1
%APPDATA%\picgo\node_modules\picgo-plugin-lankong\dist\index.js

如何找到这个文件:

  1. Win + R 打开运行对话框
  2. 输入 %APPDATA% 并回车
  3. 进入 picgo 文件夹
  4. 进入 node_modules 文件夹
  5. 进入 picgo-plugin-lankong 文件夹
  6. 进入 dist 文件夹
  7. 找到 index.js 文件

完整路径示例:

1
C:\Users\你的用户名\AppData\Roaming\picgo\node_modules\picgo-plugin-lankong\dist\index.js
image-20251205211152085

注意AppData是隐藏文件夹,要手动显示:

解决方案
#

修改步骤
#

步骤 1:打开插件文件
#

用文本编辑器(如 VS Code、Notepad++ 等)打开 index.js 文件。

步骤 2:修改 Token 处理逻辑
#

找到 postOptions 函数(大约在第 87 行),找到以下代码:

1
2
3
const isV2 = userConfig.lskyProVersion === 'V2';
const token = userConfig.token;
const ignoreCertErr = userConfig.ignoreCertErr;

修改为:

1
2
3
4
5
6
7
const isV2 = userConfig.lskyProVersion === 'V2';
let token = userConfig.token;
// 确保 V2 版本的 token 包含 Bearer 前缀
if (isV2 && token && !token.startsWith('Bearer ')) {
    token = `Bearer ${token}`;
}
const ignoreCertErr = userConfig.ignoreCertErr;

步骤 3:修改上传路径
#

继续在 postOptions 函数中,找到路径设置的部分(大约在第 145-153 行),找到类似这样的代码:

1
2
3
4
5
6
7
8
9
// 支持自定义上传路径,如果配置了 customUploadPath 则使用,否则使用默认路径
const customUploadPath = userConfig.customUploadPath;
let uploadPath;
if (customUploadPath) {
    uploadPath = customUploadPath.startsWith('/') ? customUploadPath : `/${customUploadPath}`;
} else {
    // 默认路径:V2 使用 /upload,V1 使用 /api/upload
    uploadPath = isV2 ? '/upload' : '/api/upload';
}

修改为:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 支持自定义上传路径,如果配置了 customUploadPath 则使用,否则使用默认路径
const customUploadPath = userConfig.customUploadPath;
let uploadPath;
if (customUploadPath) {
    uploadPath = customUploadPath.startsWith('/') ? customUploadPath : `/${customUploadPath}`;
} else {
    // 默认路径:V2 使用标准的 /api/v1/upload,V1 使用 /api/upload
    // 使用标准 API 路径可以绕过 CSRF 保护
    uploadPath = isV2 ? '/api/v1/upload' : '/api/upload';
}

步骤 4:修复 SSL 证书验证逻辑
#

找到 SSL agent 创建的部分(大约在第 154-160 行),找到类似这样的代码:

1
2
3
4
5
6
// 如果忽略证书错误开关打开则带上 http agent 访问, 否则不需要带(以提高性能)
if (ignoreCertErr) {
    let requestAgent = new https_1.default.Agent({
        // 此处需要取反 忽略证书错误 拒绝未授权证书选项
        rejectUnauthorized: !ignoreCertErr
    });

修改为:

1
2
3
4
5
6
7
// 如果忽略证书错误开关打开且是 HTTPS 协议,则带上 https agent 访问
const isHttps = serverUrl.startsWith('https://');
if (ignoreCertErr && isHttps) {
    let requestAgent = new https_1.default.Agent({
        // 此处需要取反 忽略证书错误 拒绝未授权证书选项
        rejectUnauthorized: !ignoreCertErr
    });

步骤 5:保存文件
#

保存修改后的文件。

重启 PicGo
#

  1. 完全关闭 PicGo

    • 右键点击系统托盘中的 PicGo 图标
    • 选择"退出"或"Quit"
    • 在任务管理器中确认没有 PicGo 进程
  2. 重新启动 PicGo

    • 从开始菜单或桌面快捷方式启动 PicGo

成功结果
#

重启 PicGo 后,再次尝试上传图片,上传成功

成功日志
#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2025-12-05 20:23:40 [PicGo INFO] [PicGo Server] is listening at 36677 

2025-12-05 20:23:40 [PicGo INFO] register builtin shortKey command: [picgo:upload] - [CommandOrControl+Shift+P] 

2025-12-05 20:23:40 [PicGo INFO] register builtin shortKey command: [picgo:upload] - [CommandOrControl+Shift+P] successfully 

2025-12-05 20:24:15 [PicGo INFO] Before transform 

2025-12-05 20:24:15 [PicGo INFO] Transforming... Current transformer is [path] 

2025-12-05 20:24:15 [PicGo INFO] Before upload 

2025-12-05 20:24:15 [PicGo INFO] beforeUploadPlugins: renameFn running 

2025-12-05 20:24:15 [PicGo INFO] Uploading... Current uploader is [lankong] 

2025-12-05 20:24:15 [PicGo INFO] [Lankong] 当前配置 - Server: http://********, Version: V2, Token: 3|qrmaJv6X... 

2025-12-05 20:24:15 [PicGo INFO] [Lankong] 上传 URL: http://********/api/v1/upload 

2025-12-05 20:24:15 [PicGo INFO] [Lankong] Authorization : Bearer ... 

2025-12-05 20:24:16 [PicGo SUCCESS] 

http://blog.benchuat.cn:8089/Sugq7o.jpg 

成功关键点
#

从成功日志可以看出:

  • 正确的协议和端口:http://********
  • 正确的 API 路径/api/v1/upload(标准 V2 API 路径)
  • 正确的 Token 格式Bearer ...(自动添加了 Bearer 前缀)
  • 成功返回图片 URLhttp://********/Sugq7o.jpg

问题总结
#

核心问题
#

  1. 路径错误:使用了前端路由 /upload 而非标准 API 路径 /api/v1/upload
  2. Token 格式:V2 API 需要 Bearer <token> 格式,但代码没有自动添加前缀
  3. SSL 验证逻辑:HTTP 协议不应该创建 HTTPS agent

解决方法
#

  1. 修改上传路径:从 /upload 改为 /api/v1/upload
  2. 自动添加 Bearer 前缀:确保 V2 token 格式正确
  3. 修复 SSL 逻辑:只在 HTTPS 协议时创建 SSL agent

经验总结
#

  • 标准 API 路径的重要性:使用 /api/v1/upload 可以绕过 CSRF 保护,因为这是 API 路由,使用 Bearer Token 认证
  • 协议匹配:确保配置的协议(HTTP/HTTPS)与服务器实际协议一致
  • 调试信息:添加日志有助于快速定位问题

注意事项
#

  1. 插件更新:如果更新了 picgo-plugin-lankong 插件,可能需要重新应用这些修改
  2. 配置备份:修改代码前建议先备份原文件
  3. Token 安全:Token 是敏感信息,不要泄露给他人