| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- import globalConfig from '@/config';
- import {
- stringMd5,
- aesCbcEncryptString,
- aesCbcDecryptString,
- rabbitEncryptString,
- rabbitDecryptString,
- } from '@/utils/crypto';
- const storageKeyIV = stringMd5(`${globalConfig.app.title}_${globalConfig.app.version}`).slice(0, 8);
- export function encryptKey(key: string) {
- return rabbitEncryptString(key, globalConfig.security.storageEncryptionKey, storageKeyIV);
- }
- export function decryptKey(key: string) {
- return rabbitDecryptString(key, globalConfig.security.storageEncryptionKey, storageKeyIV);
- }
- export function encryptData(data: string) {
- return aesCbcEncryptString(data, globalConfig.security.storageEncryptionKey);
- }
- export function decryptData(data: string) {
- return aesCbcDecryptString(data, globalConfig.security.storageEncryptionKey);
- }
- export interface StorageOptions {
- /**
- * 过期时间(秒), 0 为永远不过期
- * @default 0
- */
- expire?: number;
- /**
- * 是否加密key
- * @default false
- */
- encryptKey?: boolean;
- /**
- * 是否加密数据
- * @default false
- */
- encryptData?: boolean;
- }
- interface StorageData<T = any> {
- data: T;
- expire: number;
- }
- function shouldEncryptKey(functionOptions?: StorageOptions, instanceOptions?: StorageOptions) {
- if (globalConfig.security.enableStorageEncryption) {
- return functionOptions?.encryptKey ?? instanceOptions?.encryptKey ?? false;
- }
- return false;
- }
- function shouldEncryptData(funcOpts?: StorageOptions, instanceOpts?: StorageOptions) {
- if (globalConfig.security.enableStorageEncryption) {
- return funcOpts?.encryptData ?? instanceOpts?.encryptData ?? false;
- }
- return false;
- }
- /**
- * 创建 localStorage 工具实例
- * @param opts {StorageOptions} 本实例使用的全局配置
- * @returns
- */
- export function createLocalStorage({
- expire: confExpire = 0,
- encryptKey: confEncryptKey = false,
- encryptData: confEncryptData = false,
- }: StorageOptions = {}) {
- /**
- * 保存数据
- * @param key
- * @param data
- * @param opts 当传递了 opts 时,opts 中存在的配置项会覆盖当前实例的全局配置中的配置项。
- */
- function set<T = any>(key: string, data: T, opts?: StorageOptions) {
- const expire = opts?.expire ?? confExpire;
- const isEncryptKey = shouldEncryptKey(opts, { encryptKey: confEncryptKey });
- const isEncryptData = shouldEncryptData(opts, { encryptData: confEncryptData });
- const storageData: StorageData<T> = {
- data,
- expire: expire !== 0 ? new Date().getTime() + expire * 1000 : 0,
- };
- const json = JSON.stringify(storageData);
- const finalKey = isEncryptKey ? encryptKey(key) : key;
- const finalData = isEncryptData ? encryptData(json) : json;
- window.localStorage.setItem(finalKey, finalData);
- }
- /**
- * 读取数据
- * @param key
- * @param opts 当传递了 opts 时,opts 中存在的配置项会覆盖当前实例的全局配置中的配置项。
- * @returns
- */
- function get<T = any>(key: string, opts?: StorageOptions) {
- const isEncryptKey = shouldEncryptKey(opts, { encryptKey: confEncryptKey });
- const isEncryptData = shouldEncryptData(opts, { encryptData: confEncryptData });
- const finalKey = isEncryptKey ? encryptKey(key) : key;
- let data = window.localStorage.getItem(finalKey);
- if (!data) return null;
- if (isEncryptData) {
- data = decryptData(data);
- }
- if (!data) return null;
- let storageData: StorageData | null = null;
- try {
- storageData = JSON.parse(data);
- } catch {
- // Prevent failure
- }
- if (storageData) {
- const { data, expire = 0 } = storageData;
- if (expire === 0 || expire >= Date.now()) return data as T;
- }
- return null;
- }
- /**
- * 删除数据
- * @param key
- * @param opts 当传递了 opts 时,opts 中存在的配置项会覆盖当前实例的全局配置中的配置项。
- */
- function remove(key: string, opts?: StorageOptions) {
- const isEncryptKey = shouldEncryptKey(opts, { encryptKey: confEncryptKey });
- const finalKey = isEncryptKey ? encryptKey(key) : key;
- window.localStorage.removeItem(finalKey);
- }
- /**
- * 清除 localStorage 中的所有数据。**慎用**
- */
- function clear() {
- window.localStorage.clear();
- }
- return { set, get, remove, clear };
- }
- /**
- * 创建 sessionStorage 工具实例
- * @param opts {StorageOptions} 本实例使用的全局配置
- * @returns
- */
- export function createSessionStorage({
- expire: confExpire = 0,
- encryptKey: confEncryptKey = false,
- encryptData: confEncryptData = false,
- }: StorageOptions = {}) {
- /**
- * 保存数据
- * @param key
- * @param data
- * @param opts 当传递了 opts 时,opts 中存在的配置项会覆盖当前实例的全局配置中的配置项。
- */
- function set<T = any>(key: string, data: T, opts?: StorageOptions) {
- const expire = opts?.expire ?? confExpire;
- const isEncryptKey = shouldEncryptKey(opts, { encryptKey: confEncryptKey });
- const isEncryptData = shouldEncryptData(opts, { encryptData: confEncryptData });
- const storageData: StorageData<T> = {
- data,
- expire: expire !== 0 ? new Date().getTime() + expire * 1000 : 0,
- };
- const json = JSON.stringify(storageData);
- const finalKey = isEncryptKey ? encryptKey(key) : key;
- const finalData = isEncryptData ? encryptData(json) : json;
- window.sessionStorage.setItem(finalKey, finalData);
- }
- /**
- * 读取数据
- * @param key
- * @param opts 当传递了 opts 时,opts 中存在的配置项会覆盖当前实例的全局配置中的配置项。
- * @returns
- */
- function get<T = any>(key: string, opts?: StorageOptions) {
- const isEncryptKey = shouldEncryptKey(opts, { encryptKey: confEncryptKey });
- const isEncryptData = shouldEncryptData(opts, { encryptData: confEncryptData });
- const finalKey = isEncryptKey ? encryptKey(key) : key;
- let data = window.sessionStorage.getItem(finalKey);
- if (!data) return null;
- if (isEncryptData) {
- data = decryptData(data);
- }
- if (!data) return null;
- let storageData: StorageData | null = null;
- try {
- storageData = JSON.parse(data);
- } catch {
- // Prevent failure
- }
- if (storageData) {
- const { data, expire = 0 } = storageData;
- if (expire === 0 || expire >= Date.now()) return data as T;
- }
- return null;
- }
- /**
- * 删除数据
- * @param key
- * @param opts 当传递了 opts 时,opts 中存在的配置项会覆盖当前实例的全局配置中的配置项。
- */
- function remove(key: string, opts?: StorageOptions) {
- const isEncryptKey = shouldEncryptKey(opts, { encryptKey: confEncryptKey });
- const finalKey = isEncryptKey ? encryptKey(key) : key;
- window.sessionStorage.removeItem(finalKey);
- }
- /**
- * 清除 sessionStorage 中的所有数据。**慎用**
- */
- function clear() {
- window.sessionStorage.clear();
- }
- return { set, get, remove, clear };
- }
- export const ls = createLocalStorage({
- expire: 60 * 60 * 24 * 7,
- encryptKey: true,
- encryptData: true,
- });
- export const ss = createSessionStorage({
- expire: 60 * 60 * 24 * 7,
- encryptKey: true,
- encryptData: true,
- });
|