Files
admin/src/actions/auth.ts

126 lines
2.9 KiB
TypeScript

"use server"
import { cookies } from "next/headers"
import type { ApiResponse } from "@/lib/api"
import type { Admin } from "@/models/admin"
import { callByDevice, callByUser } from "./base"
export type TokenResp = {
access_token: string
refresh_token: string
expires_in: number
token_type: string
scope?: string
}
export async function login(params: {
username: string
password: string
remember: boolean
}): Promise<ApiResponse<string[]>> {
const resp = await callByDevice<TokenResp>("/api/auth/token", {
grant_type: "password",
login_type: "password",
login_pool: "admin",
...params,
})
if (!resp.success) {
return resp
}
// 保存到 cookies
const data = resp.data
const cookieStore = await cookies()
cookieStore.set("admin/auth_token", data.access_token, {
httpOnly: true,
sameSite: "strict",
maxAge: Math.max(data.expires_in, 0),
})
cookieStore.set("admin/auth_refresh", data.refresh_token, {
httpOnly: true,
sameSite: "strict",
maxAge: Number.MAX_SAFE_INTEGER,
})
return {
success: true,
data: data.scope?.split(" ") || [],
}
}
export async function logout() {
const cookieStore = await cookies()
// 尝试删除后台会话
const access_token = cookieStore.get("admin/auth_token")?.value
const refresh_token = cookieStore.get("admin/auth_refresh")?.value
if (access_token && refresh_token) {
await callByUser("/api/auth/revoke", {
access_token,
refresh_token,
})
}
// 删除 cookies
cookieStore.delete("admin/auth_token")
cookieStore.delete("admin/auth_refresh")
return {
success: true,
data: undefined,
}
}
export async function getProfile() {
return await callByUser<Admin & { scopes: string[] }>("/api/auth/introspect")
}
export async function refreshAuth() {
const cookie = await cookies()
const userRefresh = cookie.get("admin/auth_refresh")?.value
console.log(userRefresh, "userRefresh")
if (!userRefresh) {
throw new Error("未授权访问")
}
// 请求刷新访问令牌
const resp = await callByDevice<TokenResp>(`/api/auth/token`, {
grant_type: "refresh_token",
refresh_token: userRefresh,
})
// 处理请求
if (!resp.success) {
if (resp.status === 401) {
cookie.delete("admin/auth_refresh")
}
throw new Error("未授权访问")
}
// 解析响应
const data = resp.data
const nextAccessToken = data.access_token
const nextRefreshToken = data.refresh_token
const expiresIn = data.expires_in
// 保存令牌到 cookies
cookie.set("admin/auth_token", nextAccessToken, {
httpOnly: true,
sameSite: "strict",
maxAge: Math.max(expiresIn, 0),
})
cookie.set("admin/auth_refresh", nextRefreshToken, {
httpOnly: true,
sameSite: "strict",
maxAge: Number.MAX_SAFE_INTEGER,
})
// 返回新的访问令牌
return {
access_token: nextAccessToken,
refresh_token: nextRefreshToken,
scopes: data.scope?.split(" ") || [],
}
}