Token导航 LogoToken导航

Agent Skill · 研究检索

better-auth-electron(better auth Electron 搜索)

用于辅助安全审计、权限检查、凭据风险、认证流程和常见漏洞排查。它适合让 Agent 梳理敏感配置、检查依赖风险、分析鉴权逻辑或生成安全复核清单。使用时不能把工具输出直接当最终结论,涉及密钥、令牌、用户数据或生产系统时,应先确认最小权限、脱敏方式和操作边界。

better-auth-electron 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为接触敏感数据;许可证为 MIT,暂无第三方扫描结果,按安装量在研究检索类的 73,675 个 Skill 里排第 64,379。

总安装 303周安装 13GitHub Stars 公开资料未说明下载 106核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:better-auth-electron(better auth Electron 搜索)
来源仓库:https://github.com/5dlabs/cto
仓库路径:skills/better-auth-electron
安装命令:
npx skills add 5dlabs/cto --skill "better-auth-electron"
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

AgentSkills.tonpx skills
npx skills add 5dlabs/cto --skill "better-auth-electron"

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

better-auth-electron 用于辅助安全审计、权限检查、凭据风险、认证流程和常见漏洞排查,帮助梳理敏感配置。适用于应用安全审查、权限架构分析、认证流程优化等安全相关场景。

通过 npx skills add 5dlabs/cto --skill "better-auth-electron" 命令安装,需结合原始 README 核验具体用法。使用时不能把工具输出直接当最终结论,涉及密钥、令牌、用户数据或生产系统时,应先确认最小权限、脱敏方式和操作边界。

可结合来源仓库 https://github.com/5dlabs/cto/tree/main/skills/better-auth-electron 继续核验具体用法。

来源仓库内路径:skills/better-auth-electron

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add 5dlabs/cto --skill "better-auth-electron";命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要接触敏感数据,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

better-auth-electron 怎么安装?

在终端执行 npx skills add 5dlabs/cto --skill "better-auth-electron"。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

better-auth-electron 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

better-auth-electron 需要什么权限?

权限级别是接触敏感数据。该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

better-auth-electron 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

better-auth-electron 用的人多吗?

公开数据是累计安装 303 次,近一周安装 13 次,下载 106 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

better-auth-electron 安全吗?

没有查到第三方扫描结果,安全性无法从公开资料判断,安装前请自行审查源码、依赖和命令行为。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 许可证明确为 MIT,商用和分发边界好判断。

先想清楚的地方

  • 需要接触敏感数据,装到常用环境前要先评估影响面。
  • 没有第三方扫描结果,安全性只能靠自己读源码判断。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 环境里有大量密钥、凭证,不方便给第三方 Skill 读取的人。
  • 要求有安全扫描结论才肯安装的团队。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
better-auth-electron

better auth Electron 搜索 · 本页

303—接触敏感数据MIT未收录

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Better Auth - Electron Desktop Integration

Better Auth works seamlessly with Electron using the React client in the renderer process with secure IPC patterns.

AI Tooling

IMPORTANT: Before implementing Better Auth in Electron, consult:

  • AI Documentation: https://better-auth.com/llms.txt
  • MCP Server: https://mcp.chonkie.ai/better-auth/better-auth-builder/mcp

Use Context7 to look up Better Auth patterns:

get_library_docs({ libraryName: "better-auth", topic: "react client" })
get_library_docs({ libraryName: "better-auth", topic: "session management" })

Installation

# Install Better Auth and electron-store for session persistence
npm install better-auth electron-store

Architecture

┌─────────────────────────────────────────────────────┐
│                 Main Process                         │
│  - Session validation via IPC                        │
│  - Secure token storage (electron-store)             │
│  - Auth state management                             │
└───────────────────┬─────────────────────────────────┘
                    │ IPC (contextBridge)
┌───────────────────▼─────────────────────────────────┐
│              Preload Script                          │
│  - Expose safe auth APIs to renderer                 │
│  - No direct Node.js access                          │
└───────────────────┬─────────────────────────────────┘
                    │
┌───────────────────▼─────────────────────────────────┐
│              Renderer Process                        │
│  - Better Auth React client                          │
│  - UI components (React/shadcn)                      │
│  - Uses window.authApi from preload                  │
└─────────────────────────────────────────────────────┘

Backend Configuration

Your Electron app needs a Better Auth backend (can be local or remote):

Backend (server/auth.ts):

import { betterAuth } from "better-auth"
import { drizzleAdapter } from "better-auth/adapters/drizzle"
import { db } from "./db"

export const auth = betterAuth({
  database: drizzleAdapter(db, { provider: "sqlite" }),
  emailAndPassword: {
    enabled: true,
  },
  socialProviders: {
    github: {
      clientId: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
    },
  },
  // Trust Electron app origin
  trustedOrigins: [
    "app://.",          // Electron custom protocol
    "file://",          // File protocol
    "http://localhost", // Dev server
  ],
})

Main Process

main.ts:

import { app, BrowserWindow, ipcMain, shell } from "electron"
import Store from "electron-store"
import path from "path"

// Secure persistent storage for auth state
const store = new Store({
  name: "auth",
  encryptionKey: "your-encryption-key",  // Use secure key management
})

function createWindow() {
  const win = new BrowserWindow({
    width: 1200,
    height: 800,
    webPreferences: {
      preload: path.join(__dirname, "preload.js"),
      contextIsolation: true,   // REQUIRED - security
      nodeIntegration: false,   // REQUIRED - security
      sandbox: true,            // RECOMMENDED
    },
  })

  // Open OAuth callbacks in external browser
  win.webContents.setWindowOpenHandler(({ url }) => {
    if (url.startsWith("http")) {
      shell.openExternal(url)
      return { action: "deny" }
    }
    return { action: "allow" }
  })

  win.loadFile("index.html")
}

// IPC handlers for auth operations
ipcMain.handle("auth:get-stored-session", async () => {
  return store.get("session", null)
})

ipcMain.handle("auth:store-session", async (_, session) => {
  store.set("session", session)
})

ipcMain.handle("auth:clear-session", async () => {
  store.delete("session")
})

ipcMain.handle("auth:get-api-url", async () => {
  return process.env.AUTH_API_URL || "http://localhost:3000"
})

app.whenReady().then(createWindow)

Preload Script

preload.ts:

import { contextBridge, ipcRenderer } from "electron"

// Expose secure auth API to renderer
contextBridge.exposeInMainWorld("authApi", {
  // Session persistence
  getStoredSession: () => ipcRenderer.invoke("auth:get-stored-session"),
  storeSession: (session: unknown) => ipcRenderer.invoke("auth:store-session", session),
  clearSession: () => ipcRenderer.invoke("auth:clear-session"),

  // Config
  getApiUrl: () => ipcRenderer.invoke("auth:get-api-url"),

  // Events
  onAuthStateChange: (callback: (session: unknown) => void) => {
    ipcRenderer.on("auth:state-changed", (_, session) => callback(session))
  },
})

// Type declarations for renderer
declare global {
  interface Window {
    authApi: {
      getStoredSession: () => Promise<unknown>
      storeSession: (session: unknown) => Promise<void>
      clearSession: () => Promise<void>
      getApiUrl: () => Promise<string>
      onAuthStateChange: (callback: (session: unknown) => void) => void
    }
  }
}

Renderer Process (React)

Auth Client (src/lib/auth-client.ts):

import { createAuthClient } from "better-auth/react"

// Get API URL from main process
const getAuthClient = async () => {
  const baseURL = await window.authApi.getApiUrl()

  return createAuthClient({
    baseURL,
    // Custom fetch to handle Electron environment
    fetchOptions: {
      credentials: "include",
    },
  })
}

// Export singleton
let authClientPromise: ReturnType<typeof getAuthClient> | null = null

export const getClient = () => {
  if (!authClientPromise) {
    authClientPromise = getAuthClient()
  }
  return authClientPromise
}

// Hook for components
export function useAuthClient() {
  const [client, setClient] = useState<Awaited<ReturnType<typeof getAuthClient>> | null>(null)

  useEffect(() => {
    getClient().then(setClient)
  }, [])

  return client
}

Simplified Client (if API URL is static):

import { createAuthClient } from "better-auth/react"

export const authClient = createAuthClient({
  baseURL: "http://localhost:3000",  // Your auth server
})

export const { signIn, signUp, signOut, useSession } = authClient

Sign In Component

import { useState } from "react"
import { authClient } from "@/lib/auth-client"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"

export function SignIn() {
  const [email, setEmail] = useState("")
  const [password, setPassword] = useState("")
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const handleSignIn = async (e: React.FormEvent) => {
    e.preventDefault()
    setLoading(true)
    setError(null)

    const { data, error } = await authClient.signIn.email({
      email,
      password,
    })

    if (error) {
      setError(error.message)
    } else if (data?.session) {
      // Persist session to main process store
      await window.authApi.storeSession(data.session)
    }

    setLoading(false)
  }

  return (
    <Card className="w-full max-w-md mx-auto">
      <CardHeader>
        <CardTitle>Sign In</CardTitle>
      </CardHeader>
      <CardContent>
        <form onSubmit={handleSignIn} className="space-y-4">
          <Input
            type="email"
            placeholder="Email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            required
          />
          <Input
            type="password"
            placeholder="Password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
          />
          {error && <p className="text-sm text-destructive">{error}</p>}
          <Button type="submit" className="w-full" disabled={loading}>
            {loading ? "Signing in..." : "Sign In"}
          </Button>
        </form>
      </CardContent>
    </Card>
  )
}

Session Management

import { useEffect } from "react"
import { authClient } from "@/lib/auth-client"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"

export function UserMenu() {
  const { data: session, isPending } = authClient.useSession()

  // Sync session changes to main process
  useEffect(() => {
    if (session) {
      window.authApi.storeSession(session)
    }
  }, [session])

  const handleSignOut = async () => {
    await authClient.signOut()
    await window.authApi.clearSession()
  }

  if (isPending) {
    return <div className="h-8 w-8 animate-pulse rounded-full bg-muted" />
  }

  if (!session) {
    return <Button variant="outline">Sign In</Button>
  }

  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="ghost" className="relative h-8 w-8 rounded-full">
          <Avatar className="h-8 w-8">
            <AvatarImage src={session.user.image || ""} />
            <AvatarFallback>
              {session.user.name?.[0]?.toUpperCase()}
            </AvatarFallback>
          </Avatar>
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end">
        <DropdownMenuItem className="font-medium">
          {session.user.name}
        </DropdownMenuItem>
        <DropdownMenuItem className="text-muted-foreground">
          {session.user.email}
        </DropdownMenuItem>
        <DropdownMenuItem onClick={handleSignOut}>
          Sign Out
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

Restore Session on App Launch

// App.tsx - Restore session when app starts
import { useEffect, useState } from "react"
import { authClient } from "@/lib/auth-client"

export function App() {
  const [initialized, setInitialized] = useState(false)

  useEffect(() => {
    async function restoreSession() {
      // Check for stored session from previous launch
      const storedSession = await window.authApi.getStoredSession()

      if (storedSession) {
        // Validate session with server
        const { data: currentSession } = await authClient.getSession()

        if (!currentSession) {
          // Session expired, clear stored data
          await window.authApi.clearSession()
        }
      }

      setInitialized(true)
    }

    restoreSession()
  }, [])

  if (!initialized) {
    return <div>Loading...</div>
  }

  return <MainApp />
}

OAuth in Electron

For OAuth flows, open the auth URL in the system browser and handle the callback:

import { shell } from "electron"  // Main process only

// In main process - handle OAuth callback
app.setAsDefaultProtocolClient("myapp")  // Register custom protocol

app.on("open-url", (event, url) => {
  // Handle OAuth callback: myapp://auth/callback?code=...
  if (url.includes("/auth/callback")) {
    mainWindow.webContents.send("auth:oauth-callback", url)
  }
})

Security Best Practices

  1. Always use contextIsolation - Never expose Node.js to renderer
  2. Encrypt stored sessions - Use electron-store with encryption
  3. Validate sessions on startup - Check with server before trusting local state
  4. Handle OAuth via system browser - More secure than in-app browser
  5. Use sandbox mode - Additional security layer
  6. Clear sensitive data on sign out - Both in-memory and persistent storage

Documentation: https://better-auth.com/docs

平台分布

Claude Code

26.29%
按下载量换算28

windsurf

25.19%
按下载量换算27

trae

16.71%
按下载量换算18

OpenCode

13.68%
按下载量换算15

Codex

7.06%
按下载量换算7

Antigravity

3.64%
按下载量换算4

安全审计

暂无安全审计结果可展示。

权限和风险

接触敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills