翻译:
DjangoCFG应用程序的Type-seafe API客户端和认证系统.
安装
pnpm add @djangocfg/api
条目点
| 条目 | 导入 | 说明 |
|---|---|---|
| 主要 | @djangocfg/api | API 类、类型、取取器、计划 |
| 认证 | @djangocfg/api/auth | 认证提供者、钩子、公用事业 |
| Auth 服务器 | @djangocfg/api/auth/server | Next.js 代理中间软件 |
| 存储 | @djangocfg/api/storage | Cookie/ storage 密钥; 单签入帮助器(safeNext, (中文(简体) ), deriveAuthHost, (中文(简体) ), buildSsoLoginUrl(中文(简体) ) |
| 客户 | @djangocfg/api/clients | 预配置的 API 实例 |
生成的 API 类
每个 OpenAPI 标记一个类 。 直接导入并调用静态方法 :
import {
CfgAccounts, // OTP login
CfgAccountsProfile, // Profile CRUD
CfgAccountsOauth, // GitHub OAuth
CfgAccountsAuth, // Token refresh
CfgAccountsApiKey, // API key management
CfgTotp, // TOTP devices / disable
CfgTotpSetup, // TOTP setup / confirm
CfgTotpVerify, // TOTP verify / backup
CfgTotpBackupCodes, // Backup codes
} from '@djangocfg/api';
// OTP login
const result = await CfgAccounts.cfgAccountsOtpVerifyCreate({
body: { identifier, otp },
});
// Profile
const profile = await CfgAccountsProfile.cfgAccountsProfileRetrieve();
// Token refresh
const tokens = await CfgAccountsAuth.cfgAccountsTokenRefreshCreate({
body: { refresh },
});
Auth 模块
import { AuthProvider, useAuth } from '@djangocfg/api/auth';
// Provider
<AuthProvider config={{ routes: { auth: '/auth', defaultCallback: '/private' } }}>
{children}
</AuthProvider>
// Hook
const { user, isAuthenticated, requestOTP, verifyOTP, logout } = useAuth();
Auth 钩子
import {
useAuth, // Main auth context
useAuthGuard, // Route protection
useAuthForm, // OTP form state machine
useOAuthLogin, // GitHub / Google OAuth
useOAuthProviders, // providers enabled on the server
useTwoFactor, // 2FA verification
useTwoFactorSetup, // 2FA setup flow
useTwoFactorStatus, // 2FA status / disable
useDeleteAccount, // Account deletion
} from '@djangocfg/api/auth';
警卫解决者
"spinner vs referred vs compare"的决定是纯的,可以单独检验的.
useAuthGuard (和 @djangocfg/layouts' PrivateLayout只是电线反应状态
纳入这些:
import {
resolveGuardIsLoading, // show the preloader?
shouldRedirectToAuth, // no session → send to the auth form
isForbidden, // signed in, but lacks the required privilege
resolveGuardIsAuthenticated,
type GuardInput,
} from '@djangocfg/api/auth';
GuardInput 角色门可选两个字段 : requireStaff (单位:千美元)
路线需要工作人员/管理人员)和 isAdminUser (从) useAuth() - 那个
is_staff || is_superuser 折,从来一旗.
isForbidden 是故意的,这是故意的 没有 重定向条件:会话为
有效, 因此认证形式无法修正, 重定向会循环保存的
URL (中文(简体) ). 换成一个不同的"未经授权"状态. resolveGuardIsLoading
返回时 false 曾经禁止,所以预装机 从来没有旋转它.
单一登录主机
<AuthProvider config={{ sso: true }}> (或 BaseApp auth={{ sso: true }}制造( ) auth.<apex> 唯一的登录页面
每个子域: 追随者以 ?next=<url> 他们将被派去教化众人
他们。 会话是共享的 cookie 组合在 .<apex>关闭,除非启动,并关闭 localhost (一个控制台线).
中间软件和客户端的纯助手在其中 @djangocfg/api/storage数字 : safeNext (唯一的大门用于 next, (中文(简体) ),
deriveAuthHost, (中文(简体) ), resolveSso, (中文(简体) ), buildSsoLoginUrl。 。 。 . useAuth().sso 报告情况。 细节 :
@docs/AUTHENTICATION.md。 。 。 .
存储密钥
每个浏览器存储键是 cfg.<area>.<name> (框架)或
<owner>.<area>.<name> (应用). 使用注册簿, 绝不是字面或生字 localStorage数字 :
import { CFG_KEYS, cfgStorage, createStorage } from '@djangocfg/api/storage';
cfgStorage.read(CFG_KEYS.email.key);
cfgStorage.clearAll(); // sign-out: removes personal keys
const storage = createStorage('kino');
storage.writeJSON(storage.key('player', 'volume'), 0.4);
旧密钥名称没有迁移 。 完整的规则,关键列表和交叉tabab行为:
@docs/STORAGE_KEYS.md。 。 。 .
托肯存储
代号活在共享中 auth 存储( 默认本地Storage, 可切换)
饼干:
import { auth } from '@djangocfg/api';
auth.getToken(); // current access token
auth.setStorageMode('cookie'); // SSR-readable cookie instead of localStorage
日志——意识到角色的动词
全体 @djangocfg/* consola loggers 读取了一个全局运行时级别, 所以控制台
对终端用户来说是干净的,对管理员/devs来说是动词——如大型SaaS应用.
import { applyRoleLogPolicy, setLogLevel } from '@djangocfg/api';
// Usually automatic: AuthProvider calls this on login/logout.
// admin (is_staff/is_superuser) or dev → debug; prod regular user → errors only.
applyRoleLogPolicy({ isAdmin: user?.is_staff || user?.is_superuser });
// Manual override (0 silent · 1 error · 2 warn · 3 info · 4 debug · 5 trace):
setLogLevel(0);
错误仍然流到 @djangocfg/devtools 无论控制台级别如何,所以
事件仍然不可诊断.
信封旗帜
@djangocfg/api 是最小的共享软件包,所以 env 旗帜住在这里( 单
真相来源:
import { isDev, isProd, isBrowser, isStaticBuild } from '@djangocfg/api';
类型命名空间
import type { AccountsTypes, TotpTypes } from '@djangocfg/api';
type User = AccountsTypes.User;
type Device = TotpTypes.TotpDevice;
服务器中端软件
// middleware.ts
import { proxyMiddleware } from '@djangocfg/api/auth/server';
export function middleware(request: NextRequest) {
return proxyMiddleware(request);
}
export const config = {
matcher: ['/media/:path*', '/api/:path*'],
};
环境
NEXT_PUBLIC_API_URL=http://localhost:8000
再生成客户端
# From django solution directory
make api