个人中心
1. 功能概述
本文介绍如何使用 tio-boot 框架实现个人中心功能,包含以下核心接口:
- 用户信息查询:获取当前用户的详细信息
- 用户信息更新:修改用户基本信息
- 密码更新:安全修改用户密码
2. 接口规范
2.1 用户信息查询接口
请求
GET /api/v1/user/profile
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NDIwODgzNjgsInVzZXJJZCI6IjQ4ODIzNjI3MjMzODg3MDI3MiJ9.liKfYdWzULDPCeKfktyKyEanZIO3Q7uhZ9mAKMfjWyM
响应示例
{
"error": null,
"code": 1,
"msg": null,
"ok": true,
"data": {
"thirdPlatformUrl": null,
"updater": "",
"remark": null,
"createTime": 1752141088649,
"deleted": 0,
"creator": "",
"updateTime": 1752141088649,
"tenantId": "0",
"schoolId": null,
"metadata": "{}",
"userType": 0,
"passwordHash": null,
"passwordSalt": null,
"bio": null,
"backgroundUrl": null,
"updatedProfile": false,
"birthday": null,
"phoneNumber": null,
"emailVerified": false,
"disabled": false,
"of": "http://localhost:5173",
"invitedByUserId": null,
"coin": "0",
"mfaInfo": "[]",
"email": "litongjava@qq.com",
"photoUrl": null,
"platform": null,
"providerData": "[]",
"id": "532949489378402304",
"displayName": "litongjava"
}
}
2.2 用户信息更新接口
请求
POST /api/v1/user/update
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NDIwODgzNjgsInVzZXJJZCI6IjQ4ODIzNjI3MjMzODg3MDI3MiJ9.liKfYdWzULDPCeKfktyKyEanZIO3Q7uhZ9mAKMfjWyM
# 请求体示例
{"displayName": "新用户名", "bio": "新简介"}
响应示例
{
"error": null,
"code": 1,
"msg": null,
"ok": true,
"data": 1
}
2.3 密码更新接口
请求
POST /api/v1/user/updatePassword
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NDIwODgzNjgsInVzZXJJZCI6IjQ4ODIzNjI3MjMzODg3MDI3MiJ9.liKfYdWzULDPCeKfktyKyEanZIO3Q7uhZ9mAKMfjWyM
{
"old_password": "00000000",
"new_password": "11111111"
}
响应示例
{
"error": null,
"code": 1,
"msg": null,
"ok": true,
"data": 1
}
3. 后端实现
3.1 数据模型
密码更新请求对象
package com.litongjava.tio.boot.admin.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserUpdatePasswordRequest {
private String oldPassword;
private String newPassword;
}
3.2 SQL 查询
用户信息查询 SQL (admin_app_user.sql
)
-- 获取用户完整信息
SELECT
id, email, phone, email_verified, updated_profile,
display_name, bio, photo_url, background_url, phone_number,
disabled, birthday, coin, invited_by_user_id, "of", platform,
third_platform_url, school_id, user_type, provider_data, mfa_info,
metadata, user_info, google_id, google_info, facebook_id, facebook_info,
twitter_id, twitter_info, github_id, github_info, wechat_id, wechat_info,
qq_id, qq_info, weibo_id, weibo_info, remark, creator,
create_time, updater, update_time, deleted, tenant_id
FROM app_users
WHERE ID = ? AND deleted = 0;
3.3 服务层实现
AppUserService.java
核心方法
public class AppUserService {
// SQL 模板
private static final String SQL_SELECT_USER = SqlTemplates.get("app_users.findById");
// 获取用户信息
public AppUser getUserById(String userIdString) {
return Db.findFirst(AppUser.class, SQL_SELECT_USER, userIdString);
}
// 更新用户信息
public boolean updateById(String userIdString, Row row) {
// 移除敏感字段
row.remove("password_salt");
row.remove("password_hash");
return Db.update(TioBootAdminTableNames.app_users, row, "id", userIdString);
}
// 更新密码
public RespBodyVo updatePassword(String userIdString,
UserUpdatePasswordRequest updatePasswordRequest) {
String oldPassword = updatePasswordRequest.getOldPassword();
String newPassword = updatePasswordRequest.getNewPassword();
// 获取盐值
String salt = Db.queryStr("SELECT password_salt FROM app_users WHERE id=?", userIdString);
// 验证旧密码
String oldHash = DigestUtils.sha256Hex(oldPassword + salt);
boolean isValid = Db.existsBySql(
"SELECT 1 FROM app_users WHERE id=? AND password_hash=?",
userIdString, oldHash
);
if (isValid) {
// 生成新密码哈希
String newHash = DigestUtils.sha256Hex(newPassword + salt);
int affectedRows = Db.updateBySql(
"UPDATE app_users SET password_hash=? WHERE id=?",
newHash, userIdString
);
return RespBodyVo.ok(affectedRows);
} else {
return RespBodyVo.fail("原始密码验证失败");
}
}
}
3.4 控制器实现
AppUserHandler.java
请求处理
public class AppUserHandler {
// 获取用户信息
public HttpResponse profile(HttpRequest request) {
String userId = TioRequestContext.getUserIdString();
AppUser user = Aop.get(AppUserService.class).getUserById(userId);
return TioRequestContext.getResponse().body(RespBodyVo.ok(user));
}
// 更新用户信息
public HttpResponse update(HttpRequest request) {
String userId = TioRequestContext.getUserIdString();
Map<String, Object> params = FastJson2Utils.parseToMap(
request.getBodyString(),
String.class,
Object.class
);
return TioRequestContext.getResponse().body(
RespBodyVo.ok(Aop.get(AppUserService.class).updateById(userId, Row.fromMap(params)))
);
}
// 更新密码
public HttpResponse updatePassword(HttpRequest request) {
String userId = TioRequestContext.getUserIdString();
UserUpdatePasswordRequest req = FastJson2Utils.parse(
request.getBodyString(),
UserUpdatePasswordRequest.class
);
RespBodyVo result = Aop.get(AppUserService.class).updatePassword(userId, req);
return TioRequestContext.getResponse().body(result);
}
}
3.5 路由配置
接口路由注册
public class AppRoutes {
public void config) {
//...
AppUserHandler userHandler = new AppUserHandler();
r.add("/api/v1/user/profile", userHandler::profile);
r.add("/api/v1/user/update", userHandler::update);
r.add("/api/v1/user/updatePassword", userHandler::updatePassword);
}
}
4. 安全注意事项
敏感字段过滤:
- 更新接口中需显式移除
password_salt
和password_hash
字段 - 查询接口不应返回密码相关字段
- 更新接口中需显式移除
密码安全:
- 使用 SHA-256 加盐哈希存储密码
- 密码更新需验证原始密码
- 前端传输应使用 HTTPS 加密
权限控制:
- 所有接口需通过 JWT 认证
- 用户只能操作自己的数据(通过
TioRequestContext.getUserIdString()
获取当前用户)
5. 总结
本文详细介绍了使用 tio-boot 框架实现个人中心功能的全过程,包含:
- 清晰的接口规范定义
- 完整的数据库操作实现
- 安全的密码更新流程
- 控制器与服务的解耦设计
- 路由配置的最佳实践
实现要点:
- 使用
TioRequestContext
获取当前用户信息 - 通过
Row
对象实现灵活的数据更新 - 采用加盐哈希确保密码安全
- 使用
Aop.get()
实现依赖注入