登陆注册与忘记密码前后端与jwt配置

Change-Id: Ide4ca3ea34609fdb33ea027e28169852fa41784a
diff --git a/rhj/frontend/src/utils/auth.js b/rhj/frontend/src/utils/auth.js
new file mode 100644
index 0000000..d04e102
--- /dev/null
+++ b/rhj/frontend/src/utils/auth.js
@@ -0,0 +1,155 @@
+// 认证相关的工具函数
+
+/**
+ * 获取当前用户的认证token
+ * @returns {string|null} 认证token,如果未登录则返回null
+ */
+export const getAuthToken = () => {
+  // 优先从localStorage获取(记住我的情况)
+  const localToken = localStorage.getItem('authToken');
+  if (localToken) {
+    return localToken;
+  }
+  
+  // 然后从sessionStorage获取(不记住我的情况)
+  const sessionToken = sessionStorage.getItem('authToken');
+  return sessionToken;
+};
+
+/**
+ * 获取当前用户信息
+ * @returns {object|null} 用户信息,如果未登录则返回null
+ */
+export const getUserInfo = () => {
+  // 优先从localStorage获取
+  const localUserInfo = localStorage.getItem('userInfo');
+  if (localUserInfo) {
+    try {
+      return JSON.parse(localUserInfo);
+    } catch (error) {
+      console.error('解析localStorage中的用户信息失败:', error);
+    }
+  }
+  
+  // 然后从sessionStorage获取
+  const sessionUserInfo = sessionStorage.getItem('userInfo');
+  if (sessionUserInfo) {
+    try {
+      return JSON.parse(sessionUserInfo);
+    } catch (error) {
+      console.error('解析sessionStorage中的用户信息失败:', error);
+    }
+  }
+  
+  return null;
+};
+
+/**
+ * 检查用户是否已登录
+ * @returns {boolean} 是否已登录
+ */
+export const isLoggedIn = () => {
+  const token = getAuthToken();
+  return !!token;
+};
+
+/**
+ * 获取记住的登录信息
+ * @returns {object} 包含email, password, rememberMe的对象
+ */
+export const getRememberedLoginInfo = () => {
+  const email = localStorage.getItem('rememberedEmail') || '';
+  const password = localStorage.getItem('rememberedPassword') || '';
+  const rememberMe = localStorage.getItem('rememberMe') === 'true';
+  
+  return {
+    email,
+    password,
+    rememberMe
+  };
+};
+
+/**
+ * 保存记住的登录信息
+ * @param {string} email 邮箱
+ * @param {string} password 密码
+ * @param {boolean} remember 是否记住
+ */
+export const saveRememberedLoginInfo = (email, password, remember) => {
+  if (remember) {
+    localStorage.setItem('rememberedEmail', email);
+    localStorage.setItem('rememberedPassword', password);
+    localStorage.setItem('rememberMe', 'true');
+  } else {
+    localStorage.removeItem('rememberedEmail');
+    localStorage.removeItem('rememberedPassword');
+    localStorage.removeItem('rememberMe');
+  }
+};
+
+/**
+ * 保存用户认证信息
+ * @param {string} token 认证token
+ * @param {object} userInfo 用户信息
+ * @param {boolean} remember 是否记住登录状态
+ */
+export const saveAuthInfo = (token, userInfo, remember = false) => {
+  if (remember) {
+    // 记住我:保存到localStorage
+    localStorage.setItem('authToken', token);
+    localStorage.setItem('userInfo', JSON.stringify(userInfo));
+    
+    // 清除sessionStorage
+    sessionStorage.removeItem('authToken');
+    sessionStorage.removeItem('userInfo');
+  } else {
+    // 不记住我:保存到sessionStorage
+    sessionStorage.setItem('authToken', token);
+    sessionStorage.setItem('userInfo', JSON.stringify(userInfo));
+    
+    // 清除localStorage中的认证信息(但保留记住的登录表单信息)
+    localStorage.removeItem('authToken');
+    localStorage.removeItem('userInfo');
+  }
+};
+
+/**
+ * 清除所有认证信息(退出登录)
+ * @param {boolean} clearRemembered 是否同时清除记住的登录信息
+ */
+export const clearAuthInfo = (clearRemembered = false) => {
+  // 清除认证token和用户信息
+  localStorage.removeItem('authToken');
+  localStorage.removeItem('userInfo');
+  sessionStorage.removeItem('authToken');
+  sessionStorage.removeItem('userInfo');
+  
+  // 如果需要,清除记住的登录信息
+  if (clearRemembered) {
+    localStorage.removeItem('rememberedEmail');
+    localStorage.removeItem('rememberedPassword');
+    localStorage.removeItem('rememberMe');
+  }
+};
+
+/**
+ * 创建带认证头的fetch请求配置
+ * @param {object} options 原始fetch配置
+ * @returns {object} 带认证头的fetch配置
+ */
+export const createAuthenticatedRequest = (options = {}) => {
+  const token = getAuthToken();
+  
+  if (!token) {
+    throw new Error('用户未登录');
+  }
+  
+  return {
+    ...options,
+    headers: {
+      ...options.headers,
+      'Authorization': `Bearer ${token}`,
+      'Content-Type': 'application/json'
+    }
+  };
+};
diff --git a/rhj/frontend/src/utils/crypto.js b/rhj/frontend/src/utils/crypto.js
new file mode 100644
index 0000000..eac10f0
--- /dev/null
+++ b/rhj/frontend/src/utils/crypto.js
@@ -0,0 +1,48 @@
+// 密码加密工具函数
+import CryptoJS from 'crypto-js';
+
+/**
+ * 使用 SHA256 加密密码
+ * @param {string} password 原始密码
+ * @returns {string} 加密后的密码
+ */
+export const hashPassword = (password) => {
+  if (!password || typeof password !== 'string') {
+    throw new Error('密码必须是非空字符串');
+  }
+  
+  return CryptoJS.SHA256(password).toString();
+};
+
+/**
+ * 验证密码是否已经被加密
+ * @param {string} password 密码字符串
+ * @returns {boolean} 是否为已加密的密码(64位十六进制字符串)
+ */
+export const isEncryptedPassword = (password) => {
+  if (!password || typeof password !== 'string') {
+    return false;
+  }
+  
+  // SHA256 加密后是64位十六进制字符串
+  return /^[a-f0-9]{64}$/i.test(password);
+};
+
+/**
+ * 安全的密码加密函数,避免重复加密
+ * @param {string} password 密码
+ * @returns {string} 加密后的密码
+ */
+export const safeHashPassword = (password) => {
+  if (!password) {
+    throw new Error('密码不能为空');
+  }
+  
+  // 如果已经是加密的密码,直接返回
+  if (isEncryptedPassword(password)) {
+    return password;
+  }
+  
+  // 否则进行加密
+  return hashPassword(password);
+};