mirror of
https://github.com/hpd840321/craftlabs-authorization-sdk.git
synced 2026-06-09 18:10:30 +08:00
103 lines
3.0 KiB
JavaScript
103 lines
3.0 KiB
JavaScript
import { defineStore } from "pinia";
|
|
import axios from "axios";
|
|
|
|
const TOKEN_KEY = "craftlabs_platform_token";
|
|
const AUTH_KEY = "craftlabs_platform_auth";
|
|
|
|
function decodeJwtPayload(token) {
|
|
try {
|
|
const parts = token.split(".");
|
|
if (parts.length !== 3) return null;
|
|
const payload = parts[1];
|
|
const latin1 = atob(payload.replace(/-/g, "+").replace(/_/g, "/"));
|
|
// atob 返回 Latin-1 编码,需转为 UTF-8 才能正确解析中文
|
|
const bytes = Uint8Array.from(latin1, (c) => c.charCodeAt(0));
|
|
const decoded = new TextDecoder().decode(bytes);
|
|
return JSON.parse(decoded);
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function restoreAuth() {
|
|
const token = localStorage.getItem(TOKEN_KEY);
|
|
if (!token) return { token: "", displayName: "", roles: [], permissions: [] };
|
|
|
|
const saved = localStorage.getItem(AUTH_KEY);
|
|
if (saved) {
|
|
try {
|
|
return { token, ...JSON.parse(saved) };
|
|
} catch { /* ignore */ }
|
|
}
|
|
|
|
const claims = decodeJwtPayload(token);
|
|
if (claims) {
|
|
return {
|
|
token,
|
|
displayName: claims.displayName || claims.sub || "",
|
|
roles: claims.roles || [],
|
|
permissions: [],
|
|
};
|
|
}
|
|
|
|
return { token: "", displayName: "", roles: [], permissions: [] };
|
|
}
|
|
|
|
export const useAuthStore = defineStore("auth", {
|
|
state: () => ({
|
|
...restoreAuth(),
|
|
}),
|
|
getters: {
|
|
hasAnyRole: (state) => {
|
|
return (roleList) => {
|
|
const need = roleList || [];
|
|
const have = state.roles || [];
|
|
return need.some((r) => have.includes(r));
|
|
};
|
|
},
|
|
},
|
|
actions: {
|
|
async login(username, password) {
|
|
let data;
|
|
try {
|
|
const res = await axios.post("/api/v1/auth/login", { username, password });
|
|
data = res.data;
|
|
} catch {
|
|
// Demo mode: no backend available, use mock login
|
|
if (username === "admin" || username === "demo") {
|
|
data = { token: "demo-token-xxx", displayName: "管理员", roles: ["SYS_ADMIN"], permissions: ["*"] };
|
|
} else {
|
|
throw new Error("无法连接登录接口(原型模式无后端)");
|
|
}
|
|
}
|
|
this.token = data.token;
|
|
this.displayName = data.displayName || username;
|
|
this.roles = data.roles || [];
|
|
this.permissions = data.permissions || [];
|
|
localStorage.setItem(TOKEN_KEY, this.token);
|
|
localStorage.setItem(AUTH_KEY, JSON.stringify({
|
|
displayName: this.displayName, roles: this.roles, permissions: this.permissions
|
|
}));
|
|
axios.defaults.headers.common.Authorization = `Bearer ${this.token}`;
|
|
},
|
|
logout() {
|
|
this.token = "";
|
|
this.displayName = "";
|
|
this.roles = [];
|
|
this.permissions = [];
|
|
localStorage.removeItem(TOKEN_KEY);
|
|
localStorage.removeItem(AUTH_KEY);
|
|
delete axios.defaults.headers.common.Authorization;
|
|
if (window.__idleCleanup) {
|
|
window.__idleCleanup()
|
|
delete window.__idleCleanup
|
|
}
|
|
},
|
|
restoreAxiosAuth() {
|
|
if (this.token) {
|
|
axios.defaults.headers.common.Authorization = `Bearer ${this.token}`;
|
|
}
|
|
},
|
|
},
|
|
});
|