Token导航 LogoToken导航

Agent Skill · 前端设计

bknd-login-flow(bknd 登录流程)

bknd-login-flow 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

bknd-login-flow 是前端设计类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为接触敏感数据;许可证信息还不明确,第三方扫描有未通过项,按安装量在前端设计类的 10,216 个 Skill 里排第 7,287。

总安装 392周安装 16GitHub Stars 3下载 127核验 2026-05-01

安装说明

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

安装方式

通过对话安装

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

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

命令行安装

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

skills.shnpx skills
npx skills add https://github.com/cameronapak/bknd-skills --skill bknd-login-flow

这个 Skill 是做什么的

前端设计类 Skill 关注页面结构、视觉规范和组件写法,输出通常是可运行的界面代码。

用于实现用户登录、登出和会话检查的认证流程。支持密码策略和 OAuth 集成,适用于前端表单和状态管理。可通过 SDK 或 React 组件构建登录界面与鉴权逻辑。需先启用认证并配置至少一种策略如密码或第三方登录。bknd-login-flow 属于前端设计类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/bknd-login-flow

上手步骤

4 步
  1. 1

    确认自己的宿主工具

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

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/cameronapak/bknd-skills --skill bknd-login-flo…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

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

  4. 4

    按最小权限试用

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

常见问题

6 条

bknd-login-flow 怎么安装?

在终端执行 npx skills add https://github.com/cameronapak/bknd-skills --skill bknd-login-flow。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

bknd-login-flow 支持哪些 AI 工具?

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

bknd-login-flow 需要什么权限?

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

bknd-login-flow 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

bknd-login-flow 用的人多吗?

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

bknd-login-flow 安全吗?

第三方扫描有未通过项,风险较高。除非你确认过源码,否则不建议直接安装到常用环境。

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

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。

先想清楚的地方

  • 需要接触敏感数据,装到常用环境前要先评估影响面。
  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方扫描存在提醒项或未通过项,需要人工逐条确认。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

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

不太适合

  • 环境里有大量密钥、凭证,不方便给第三方 Skill 读取的人。
  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

前端设计类 Skill 对比

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

前端设计 · Codex、Claude

8,823,360126,072只读MIT通过
vercel-composition-patterns

Vercel 组合模式 · Codex、Claude

3,858,81625,893需要联网MIT通过
vercel-react-native-skills

Vercel React native skills 前端 · Codex、Claude

2,468,66425,878只读MIT通过
adapt

adapt 搜索 · Codex、Claude

2,027,04023,125操作浏览器未明确通过
bolder

bolder 分析 · Codex、Claude

2,004,28823,130只读未明确通过
bknd-login-flow

bknd 登录流程 · 本页

3923接触敏感数据未明确未通过

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

SKILL.md 原文

Login/Logout Flow

Implement user authentication flow with login, logout, and session checking in Bknd.

Prerequisites

  • Bknd project with auth enabled (bknd-setup-auth)
  • At least one auth strategy configured (password, OAuth)
  • For SDK: bknd package installed
  • For React: @bknd/react package installed

When to Use UI Mode

  • Testing login/logout endpoints via admin panel
  • Viewing active sessions
  • Checking user authentication status

UI steps: Admin Panel > Auth > Test endpoints

When to Use Code Mode

  • Implementing login forms in your frontend
  • Adding logout functionality
  • Checking authentication state
  • Building protected routes
  • Handling authentication errors

SDK Approach

Initialize API Client

import { Api } from "bknd";

const api = new Api({
  host: "http://localhost:7654",
  storage: localStorage,  // Persist token between sessions
});

SDK options:

OptionTypeDescription
hoststringBackend URL
storageStorageToken persistence (localStorage, sessionStorage)
tokenstringPre-set auth token
tokenTransport"header" \"cookie"How token is sent (default: header)

Login with Password Strategy

async function login(email: string, password: string) {
  const { ok, data, error, status } = await api.auth.login("password", {
    email,
    password,
  });

  if (ok) {
    // Token automatically stored in localStorage
    console.log("Logged in as:", data.user.email);
    console.log("User ID:", data.user.id);
    console.log("Role:", data.user.role);
    return data.user;
  }

  // Handle errors
  if (status === 401) {
    throw new Error("Invalid email or password");
  }
  if (status === 403) {
    throw new Error("Account uses different login method");
  }
  throw new Error(error?.message || "Login failed");
}

Login response:

type LoginResponse = {
  ok: boolean;
  status: number;
  data?: {
    user: {
      id: number | string;
      email: string;
      role?: string;
      // Custom fields...
    };
    token: string;
  };
  error?: { message: string };
};

Check Current User

async function getCurrentUser() {
  const { ok, data } = await api.auth.me();

  if (ok && data?.user) {
    return data.user;  // User is authenticated
  }
  return null;  // Not authenticated
}

Logout

async function logout() {
  await api.auth.logout();
  // Token removed from storage
  // User is now logged out
}

Check If Authenticated

async function isAuthenticated(): Promise<boolean> {
  const { ok, data } = await api.auth.me();
  return ok && data?.user !== null;
}

Complete Login Flow Example

import { Api } from "bknd";

class AuthService {
  private api: Api;

  constructor() {
    this.api = new Api({
      host: import.meta.env.VITE_API_URL || "http://localhost:7654",
      storage: localStorage,
    });
  }

  async login(email: string, password: string) {
    const result = await this.api.auth.login("password", { email, password });

    if (!result.ok) {
      throw new AuthError(result.status, result.error?.message);
    }

    return result.data!.user;
  }

  async logout() {
    await this.api.auth.logout();
  }

  async getUser() {
    const { ok, data } = await this.api.auth.me();
    return ok ? data?.user : null;
  }

  async isAuthenticated() {
    const user = await this.getUser();
    return user !== null;
  }
}

class AuthError extends Error {
  constructor(public status: number, message?: string) {
    super(message || "Authentication failed");
    this.name = "AuthError";
  }
}

// Usage
const auth = new AuthService();

try {
  const user = await auth.login("user@example.com", "password123");
  console.log("Welcome,", user.email);
} catch (e) {
  if (e instanceof AuthError && e.status === 401) {
    console.error("Wrong credentials");
  }
}

REST API Approach

Login via REST

# Login
curl -X POST http://localhost:7654/api/auth/password/login \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com", "password": "password123"}'

Response:

{
  "user": {
    "id": 1,
    "email": "user@example.com",
    "role": "user"
  },
  "token": "eyJhbGciOiJIUzI1NiIs..."
}

Use Token in Requests

# Get current user
curl http://localhost:7654/api/auth/me \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

# Access protected data
curl http://localhost:7654/api/data/posts \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Logout via REST

curl -X POST http://localhost:7654/api/auth/logout \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Note: Logout clears server-side cookie. For header-based auth, client must discard token.

REST Endpoints Reference

MethodPathDescription
POST/api/auth/password/loginLogin with email/password
GET/api/auth/meGet current authenticated user
POST/api/auth/logoutLog out (clear session)
GET/api/auth/strategiesList available strategies

React Integration

Using useAuth Hook

import { BkndProvider, useAuth } from "@bknd/react";

function App() {
  return (
    <BkndProvider config={{ host: "http://localhost:7654" }}>
      <AuthExample />
    </BkndProvider>
  );
}

function AuthExample() {
  const { user, isLoading, login, logout } = useAuth();

  if (isLoading) {
    return <div>Loading...</div>;
  }

  if (!user) {
    return <LoginForm onLogin={login} />;
  }

  return (
    <div>
      <p>Welcome, {user.email}!</p>
      <button onClick={logout}>Logout</button>
    </div>
  );
}

Login Form Component

import { useState } from "react";
import { useAuth } from "@bknd/react";

function LoginForm() {
  const { login } = useAuth();
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState<string | null>(null);
  const [isSubmitting, setIsSubmitting] = useState(false);

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setError(null);
    setIsSubmitting(true);

    try {
      await login("password", { email, password });
      // Redirect or update UI - user state updates automatically
    } catch (err) {
      setError(err instanceof Error ? err.message : "Login failed");
    } finally {
      setIsSubmitting(false);
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      {error && <div className="error">{error}</div>}

      <label>
        Email:
        <input
          type="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          required
        />
      </label>

      <label>
        Password:
        <input
          type="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
          required
        />
      </label>

      <button type="submit" disabled={isSubmitting}>
        {isSubmitting ? "Logging in..." : "Login"}
      </button>
    </form>
  );
}

Protected Route Pattern

import { Navigate } from "react-router-dom";
import { useAuth } from "@bknd/react";

function ProtectedRoute({ children }: { children: React.ReactNode }) {
  const { user, isLoading } = useAuth();

  if (isLoading) {
    return <div>Loading...</div>;
  }

  if (!user) {
    return <Navigate to="/login" replace />;
  }

  return <>{children}</>;
}

// Usage with React Router
function AppRoutes() {
  return (
    <Routes>
      <Route path="/login" element={<LoginPage />} />
      <Route
        path="/dashboard"
        element={
          <ProtectedRoute>
            <DashboardPage />
          </ProtectedRoute>
        }
      />
    </Routes>
  );
}

Logout Button Component

import { useAuth } from "@bknd/react";
import { useNavigate } from "react-router-dom";

function LogoutButton() {
  const { logout } = useAuth();
  const navigate = useNavigate();

  async function handleLogout() {
    await logout();
    navigate("/login");
  }

  return <button onClick={handleLogout}>Logout</button>;
}

Manual API with React

If not using @bknd/react:

import { useState, useEffect, createContext, useContext } from "react";
import { Api } from "bknd";

type User = { id: number; email: string; role?: string };

type AuthContextType = {
  user: User | null;
  isLoading: boolean;
  login: (email: string, password: string) => Promise<void>;
  logout: () => Promise<void>;
};

const AuthContext = createContext<AuthContextType | null>(null);

const api = new Api({
  host: "http://localhost:7654",
  storage: localStorage,
});

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [user, setUser] = useState<User | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  // Check auth on mount
  useEffect(() => {
    api.auth.me().then(({ ok, data }) => {
      setUser(ok ? data?.user ?? null : null);
      setIsLoading(false);
    });
  }, []);

  async function login(email: string, password: string) {
    const { ok, data, error } = await api.auth.login("password", {
      email,
      password,
    });

    if (!ok) {
      throw new Error(error?.message || "Login failed");
    }

    setUser(data!.user);
  }

  async function logout() {
    await api.auth.logout();
    setUser(null);
  }

  return (
    <AuthContext.Provider value={{ user, isLoading, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  const context = useContext(AuthContext);
  if (!context) throw new Error("useAuth must be used within AuthProvider");
  return context;
}

Cookie-Based Authentication

For browser apps with cookie transport:

const api = new Api({
  host: "http://localhost:7654",
  tokenTransport: "cookie",  // Use cookies instead of header
});

// Login sets httpOnly cookie automatically
await api.auth.login("password", { email, password });

// Subsequent requests include cookie automatically
await api.data.readMany("posts");

// Logout clears cookie
await api.auth.logout();

Cookie mode benefits:

  • HttpOnly cookies not accessible via JavaScript (XSS protection)
  • Automatic renewal on requests (if configured)
  • No manual token management

Error Handling

Error Codes

StatusMeaningCommon Cause
400Bad RequestMissing email/password
401UnauthorizedInvalid credentials
403ForbiddenWrong strategy, disabled account
409ConflictAccount uses different login method

Handling Specific Errors

async function handleLogin(email: string, password: string) {
  const { ok, status, error } = await api.auth.login("password", {
    email,
    password,
  });

  if (ok) return;

  switch (status) {
    case 400:
      throw new Error("Please enter email and password");
    case 401:
      throw new Error("Invalid email or password");
    case 403:
      throw new Error("This account uses a different login method");
    case 409:
      throw new Error("Please use social login for this account");
    default:
      throw new Error(error?.message || "Login failed. Try again.");
  }
}

Common Patterns

Remember Me

Store token in localStorage (persistent) vs sessionStorage (per-session):

// Remember me enabled
const api = new Api({
  host: "http://localhost:7654",
  storage: localStorage,  // Persists across browser sessions
});

// Remember me disabled
const api = new Api({
  host: "http://localhost:7654",
  storage: sessionStorage,  // Cleared when tab closes
});

Auto-Refresh Token

If using short-lived tokens, refresh before expiry:

async function withAuth<T>(fn: () => Promise<T>): Promise<T> {
  try {
    return await fn();
  } catch (e) {
    // If 401, attempt refresh and retry
    if (e instanceof Error && e.message.includes("401")) {
      const { ok } = await api.auth.me();  // Refresh token
      if (ok) return await fn();
    }
    throw e;
  }
}

Redirect After Login

// Store intended destination
const redirectUrl = new URLSearchParams(window.location.search).get("redirect");

async function login(email: string, password: string) {
  await api.auth.login("password", { email, password });

  // Redirect to original destination or default
  window.location.href = redirectUrl || "/dashboard";
}

Common Pitfalls

Token Not Persisted

Problem: User logged out after page refresh

Fix: Provide storage option to API client:

// Wrong - token lost on refresh
const api = new Api({ host: "http://localhost:7654" });

// Correct - token persisted
const api = new Api({
  host: "http://localhost:7654",
  storage: localStorage,
});

CORS Errors

Problem: Login fails with CORS error

Fix: Configure CORS on backend or use same origin:

// Backend config
{
  server: {
    cors: {
      origin: ["http://localhost:3000"],
      credentials: true,
    },
  },
}

Cookie Not Set (HTTPS)

Problem: Cookie not received in browser

Fix: Disable secure for local development:

// Backend config
{
  auth: {
    cookie: {
      secure: process.env.NODE_ENV === "production",
    },
  },
}

Multiple Strategy Conflict

Problem: User signed up with different strategy

Solution: Users can only have one strategy. If they registered with OAuth, they cannot use password login. Check user's strategy first or guide to correct login method.

Verification

Test login flow:

1. Login and get token:

curl -X POST http://localhost:7654/api/auth/password/login \
  -H "Content-Type: application/json" \
  -d '{"email": "test@example.com", "password": "password123"}'

2. Use token to access protected endpoint:

curl http://localhost:7654/api/auth/me \
  -H "Authorization: Bearer <token>"

3. Verify logout clears session:

curl -X POST http://localhost:7654/api/auth/logout \
  -H "Authorization: Bearer <token>"

# Should now fail
curl http://localhost:7654/api/auth/me \
  -H "Authorization: Bearer <token>"

DOs and DON'Ts

DO:

  • Store tokens securely (localStorage or httpOnly cookie)
  • Handle all error cases in login flow
  • Show loading state during auth operations
  • Redirect users after successful login
  • Clear auth state fully on logout

DON'T:

  • Store tokens in memory only (lost on refresh)
  • Ignore error handling for login
  • Expose tokens in URLs
  • Forget to handle expired tokens
  • Mix cookie and header auth without reason

Related Skills

  • bknd-setup-auth - Configure authentication system
  • bknd-registration - Set up user registration
  • bknd-session-handling - Manage user sessions
  • bknd-oauth-setup - OAuth/social login providers
  • bknd-protect-endpoint - Secure specific endpoints

平台分布

Codex

35.07%
按下载量换算45

Claude

33.19%
按下载量换算42

Cursor

18.8%
按下载量换算24

Gemini CLI

9.98%
按下载量换算13

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

未通过

权限和风险

接触敏感数据

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

安装前确认

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

继续浏览同类 Skills