状态
包状态为 当前包。Svelte 5 store、SvelteKit 服务端 hook 和辅助工具已实现。在真实生产基础设施上的 IdP 往返验证仍待人工核实。
客户端配置
在根布局中使用 createXidStores 和 setXidContext 创建 store。Store 使用 XidClient.subscribe,满足 Svelte store 订阅者契约。
<!-- +layout.svelte -->
<script lang="ts">
import { setContext, onMount } from 'svelte'
import { XidClient, createXidStores, setXidContext } from '@xid-kit/svelte'
const client = new XidClient({ apiUrl: 'https://acme.xid.dev' })
const stores = createXidStores(client)
setXidContext(setContext, stores)
onMount(() => {
const ac = new AbortController()
void client.load({ signal: ac.signal })
return () => ac.abort()
})
</script>
<slot />读取认证状态
<!-- Any child component -->
<script lang="ts">
import { getContext } from 'svelte'
import { getXidContext } from '@xid-kit/svelte'
const { auth, user } = getXidContext(getContext)
// $auth: { isLoaded, isSignedIn, userId, sessionId, session }
// $user: discriminated union on isLoaded / isSignedIn / user
</script>
{#if !$auth.isLoaded}
<p>Loading...</p>
{:else if $auth.isSignedIn}
<p>Hello, {$user.isSignedIn ? $user.user.fullName : ''}</p>
{:else}
<p>Not signed in</p>
{/if}登录与登出
<script lang="ts">
import { getContext } from 'svelte'
import { getXidContext, buildSignInUrl, executeSignOut } from '@xid-kit/svelte'
const { client } = getXidContext(getContext)
function handleSignIn() {
window.location.assign(buildSignInUrl('/sign-in', window.location.href))
}
async function handleSignOut() {
await executeSignOut(client, { redirectUrl: '/' })
}
</script>角色与权限守卫
<script lang="ts">
import { getContext } from 'svelte'
import { getXidContext, isAllowed } from '@xid-kit/svelte'
const { state } = getXidContext(getContext)
</script>
{#if isAllowed($state, { role: 'org:admin' })}
<AdminPanel />
{/if}
{#if isAllowed($state, { permission: 'org:member:write' })}
<EditButton />
{/if}SvelteKit 服务端 hook
// src/hooks.server.ts
import { handleXid } from '@xid-kit/svelte/server'
export const handle = handleXid({
jwtKey: JSON.parse(process.env.XID_JWT_KEY!),
issuer: 'https://xid.dev',
protectedRoutes: ['/dashboard', '/account'],
signInUrl: '/sign-in',
})在 load 函数中读取认证信息
// +page.server.ts
import { redirect } from '@sveltejs/kit'
import { getXidAuth } from '@xid-kit/svelte/server'
import type { PageServerLoad } from './$types'
export const load: PageServerLoad = async ({ locals }) => {
const auth = getXidAuth(locals)
if (!auth.userId) throw redirect(303, '/sign-in')
return { userId: auth.userId, orgId: auth.orgId }
}App.Locals 类型定义
// src/app.d.ts
import type { AuthResult } from '@xid-kit/svelte/server'
declare global {
namespace App {
interface Locals {
xidAuth: AuthResult
}
}
}
export {}导出的 API
| 导出 | 类型 | 模块 |
|---|---|---|
XidClient, createXidStores, setXidContext, getXidContext |
客户端配置 | @xid-kit/svelte |
buildSignInUrl, executeSignOut, isAllowed |
工具函数 | @xid-kit/svelte |
handleXid, getXidAuth |
服务端 hook | @xid-kit/svelte/server |