Next.js 14集成NextAuth.js实现安全认证
1. Next.js 14与NextAuth.js集成概述在Next.js 14项目中引入NextAuth.js现称Auth.js进行用户认证已经成为现代Web开发的标准实践。这套组合拳完美解决了React应用中的身份验证难题特别是对于需要服务端渲染的应用场景。NextAuth.js作为专门为Next.js设计的认证库提供了开箱即用的OAuth集成、数据库会话管理以及完整的TypeScript支持。我最近在一个电商后台管理系统项目中实际应用了这套方案。相比传统的JWT自行实现方案NextAuth.js显著降低了开发复杂度特别是在处理第三方登录如Google、GitHub时配置时间从原来的2-3天缩短到2小时内。其内置的CSRF保护和加密Cookie机制也让安全性得到了专业级的保障。2. 环境准备与基础配置2.1 创建Next.js 14项目首先确保你的开发环境满足以下要求Node.js 18或更高版本npm 9.x / yarn 1.x / pnpm 7.x已安装Git使用以下命令创建新项目npx create-next-applatest my-auth-app --typescript --tailwind cd my-auth-app2.2 安装NextAuth.js目前NextAuth.js正处于v5 beta阶段提供了更好的App Router支持。安装时需要注意版本指定npm install next-authbeta # 或 yarn add next-authbeta # 或 pnpm add next-authbeta2.3 基础配置结构在项目根目录创建auth配置// auth.ts import NextAuth from next-auth export const { handlers: { GET, POST }, auth, signIn, signOut, } NextAuth({ providers: [ // 后续在此添加认证提供商 ], })创建API路由文件// app/api/auth/[...nextauth]/route.ts import { handlers } from /auth export const { GET, POST } handlers3. 认证提供商配置实战3.1 配置GitHub OAuth首先在GitHub开发者设置中创建OAuth应用访问GitHub Settings Developer settings OAuth Apps设置回调URL为http://localhost:3000/api/auth/callback/github然后在auth.ts中添加配置import GitHub from next-auth/providers/github providers: [ GitHub({ clientId: process.env.GITHUB_ID as string, clientSecret: process.env.GITHUB_SECRET as string, }), ],3.2 配置Google OAuthGoogle Cloud控制台配置步骤创建OAuth 2.0客户端ID设置授权JavaScript来源和重定向URI启用Google APIauth.ts配置示例import Google from next-auth/providers/google providers: [ Google({ clientId: process.env.GOOGLE_ID as string, clientSecret: process.env.GOOGLE_SECRET as string, }), ],3.3 邮箱密码认证对于需要传统登录方式的场景可以配置CredentialsProviderimport Credentials from next-auth/providers/credentials providers: [ Credentials({ name: Credentials, credentials: { email: { label: Email, type: text }, password: { label: Password, type: password } }, async authorize(credentials) { // 这里添加你的认证逻辑 const user await authenticateUser( credentials.email, credentials.password ) return user || null } }) ],4. 会话管理与用户信息获取4.1 基础会话使用在页面组件中获取会话信息// app/page.tsx import { auth } from /auth export default async function Home() { const session await auth() return ( main {session?.user ? ( div p欢迎, {session.user.name}!/p p邮箱: {session.user.email}/p {session.user.image ( img src{session.user.image} alt用户头像 classNamew-12 h-12 rounded-full / )} /div ) : ( p请先登录/p )} /main ) }4.2 自定义会话数据通过callbacks扩展会话信息// auth.ts callbacks: { async session({ session, token }) { if (session.user) { session.user.role token.role session.user.accessToken token.accessToken } return session }, async jwt({ token, user }) { if (user) { token.role user.role } return token } }4.3 获取完整用户信息对于需要更多用户信息的场景可以通过userinfo端点获取async function fetchUserProfile(accessToken: string) { const response await fetch(https://api.github.com/user, { headers: { Authorization: Bearer ${accessToken}, Accept: application/vnd.githubjson } }) if (!response.ok) { throw new Error(获取用户信息失败) } return await response.json() }5. 高级功能实现5.1 角色访问控制(RBAC)在jwt回调中添加角色信息callbacks: { async jwt({ token, user }) { if (user) { // 从数据库获取用户角色 const dbUser await getUserById(user.id) token.role dbUser.role } return token } }然后在中间件中实现路由保护// middleware.ts import { auth } from /auth import { NextResponse } from next/server export default auth((req) { const { pathname } req.nextUrl const session req.auth // 保护/admin路由 if (pathname.startsWith(/admin) session?.user.role ! admin) { return NextResponse.redirect(new URL(/denied, req.url)) } return NextResponse.next() }) export const config { matcher: [/((?!api|_next/static|_next/image|favicon.ico).*)] }5.2 自定义登录页面创建自定义登录页// app/login/page.tsx import { signIn } from /auth export default function LoginPage() { return ( div classNameflex flex-col gap-4 form action{async () { use server await signIn(github) }} button typesubmit classNamebtn GitHub登录 /button /form form action{async () { use server await signIn(google) }} button typesubmit classNamebtn Google登录 /button /form /div ) }5.3 数据库适配器安装Prisma适配器npm install next-auth/prisma-adapter prisma/client配置Prisma schemamodel User { id String id default(cuid()) name String? email String? unique emailVerified DateTime? image String? accounts Account[] sessions Session[] } model Account { id String id default(cuid()) userId String type String provider String providerAccountId String refresh_token String? access_token String? expires_at Int? token_type String? scope String? id_token String? session_state String? user User relation(fields: [userId], references: [id], onDelete: Cascade) unique([provider, providerAccountId]) } model Session { id String id default(cuid()) sessionToken String unique userId String expires DateTime user User relation(fields: [userId], references: [id], onDelete: Cascade) }初始化适配器import { PrismaAdapter } from next-auth/prisma-adapter import { PrismaClient } from prisma/client const prisma new PrismaClient() export default NextAuth({ adapter: PrismaAdapter(prisma), // ...其他配置 })6. 生产环境最佳实践6.1 安全配置关键安全设置export default NextAuth({ secret: process.env.AUTH_SECRET, session: { strategy: jwt, maxAge: 30 * 24 * 60 * 60, // 30天 updateAge: 24 * 60 * 60 // 24小时 }, cookies: { sessionToken: { name: __Secure-next-auth.session-token, options: { httpOnly: true, sameSite: lax, path: /, secure: true } } } })6.2 性能优化实现无状态JWT会话export default NextAuth({ session: { strategy: jwt }, jwt: { maxAge: 30 * 24 * 60 * 60 } })6.3 错误处理自定义错误页面// app/auth/error/page.tsx use client import { useEffect } from react import { useSearchParams } from next/navigation export default function AuthErrorPage() { const searchParams useSearchParams() const error searchParams.get(error) const errorMessages { OAuthSignin: 登录初始化失败, OAuthCallback: 回调处理失败, OAuthCreateAccount: 创建用户失败, EmailCreateAccount: 创建用户失败, Callback: 回调处理失败, OAuthAccountNotLinked: 账号未关联, EmailSignin: 邮件发送失败, CredentialsSignin: 凭据验证失败, SessionRequired: 需要登录, Default: 未知错误 } return ( div classNameerror-container h2登录错误/h2 p{errorMessages[error as keyof typeof errorMessages] || errorMessages.Default}/p /div ) }7. 常见问题与解决方案7.1 会话状态不一致典型症状前端显示已登录但后端获取不到会话 解决方案检查中间件配置是否正确确保NEXTAUTH_URL环境变量设置正确验证Cookie域和路径配置7.2 第三方登录回调失败排查步骤检查回调URL是否与提供商配置完全一致验证OAuth客户端ID和密钥是否正确确保提供商的应用配置了正确的重定向URI7.3 生产环境HTTPS问题解决方案// auth.ts export default NextAuth({ useSecureCookies: process.env.NODE_ENV production, trustHost: true })7.4 类型扩展问题扩展Session和JWT类型// auth.ts declare module next-auth { interface Session { user: { id: string role: string } DefaultSession[user] } interface User { role: string } } declare module next-auth/jwt { interface JWT { role: string } }8. 实际项目经验分享在最近的企业级项目中我们遇到了几个值得分享的案例案例一多租户系统实现 通过扩展JWT token添加organization_id字段配合数据库查询实现数据隔离。关键代码callbacks: { async jwt({ token, user }) { if (user) { const org await getUserOrganization(user.id) token.organizationId org.id } return token } }案例二混合认证策略 同时支持OAuth和传统账号密码登录时处理账号合并的逻辑async authorize(credentials) { // 查找已有账号 const user await findUserByEmail(credentials.email) if (user) { // 验证密码 const isValid await verifyPassword(user.password, credentials.password) return isValid ? user : null } else { // 创建新账号 return await createUser(credentials) } }案例三性能优化 对于高并发系统我们实现了Redis缓存会话import { RedisAdapter } from next-auth/redis-adapter import { createClient } from redis const redisClient createClient({ url: process.env.REDIS_URL }) export default NextAuth({ adapter: RedisAdapter(redisClient), // ...其他配置 })9. 测试与调试技巧9.1 开发环境调试推荐调试配置logger: { error(code, metadata) { console.error(code, metadata) }, warn(code) { console.warn(code) }, debug(code, metadata) { console.debug(code, metadata) } }9.2 自动化测试编写集成测试示例import { test, expect } from playwright/test test(认证流程测试, async ({ page }) { await page.goto(/) // 点击登录按钮 await page.click(textSign in with GitHub) // 模拟GitHub登录 await page.fill(input[namelogin], process.env.TEST_GITHUB_USER) await page.fill(input[namepassword], process.env.TEST_GITHUB_PASS) await page.click(input[namecommit]) // 验证登录成功 await expect(page.locator(text欢迎回来)).toBeVisible() })9.3 监控与日志推荐监控指标认证成功率/失败率平均认证耗时各提供商使用占比异常错误统计10. 升级与迁移策略10.1 从NextAuth.js v4迁移到v5主要变更点配置文件从[...nextauth].ts移动到auth.ts提供者配置语法变化新增App Router支持迁移步骤安装新版本npm install next-authbeta创建新的auth.ts配置文件更新提供者配置语法测试所有认证流程10.2 从其他方案迁移从Firebase Auth迁移示例导出Firebase用户数据创建密码哈希映射表实现自定义CredentialsProvider逐步切换认证入口点11. 扩展与自定义开发11.1 自定义提供者实现企业微信提供者示例import type { NextAuthConfig } from next-auth export function WeComProvider(options: { clientId: string clientSecret: string corpId: string }): NextAuthConfig { return { id: wecom, name: 企业微信, type: oauth, authorization: { url: https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid${options.clientId}agentid${options.corpId}redirect_uri }, token: https://qyapi.weixin.qq.com/cgi-bin/gettoken, userinfo: https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo, // ...其他OAuth配置 } }11.2 多因素认证实现短信验证码二次验证callbacks: { async signIn({ user, account, profile }) { if (account?.provider ! credentials) return true // 检查是否已通过短信验证 const session await getSmsSession(user.id) if (!session?.verified) { return /sms-verify // 重定向到验证页面 } return true } }11.3 无密码认证实现魔法链接登录import { createTransport } from nodemailer const transporter createTransport({ service: SendGrid, auth: { user: process.env.EMAIL_USER, pass: process.env.EMAIL_PASSWORD } }) async function sendMagicLink(email: string, url: string) { await transporter.sendMail({ to: email, subject: 您的登录链接, html: 点击a href${url}此处/a登录 }) }12. 性能优化进阶12.1 会话存储优化使用内存缓存高频访问的会话import LRU from lru-cache const sessionCache new LRU({ max: 1000, ttl: 1000 * 60 * 5 // 5分钟 }) callbacks: { async session({ session, token }) { const cached sessionCache.get(session.user.email) if (cached) return cached const fullSession await fetchFullSession(session) sessionCache.set(session.user.email, fullSession) return fullSession } }12.2 数据库查询优化为认证相关查询添加索引model User { index([email]) index([createdAt]) } model Account { unique([provider, providerAccountId]) index([userId]) } model Session { index([sessionToken]) index([userId]) index([expires]) }12.3 CDN缓存策略配置合理的缓存头// middleware.ts export function middleware(req: NextRequest) { const res NextResponse.next() if (req.nextUrl.pathname.startsWith(/_next/static)) { res.headers.set(Cache-Control, public, max-age31536000, immutable) } return res }13. 安全加固措施13.1 防止暴力破解实现登录限流import rateLimit from express-rate-limit const limiter rateLimit({ windowMs: 15 * 60 * 1000, // 15分钟 max: 5, // 每个IP最多5次请求 message: 尝试次数过多请稍后再试 }) // 在登录路由应用 export const config { api: { bodyParser: false, externalResolver: true } }13.2 敏感操作验证关键操作二次验证async function requireReauth(action: string, userId: string) { const lastAuth await getLastAuthTime(userId) if (Date.now() - lastAuth 5 * 60 * 1000) { await sendVerificationCode(userId) throw new Error(需要重新验证) } await logSecurityAction(userId, action) }13.3 安全头设置增强HTTP安全头// next.config.js module.exports { async headers() { return [ { source: /(.*), headers: [ { key: X-Frame-Options, value: SAMEORIGIN }, { key: X-Content-Type-Options, value: nosniff }, { key: Referrer-Policy, value: strict-origin-when-cross-origin } ] } ] } }14. 国际化支持14.1 多语言认证界面根据用户语言偏好显示不同文案// auth.ts import { i18n } from ./i18n-config export default NextAuth({ theme: { brandColor: #3b82f6, colorScheme: auto, buttonText: (params: { locale?: string }) { return i18n[params.locale || en].signIn } } })14.2 本地化错误消息映射错误代码到多语言const errorMessages { en: { OAuthSignin: Error in signin process, // ... }, zh: { OAuthSignin: 登录过程出错, // ... } } function getErrorMessage(code: string, locale: string) { return errorMessages[locale]?.[code] || errorMessages.en[code] || Unknown error }15. 移动端适配15.1 深度链接支持配置移动端回调// auth.ts providers: [ Google({ clientId: process.env.GOOGLE_ID, clientSecret: process.env.GOOGLE_SECRET, authorization: { params: { redirect_uri: Platform.select({ ios: yourapp://oauth/google, android: yourapp://oauth/google, default: ${process.env.NEXTAUTH_URL}/api/auth/callback/google }) } } }) ]15.2 生物识别认证集成Face ID/Touch IDimport * as LocalAuthentication from expo-local-authentication async function authenticateWithBiometrics() { const hasHardware await LocalAuthentication.hasHardwareAsync() const isEnrolled await LocalAuthentication.isEnrolledAsync() if (!hasHardware || !isEnrolled) { return false } const result await LocalAuthentication.authenticateAsync({ promptMessage: 请验证身份, fallbackLabel: 使用密码 }) return result.success }16. 数据分析与监控16.1 认证事件追踪记录关键指标callbacks: { async signIn({ user, account, profile }) { trackEvent(sign_in, { provider: account.provider, user_id: user.id, method: account.type }) return true } }16.2 异常行为检测识别可疑登录尝试async function checkSuspiciousActivity(ip: string, userAgent: string, userId: string) { const lastLogin await getLastLogin(userId) if (lastLogin.ip ! ip || lastLogin.userAgent ! userAgent) { await sendSecurityAlert(userId, { type: new_device, ip, userAgent }) } }17. 服务器端渲染优化17.1 认证数据预取在getServerSideProps中获取会话export async function getServerSideProps(context) { const session await unstable_getServerSession( context.req, context.res, authOptions ) if (!session) { return { redirect: { destination: /login, permanent: false } } } return { props: { session } } }17.2 静态生成优化处理认证状态的静态生成export async function getStaticProps() { return { props: { // 传递基础数据 }, revalidate: 60 // ISR每60秒重新验证 } }18. 微服务架构集成18.1 分布式会话管理使用Redis存储共享会话import { RedisStore } from auth/redis-adapter import { createClient } from redis const redisClient createClient({ url: process.env.REDIS_URL }) export default NextAuth({ adapter: RedisStore(redisClient), // ...其他配置 })18.2 服务间认证生成服务间访问令牌async function generateServiceToken(serviceName: string) { const now Math.floor(Date.now() / 1000) const payload { iss: auth-service, sub: serviceName, iat: now, exp: now 3600 // 1小时有效 } return jwt.sign(payload, process.env.SERVICE_SECRET) }19. 无服务器架构适配19.1 Serverless部署配置Vercel部署注意事项// vercel.json { rewrites: [ { source: /api/auth/(.*), destination: /api/auth/[...nextauth] } ] }19.2 冷启动优化预加载认证模块// api/_init.ts import /auth export default function init() { // 预加载模块 }20. 未来演进方向20.1 Web3认证集成支持钱包登录import { EthereumProvider } from walletconnect/ethereum-provider const provider await EthereumProvider.init({ projectId: process.env.WALLETCONNECT_ID, chains: [1], showQrModal: true }) provider.on(connect, (accounts) { // 处理钱包连接 })20.2 密码学增强探索WebAuthn集成import { generateRegistrationOptions } from simplewebauthn/server async function startWebAuthnRegistration(userId: string) { return generateRegistrationOptions({ rpName: My App, rpID: window.location.hostname, userID: userId, userName: user.email, attestationType: none }) }20.3 AI驱动的安全防护异常行为识别async function analyzeLoginPattern(userId: string, currentLogin: LoginData) { const history await getLoginHistory(userId) const model await loadAnomalyDetectionModel() const features extractFeatures(currentLogin, history) const score model.predict(features) if (score THRESHOLD) { await triggerSecurityReview(userId) } }

相关新闻

Homebrew 入门与深度实践:macOS 包管理核心指南

Homebrew 入门与深度实践:macOS 包管理核心指南

1. 项目概述:为什么 macOS 用户绕不开 Homebrew 这个“包管理中枢” Homebrew 是 macOS 生态里最成熟、最被广泛信任的开源包管理器,它不是可有可无的“小工具”,而是现代 macOS 开发者、运维人员、数据工程师甚至设计师日常工作的基础设施级…

2026/10/12 21:33:11 阅读更多 →
3步搞定EmailEngine Webhook:让邮件事件驱动你的业务自动化 [特殊字符]

3步搞定EmailEngine Webhook:让邮件事件驱动你的业务自动化 [特殊字符]

3步搞定EmailEngine Webhook:让邮件事件驱动你的业务自动化 🚀 【免费下载链接】emailengine Headless email client 项目地址: https://gitcode.com/gh_mirrors/em/emailengine 还在手动检查邮箱吗?EmailEngine的Webhook功能能让你的…

2026/10/8 7:30:43 阅读更多 →
2024主流AI编程助手评测与选型指南

2024主流AI编程助手评测与选型指南

1. 主流IDE集成AI工具全景概览在2024年的开发现场,AI编程助手已经成为IDE生态中不可或缺的组成部分。Claude Code作为Anthropic推出的专业级工具,确实在代码理解与生成质量上表现出色,但其区域限制和商业化策略让不少开发者开始寻找替代方案。…

2026/10/7 20:44:35 阅读更多 →

最新新闻

OpenClaw 跨平台部署指南:Windows/macOS/Linux 环境搭建避坑全记录

OpenClaw 跨平台部署指南:Windows/macOS/Linux 环境搭建避坑全记录

如果你准备把 OpenClaw 真正用起来,第一道门槛往往不是模型接入,也不是技能配置,而是环境搭建。我见过太多人卡在“装好了但跑不动”“这台能跑换台就崩”的阶段,尤其是在 Windows、macOS、Linux 三套系统之间反复横跳的时候&…

2026/10/13 5:59:40 阅读更多 →
MOE框架详解与实现

MOE框架详解与实现

1. 简介 MoE 是一种将多个子模型(专家)结合的技术,用于提升大语言模型(LLMs)性能。它主要由稀疏 MoE 层和门控网络(路由)组成。稀疏 MoE 层替代传统 Transformer 中的前馈神经网络(FFN)层,包含多个独立的专家网络,每个专家都是一个 FFN。门控网络负责决定输入的 tok…

2026/10/13 5:59:40 阅读更多 →
支付宝模拟器 高仿支付宝 单机版APP 装逼神器

支付宝模拟器 高仿支付宝 单机版APP 装逼神器

这是用uni-app开发的一款单机版的高仿支付宝App这是一个高仿支付宝的单机版app,可以更换头像,用户名,账号,添加账单,设置余额,设置花呗等。 链接地址:项目地址点击这里 直接上截图

2026/10/13 5:59:40 阅读更多 →
贾子猜想(Kucius Conjecture):高维数论的宇宙密码与人类认知边界的探索

贾子猜想(Kucius Conjecture):高维数论的宇宙密码与人类认知边界的探索

贾子猜想(Kucius Conjecture)由鸽姆智库创始人Kucius Teng(贾子邓,读音gǔ zǐ)于2025年3月28日(黄帝4722年二月廿九日)提出,结合代数几何、模形式与量子计算,探讨其与宇…

2026/10/13 5:59:40 阅读更多 →
蓝鲸配置平台 bk-cmdb 开放接口实战:批量更新进程实例(update_process_instance)

蓝鲸配置平台 bk-cmdb 开放接口实战:批量更新进程实例(update_process_instance)

后端企业应用运维 【免费下载链接】bk-cmdb 蓝鲸智云配置平台(BlueKing CMDB) 项目地址: https://gitcode.com/gh_mirrors/bk/bk-cmdb 点击查看 免费下载 本篇文章以 update_process_instance.md(中文版见 update_process_instance.md)为骨架…

2026/10/13 5:59:40 阅读更多 →
MIPI D-PHY物理层调试:从CTS FAIL定位信号完整性根因

MIPI D-PHY物理层调试:从CTS FAIL定位信号完整性根因

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

2026/10/13 5:58:39 阅读更多 →

日新闻

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

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

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

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 阅读更多 →