LoopBack 4 认证动作(Authentication Action)实战:为自定义 Sequence 接入 authenticate 动作并保护 REST 端点
后端微服务【免费下载链接】loopback-nextLoopBack makes it easy to build modern API applications that require complex integrations.项目地址https://gitcode.com/gh_mirrors/lo/loopback-next点击查看免费下载本文聚焦 LoopBack 4 认证体系中最核心的接入点——认证动作Authentication Action在基于Sequence序列的请求处理管线中authenticate默认并不存在需要开发者通过AuthenticateActionProvider提供的AuthenticateFn手动注入到自定义序列中。读完本文你将掌握默认序列的执行步骤、AuthenticateActionProvider的底层机制策略延迟解析、用户 Profile 写入上下文、协议无关错误码并能在自己的应用中写出一个可运行、可绑定、可返回 401 的自定义认证序列同时了解新版本中间件式序列下认证中间件的等价实现。理解认证动作与 Sequenceauthenticate 为什么默认缺席在 LoopBack 4 的 REST 应用中每一个请求都会经过一组无状态动作的编排这组动作被称为Sequence序列。序列本质上是一系列步骤用于控制RestServer如何响应传入请求。默认序列会注入并依次执行findRoute、parseParams、invoke、send、reject这五个动作。在 Todo 示例的序列文件 中可以找到默认序列的经典实现该示例当前版本已切换为MiddlewareSequence但其对五个动作的语义描述仍然成立export class DefaultSequence implements SequenceHandler { /** * Constructor: Injects findRoute, invokeMethod logError * methods as promises. * * param {FindRoute} findRoute Finds the appropriate controller method, * spec and args for invocation (injected via SequenceActions.FIND_ROUTE). * param {ParseParams} parseParams The parameter parsing function (injected * via SequenceActions.PARSE_PARAMS). * param {InvokeMethod} invoke Invokes the method specified by the route * (injected via SequenceActions.INVOKE_METHOD). * param {Send} send The action to merge the invoke result with the response * (injected via SequenceActions.SEND) * param {Reject} reject The action to take if the invoke returns a rejected * promise result (injected via SequenceActions.REJECT). */ constructor( inject(SequenceActions.FIND_ROUTE) protected findRoute: FindRoute, inject(SequenceActions.PARSE_PARAMS) protected parseParams: ParseParams, inject(SequenceActions.INVOKE_METHOD) protected invoke: InvokeMethod, inject(SequenceActions.SEND) public send: Send, inject(SequenceActions.REJECT) public reject: Reject, ) {} /** * Runs the default sequence. Given a handler context (request and response), * running the sequence will produce a response or an error. */ async handle(context: RequestContext): Promisevoid { try { const {request, response} context; const route this.findRoute(request); const args await this.parseParams(request, route); const result await this.invoke(route, args); debug(%s result -, route.describe(), result); this.send(response, result); } catch (error) { this.reject(context, error); } } }每个动作的职责如下动作职责findRoute找到合适的控制器方法、Swagger 规范与调用参数parseParams解析 HTTP 请求得到 API 参数列表invoke调用 Application Controller 中定义的 APIsend将 API 的返回结果写入 HTTP 响应reject上述任一步骤出错时捕获错误并记录日志关键点默认情况下authenticate不是动作序列的一部分。因此如果你要为端点启用认证必须修改默认序列把认证动作加进去。注意如果你使用的是基于中间件的序列middleware-based sequence则不需要本节的操作——认证由自动发现并加入序列的中间件强制执行。详见本文「中间件式序列下的认证」一节与 REST 中间件序列文档。AuthenticateActionProvider认证动作的提供者与底层机制认证动作AuthenticateFn由AuthenticateActionProvider类提供该类的核心实现在 auth-action.provider.ts。原文档给出的机制说明代码如下// ------ CODE THAT EXPLAINS THE MECHANISM --------- export class AuthenticateActionProvider implements ProviderAuthenticateFn { constructor( // The provider is instantiated for Sequence constructor, // at which time we dont have information about the current // route yet. This information is needed to determine // what auth strategy should be used. // To solve this, we are injecting a getter function that will // defer resolution of the strategy until authenticate() action // is executed. inject.getter(AuthenticationBindings.STRATEGY) readonly getStrategy: GetterAuthenticationStrategy, inject.setter(SecurityBindings.USER) readonly setCurrentUser: SetterUserProfile, ) {} /** * returns authenticateFn */ value(): AuthenticateFn { return request this.action(request); } /** * The implementation of authenticate() sequence action. * param request The incoming request provided by the REST layer */ async action(request: Request): PromiseUserProfile | undefined { const strategy await this.getStrategy(); if (!strategy) { // The invoked operation does not require authentication. return undefined; } const userProfile await strategy.authenticate(request); if (!userProfile) { // important to throw a non-protocol-specific error here let error new Error( User profile not returned from strategys authenticate function, ); Object.assign(error, { code: USER_PROFILE_NOT_FOUND, }); throw error; } this.setCurrentUser(userProfile); return userProfile; } }机制拆解如下value()返回一个类型为AuthenticateFn的函数该函数尝试获取认证策略由AuthenticationStrategyProvider通过AuthenticationBindings.STRATEGY绑定解析得到。如果该端点没有指定认证策略认证动作立即返回undefined请求继续往下走。如果该端点指定了认证策略则调用策略的authenticate(request)方法。若返回了用户 Profile说明认证成功该 Profile 会通过SecurityBindings.USER绑定写入请求上下文否则抛出USER_PROFILE_NOT_FOUND错误。之所以在构造函数中注入的是inject.getterGetter 函数而非直接注入策略实例是因为 Provider 在序列构造时就被实例化此时还不知道当前路由信息而路由信息恰恰决定了应使用哪个策略。通过延迟解析直到authenticate()动作真正执行时才解析策略。现代源码的增强多策略、failOnError 与重定向当前仓库中的AuthenticateActionProvider见 auth-action.provider.ts在原始机制之上支持了更多能力构造函数注入了策略 Getter、当前用户 Setter、重定向 URL/状态 Setter以及组件配置AuthenticationOptionsexport class AuthenticateActionProvider implements ProviderAuthenticateFn { constructor( inject.getter(AuthenticationBindings.STRATEGY) readonly getStrategies: Getter AuthenticationStrategy | AuthenticationStrategy[] | undefined , inject.setter(SecurityBindings.USER) readonly setCurrentUser: SetterUserProfile, inject.setter(AuthenticationBindings.AUTHENTICATION_REDIRECT_URL) readonly setRedirectUrl: Setterstring, inject.setter(AuthenticationBindings.AUTHENTICATION_REDIRECT_STATUS) readonly setRedirectStatus: Setternumber, config({fromBinding: AuthenticationBindings.COMPONENT}) private readonly options: AuthenticationOptions {}, ) {} value(): AuthenticateFn { return request this.action(request); } async action(request: Request): PromiseUserProfile | undefined { let strategies await this.getStrategies(); if (strategies null) { // The invoked operation does not require authentication. return undefined; } // convert to array if required strategies Array.isArray(strategies) ? strategies : [strategies]; const authErrors: unknown[] []; for (const strategy of strategies) { let authResponse: UserProfile | RedirectRoute | undefined undefined; try { authResponse await strategy.authenticate(request); } catch (err) { if (this.options.failOnError) { throw err; } authErrors.push(err); } // response from strategy.authenticate() could return an object of // type UserProfile or RedirectRoute if (RedirectRoute.isRedirectRoute(authResponse)) { const redirectOptions authResponse; // bind redirection url and status to the context // controller should handle actual redirection this.setRedirectUrl(redirectOptions.targetLocation); this.setRedirectStatus(redirectOptions.statusCode); return; } else if (authResponse ! null) { // if strategy.authenticate() returns an object of type UserProfile, // set it as current user const userProfile authResponse as UserProfile; this.setCurrentUser(userProfile); return userProfile; } } if (authErrors.length) { throw authErrors[0]; } // important to throw a non-protocol-specific error here const error new Error( User profile not returned from strategys authenticate function, ); Object.assign(error, { code: USER_PROFILE_NOT_FOUND, }); throw error; } }现代版本的行为要点支持多个策略一个端点可绑定多个策略认证动作会按顺序逐个调用只要有一个策略返回UserProfile即认证成功。failOnError选项当某个策略抛出异常时默认行为是记录错误并继续尝试下一个策略若组件配置failOnError: true见 AuthenticationOptions 定义则立即抛出错误终止认证。支持RedirectRoute策略的authenticate()若返回RedirectRoute常用于 OAuth 登录跳转认证动作会将该重定向 URL 与状态码通常是 302/303绑定到上下文交由控制器处理实际跳转。对应绑定键AUTHENTICATION_REDIRECT_URL与AUTHENTICATION_REDIRECT_STATUS定义在 keys.ts。所有策略都失败且存在错误时抛出第一个错误没有任何策略返回 Profile 时抛出带code: USER_PROFILE_NOT_FOUND的协议无关错误。相关类型与绑定键AuthenticateFn类型定义在 types.ts(request: Request) PromiseUserProfile | undefined。AuthenticationStrategy接口types.ts要求实现name属性与authenticate(request)方法返回值可以是UserProfile、RedirectRoute或undefined。绑定键AuthenticationBindings.AUTH_ACTION定义在 keys.ts其值为authentication.actions.authenticate用于从上下文获取认证函数。AuthenticationComponentauthentication.component.ts会把AuthenticateActionProvider注册到AUTH_ACTION绑定键上同时注册策略提供者与元数据提供者。单元测试佐证仓库中的单元测试 authentication.provider.unit.ts 验证了上述机制value()返回的函数能认证请求并返回用户returns a function which authenticates a request and returns a user。认证成功后更新当前用户updates current user。所有策略都失败时抛出错误只要有一个策略成功则不抛错failOnError: true时任一策略失败即抛错。未返回用户 Profile 时抛出code: USER_PROFILE_NOT_FOUND的错误对应测试throws USER_PROFILE_NOT_FOUND error when userprofile not returned。自定义序列接入认证动作MyAuthenticatingSequence 实战下面是一个改造后的自定义序列它在invoke之前调用了authenticate动作。这是原文档给出的核心示例也是仓库测试夹具 authentication.sequence.ts 中真实使用的模式export class MyAuthenticatingSequence implements SequenceHandler { constructor( // ... Other injections // ------ ADD SNIPPET --------- inject(AuthenticationBindings.AUTH_ACTION) protected authenticateRequest: AuthenticateFn, // ------------- END OF SNIPPET ------------- ) {} async handle(context: RequestContext) { try { const {request, response} context; const route this.findRoute(request); // ------ ADD SNIPPET --------- //call authentication action await this.authenticateRequest(request); // ------------- END OF SNIPPET ------------- // Authentication successful, proceed to invoke controller const args await this.parseParams(request, route); const result await this.invoke(route, args); this.send(response, result); } catch (error) { // ------ ADD SNIPPET --------- if ( error.code AUTHENTICATION_STRATEGY_NOT_FOUND || error.code USER_PROFILE_NOT_FOUND ) { Object.assign(error, {statusCode: 401 /* Unauthorized */}); } // ------------- END OF SNIPPET ------------- this.reject(context, error); return; } } }注意到序列构造函数中新增的依赖注入inject(AuthenticationBindings.AUTH_ACTION) protected authenticateRequest: AuthenticateFn,绑定键AuthenticationBindings.AUTH_ACTION让我们拿到由AuthenticateActionProvider提供的、类型为AuthenticateFn的认证函数authenticateRequest。使用要点位置认证函数authenticateRequest可以在自定义序列中任何位于invoke动作之前的地方调用从而保护端点。错误码映射AUTHENTICATION_STRATEGY_NOT_FOUND与USER_PROFILE_NOT_FOUND是两个协议无关protocol-agnostic的错误必须在序列中捕获并赋予 HTTP 状态码401Unauthorized。具体返回什么 HTTP 错误码由开发者在自己实现的认证策略或其自定义服务中决定。失败即短路认证过程中一旦抛出任何错误端点的控制器函数永远不会被执行。策略实现自身抛出的错误通常已带有statusCode只有上述两个协议无关错误需要序列手动补上statusCode: 401。仓库测试夹具 authentication.sequence.ts 的注释明确说明了这一设计意图。在 passport-login 示例 中可以看到一个更复杂的真实场景该序列把authenticateRequest放在parseParams之后调用因为登录场景需要先从路径参数中解析出 OAuth 提供者名称再把oauth2-provider-name写入 query最后才执行认证认证失败且请求路径为/login时则把UnauthorizedError事件交回给外层 Express 应用处理。将认证序列绑定到应用定义好执行认证动作的自定义序列后必须把它绑定到应用application.ts上export class MyApplication extends BootMixin( ServiceMixin(RepositoryMixin(RestApplication)), ) { constructor(options?: ApplicationConfig) { super(options); //... // ------ ADD SNIPPET --------- this.sequence(MyAuthenticatingSequence); // ------------- END OF SNIPPET ------------- //... } }一个完整的认证应用配置通常包含三部分可参考 Authentication-component-options.md 的总结加载认证组件、注册认证策略、绑定认证序列import { AuthenticationComponent, registerAuthenticationStrategy, } from loopback/authentication; export class MyApplication extends BootMixin( ServiceMixin(RepositoryMixin(RestApplication)), ) { constructor(options?: ApplicationConfig) { super(options); //... // ------ ADD SNIPPET --------- // load the authentication component this.component(AuthenticationComponent); // register your custom authentication strategy registerAuthenticationStrategy(this, BasicAuthenticationStrategy); // use your custom authenticating sequence this.sequence(MyAuthenticatingSequence); // ------------- END OF SNIPPET ------------- } }在 JWT 认证教程对应示例 todo-jwt中你还可以看到完整的端到端流程加载AuthenticationComponent与JWTAuthenticationComponent、在序列中启用 JWT 认证动作、创建登录/注册控制器、用authenticate(jwt)保护 Todo 接口。中间件式序列下的认证AuthenticationMiddlewareProvider原文档开头有一条重要提示如果应用使用基于中间件的序列middleware-based sequence则无需手动添加认证动作因为认证由自动发现并加入序列的中间件强制执行。loopback/rest自 6.0.0 起默认采用中间件式序列MiddlewareSequencelb4 app生成的src/sequence.ts即继承它参见 REST 中间件序列文档。loopback/authentication为此提供了AuthenticationMiddlewareProvider与AuthenticateActionProvider同文件见 auth-action.provider.tsinjectable( asMiddleware({ group: RestMiddlewareGroups.AUTHENTICATION, upstreamGroups: [RestMiddlewareGroups.FIND_ROUTE], }), ) export class AuthenticationMiddlewareProvider implements ProviderMiddleware { constructor( inject(AuthenticationBindings.AUTH_ACTION) private authenticate: AuthenticateFn, ) {} value(): Middleware { return async (ctx, next) { try { await this.authenticate(ctx.request); } catch (error) { if ( error.code AUTHENTICATION_STRATEGY_NOT_FOUND || error.code USER_PROFILE_NOT_FOUND ) { error.statusCode 401; } throw error; } return next(); }; } }该中间件被注册到RestMiddlewareGroups.AUTHENTICATION组并声明findRoute为其上游组。它内部复用同一个AUTH_ACTION绑定的AuthenticateFn并在捕获两个协议无关错误时自动补上statusCode 401——这正是自定义序列中那段错误映射代码的中间件版等价实现。上图展示了中间件式序列中各组件的执行顺序sendResponse最先进入负责收集下游结果或捕获错误、随后依次执行cors、apiSpec、middleware、findRoute、authentication、parseParams、invokeMethod。认证中间件在findRoute之后、parseParams之前执行与自定义序列中认证动作放在 invoke 之前的位置语义一致。因此在新生成的应用中你通常什么都不用做加载AuthenticationComponent后认证中间件会被自动发现并加入序列。只有当你的应用仍使用传统动作式序列例如需要精细控制每个动作的执行时机、或从旧版本迁移而来才需要采用本文第三、四节的自定义序列方案。错误码约定与协议无关设计认证体系特意设计为协议无关即认证动作本身不直接与 HTTP 状态码耦合而由外层序列或中间件负责映射。仓库中定义了两个错误码常量types.tsAUTHENTICATION_STRATEGY_NOT_FOUND策略解析失败时抛出。由 auth-strategy.provider.ts 在按名字查找不到策略时生成错误消息形如The strategy doesnotexist is not available.。USER_PROFILE_NOT_FOUND策略执行完成但没有返回用户 Profile 时抛出错误消息为User profile not returned from strategys authenticate function。在自定义序列或认证中间件中这两个错误应被映射为 HTTP 401。仓库的接受测试 basic-auth-extension.acceptance.ts 验证了完整行为携带正确 Basic 凭据访问/whoAmI返回用户 ID缺少Authorization头时返回statusCode: 401的UnauthorizedError使用不存在的策略名authenticate(doesnotexist)时返回code: AUTHENTICATION_STRATEGY_NOT_FOUND、statusCode: 401策略返回undefined时返回code: USER_PROFILE_NOT_FOUND、statusCode: 401未加authenticate装饰器的方法允许匿名访问认证动作因没有策略而直接返回。延伸阅读认证装饰器Authentication Decoratorauthenticate的语法与元数据即端点如何声明需要认证。认证策略Authentication Strategy自定义策略的实现与注册。管理自定义认证策略选项defaultMetadata、failOnError等组件配置。REST 中间件序列中间件式序列的组排序与扩展方式。JWT 认证教程完整可运行的 JWT 认证应用。认证装饰器参考authenticate装饰器的详细 API。赞分享后端微服务【免费下载链接】loopback-nextLoopBack makes it easy to build modern API applications that require complex integrations.项目地址https://gitcode.com/gh_mirrors/lo/loopback-next点击查看免费下载相关推荐Redwood 自定义认证Custom Authentication集成指南以 Nhost 为例接入任意 Auth ProviderRedwood 自定义认证Custom Authentication集成指南以 Nhost 为例接入任意 Auth Provider 当 Redwood后端前端Web框架开发工具LoopBack 4 高效传输请求体loopback/rest-msgpack 组件接入与实战指南LoopBack 4 高效传输请求体loopback/rest msgpack 组件接入与实战指南 导读 本文讲解 LoopBack 4 生态中的 loo后端微服务InvenTree Action 插件开发指南基于 ActionMixin 与 /api/action/ 端点构建自定义动作InvenTree Action 插件开发指南基于 ActionMixin 与 /api/action/ 端点构建自定义动作 本文面向 InvenTree 插后端前端企业应用ERP上一篇Spring AI流式模式下Token计算的3种高效解决方案下一篇百度网盘提取码效率工具快速获取分享资源的实用方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

C 语言内存函数超清晰总结(memcpy、memmove、memcmp、memset)

C 语言内存函数超清晰总结(memcpy、memmove、memcmp、memset)

前言: C 语言中, strcpy / strcmp 等字符串函数只能处理字符串。 想要通用拷贝任意类型数组、结构体,就要用内存操作函数:按字节操作,不关心数据类型。 本文一次性讲清 4 个常用内存函数:用法 区别 模拟…

2026/10/13 6:19:45 阅读更多 →
数据库课程设计实战:图书管理系统建表与借还书SQL全解析

数据库课程设计实战:图书管理系统建表与借还书SQL全解析

简介:这份数据库课程设计报告面向高校计算机相关专业学生,尤其是正在完成数据库课程设计或需要撰写实验报告的学习者。报告以图书管理系统为案例,完整呈现从开发背景、需求分析到物理设计与实施的全过程,帮助读者理解如何将数据库…

2026/10/13 6:19:45 阅读更多 →
Visual Studio 2012 C++ 开发环境配置与首个程序实战指南

Visual Studio 2012 C++ 开发环境配置与首个程序实战指南

简介:这份《Visual Studio 2012 指导教程》面向具备C语言基础的初学者与希望系统梳理开发流程的进阶开发者,帮助读者从集成开发环境入手,逐步掌握命令行程序、Windows应用乃至简单游戏的构建方法。教程内容按主题递进,涵盖解决方案…

2026/10/13 6:19:45 阅读更多 →

最新新闻

学习 Python 基础语法与工程环境操作流程

学习 Python 基础语法与工程环境操作流程

前言一、基础概念虚拟环境:可以理解成每个项目专属的「Python 独立工具箱」。每个项目单独一套 Python 解释器和第三方安装包,项目之间互不干扰,不会出现 A 项目装的包覆盖 B 项目依赖的情况,删掉环境文件夹就能一键重置&#xff…

2026/10/13 6:59:55 阅读更多 →
陈,读懂生理药理实验多用仪

陈,读懂生理药理实验多用仪

生理药理刺激多用仪属于多功能综合性实验设备,依托数字集成电路对振荡频率分频处理,输出多种标准频率与时间信号。设备可输出前沿陡直、平顶稳定的标准矩形刺激波,波宽与输出电压连续可调,支持单次、双次、定时、连续等多种刺激输…

2026/10/13 6:59:55 阅读更多 →
MCP基本使用

MCP基本使用

MCP版本用日期定义,最早的正式版本2024-11-05,截止当前最新的是2026-07-28(这一版协议有根本性改动,Python SDK需要使用 v2)。下面的概念是针对 2024-11-05 版的,2026-07-28 变成无状态协议了,下…

2026/10/13 6:59:55 阅读更多 →
企业微信 AI 客服答不准怎么办?兜底话术与置信度阈值

企业微信 AI 客服答不准怎么办?兜底话术与置信度阈值

客户问的是一款产品的偏门参数,AI 一本正经地答错了。这种错比不回复更伤:客户按错信息做了决定,回头算在品牌头上。答不准通常不是模型变笨,而是两件事没配好——该兜底的时候它硬答,该收进知识库的问题它够不着。## …

2026/10/13 6:59:55 阅读更多 →
恶意代码概述

恶意代码概述

1. 计算机病毒(Virus)核心特点:必须依附文件,需要人为触发,不能自己网上传播 原理:寄生在正常文件里(exe / 文档)。必须用户手动打开这个带毒文件,病毒才会激活&#xff…

2026/10/13 6:59:55 阅读更多 →
恶意代码检测毕设实战:PE特征提取与机器学习模型训练

恶意代码检测毕设实战:PE特征提取与机器学习模型训练

简介:这份资源是一套基于机器学习的恶意代码检测项目源码,面向计算机、人工智能、通信工程、自动化等专业的在校学生与教师,也适合作为毕设、课程设计或项目立项演示的参考。项目围绕恶意代码的特征提取、向量化与模型训练展开,涵…

2026/10/13 6:58:55 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →