引言
在上一节《淘东电商项目(16) -会员注册功能》,主要讲解如何实现会员注册功能,目的主要还是讲解Feign客户端的调用。
代码已提交至Github(版本号:
36aaaaae0449b483f82b658dcdda8df9f5a208b9
),有兴趣的同学可以下载来看看:https://github.com/ylw-github/taodong-shop
本文主要讲解微服务接口的安全问题,使用DTO如何细分接口中的实体。
本文目录结构:
l____引言
l____ 1. 问题引入
l____ 2. 何为VO、DO、DTO?
l____ 3. 项目改造
l________ 3.1 会员微服务改造
l________________ 3.1.1 新增VO、DO
l________________ 3.1.2 替换之前的实体类
l________ 3.2 微信微服务改造
l____ 4. 测试
l____总结
1. 问题引入
我们看看目前项目中注册接口:
其中里面的请求实体类如下:
@Data
@ApiModel(value = "用户中注册")
public class UserEntity {
/**
* userid
*/
@ApiModelProperty(value = "用户id")
private Long userid;
/**
* 手机号码
*/
@ApiModelProperty(value = "手机号码")
private String mobile;
/**
* 邮箱
*/
@ApiModelProperty(value = "邮箱")
private String email;
/**
* 密码
*/
@ApiModelProperty(value = "密码")
private String password;
/**
* 用户名称
*/
@ApiModelProperty(value = "用户名称")
private String userName;
/**
* 性别 0 男 1女
*/
@ApiModelProperty(value = "用户性别")
private char sex;
/**
* 年龄
*/
@ApiModelProperty(value = "用户年龄")
private Long age;
/**
* 注册时间
*/
@ApiModelProperty(value = "创建时间")
private Date createTime;
/**
* 修改时间
*
*/
@ApiModelProperty(value = "修改时间")
private Date updateTime;
/**
* 账号是否可以用 1 正常 0冻结
*/
@ApiModelProperty(value = "账号是否可以用 1 正常 0冻结")
private char is_avalible;
/**
* 用户头像
*/
@ApiModelProperty(value = " 用户头像")
private String pic_img;
/**
* 用户关联 QQ 开放ID
*/
@ApiModelProperty(value = "用户关联 QQ 开放ID")
private Date qq_openid;
/**
* 用户关联 微信 开放ID
*/
@ApiModelProperty(value = "用户关联 微信 开放ID")
private Date WX_OPENID;
}
是否想过,请求的实体类是和数据库的实体类是一模一样的,这样会不会造成安全的问题?譬如我需要增加一个字段isVip
(表示是否为会员),那请求者如果是非会员,通过抓包,设置为true
,那岂不是会造成数据安全的问题么?其实,我们需要改造一下请求的实体内容,让其与数据库对应的实体类有所区别。
下面先来了解下VO、DO、DTO 之间的区别。
2. 何为VO、DO、DTO?
在日常的项目开发中:
- VO对应于页面上需要显示的数据(表单)
- DO对应于数据库中存储的数据(数据表)
- DTO对应于除二者之外需要进行接口形式传递的数据。
在传统的项目中,一般不使用DTO和VO的原因无非以下几个:
- 项目太小,对于一种业务实体,封装成一个DO就够了。
- 并不熟悉DTO、VO,更不知道他们之间的区别。
- 了解DO\DTO\VO之间的区别,但是懒得用。
直接进入主题,修改我们的项目。
3. 项目改造
首先需要构建新的新的模块:taodong-shop-api-dto
,并删除旧的模块taodong-shop-api-entity
:
除此,在taodong-shop-common-core
模块,添加DTO转换工具类:
public class BeanUtils<Dto, Do> {
/**
* dot 转换为Do 工具类
*
* @param dtoEntity
* @param doClass
* @return
*/
public static <Do> Do dtoToDo(Object dtoEntity, Class<Do> doClass) {
// 判断dto是否为空!
if (dtoEntity == null) {
return null;
}
// 判断DoClass 是否为空
if (doClass == null) {
return null;
}
try {
Do newInstance = doClass.newInstance();
org.springframework.beans.BeanUtils.copyProperties(dtoEntity, newInstance);
// Dto转换Do
return newInstance;
} catch (Exception e) {
return null;
}
}
/**
* do 转换为Dto 工具类
*
* @param dtoClass
* @param doEntity
* @return
*/
public static <Dto> Dto doToDto(Object doEntity, Class<Dto> dtoClass) {
// 判断dto是否为空!
if (doEntity == null) {
return null;
}
// 判断DoClass 是否为空
if (dtoClass == null) {
return null;
}
try {
Dto newInstance = dtoClass.newInstance();
org.springframework.beans.BeanUtils.copyProperties(doEntity, newInstance);
// Dto转换Do
return newInstance;
} catch (Exception e) {
return null;
}
}
// 后面集合类型带封装
}
3.1 会员微服务改造
3.1.1 新增VO、DO
1.在会员DTO模块下,新建两个包:input
(输入参数,请求参数)、output
(输出参数,返回响应参数):
2.修改taodong-shop-api-member-entity
中的UserEntity
->UserInDTO
,并把UserInDTO
复制到第一步的“输入参数”包里,改造内容如下:
/**
* description: 用户输入DTO
* create by: YangLinWei
* create time: 2020/3/2 11:10 上午
*/
@Data
@ApiModel(value = "用户信息实体类")
public class UserInDTO {
/**
* userid
*/
@ApiModelProperty(value = "用户id")
private Long userId;
/**
* 手机号码
*/
@ApiModelProperty(value = "手机号码")
private String mobile;
/**
* 邮箱
*/
@ApiModelProperty(value = "邮箱")
private String email;
/**
* 密码
*/
@ApiModelProperty(value = "密码")
private String password;
/**
* 用户名称
*/
@ApiModelProperty(value = "用户名称")
private String userName;
/**
* 性别 0 男 1女
*/
@ApiModelProperty(value = "用户性别")
private char sex;
/**
* 年龄
*/
@ApiModelProperty(value = "用户年龄")
private Integer age;
/**
* 用户头像
*/
@ApiModelProperty(value = " 用户头像")
private String picImg;
/**
* 用户关联 QQ 开放ID
*/
@ApiModelProperty(value = "用户关联 QQ 开放ID")
private String qqOpenId;
/**
* 用户关联 微信 开放ID
*/
@ApiModelProperty(value = "用户关联 微信 开放ID")
private String wxOpenId;
}
3.修改taodong-shop-api-member-entity
中的UserEntity
->UserOutDTO
,并把UserOutDTO
复制到第一步的“输出参数”包里,改造内容如下:
/**
* description: 响应返回参数
* create by: YangLinWei
* create time: 2020/3/2 11:12 上午
*/
@Data
@ApiModel(value = "用户返回参数")
public class UserOutDTO {
/**
* userid
*/
@ApiModelProperty(value = "用户id")
private Long userId;
/**
* 手机号码
*/
@ApiModelProperty(value = "手机号码")
private String mobile;
/**
* 邮箱
*/
@ApiModelProperty(value = "邮箱")
private String email;
/**
* 用户名称
*/
@ApiModelProperty(value = "用户名称")
private String userName;
/**
* 性别 0 男 1女
*/
@ApiModelProperty(value = "用户性别")
private char sex;
/**
* 年龄
*/
@ApiModelProperty(value = "用户年龄")
private Integer age;
/**
* 注册时间
*/
@ApiModelProperty(value = "创建时间")
private Date createTime;
/**
* 修改时间
*
*/
@ApiModelProperty(value = "修改时间")
private Date updateTime;
/**
* 账号是否可以用 1 正常 0冻结
*/
@ApiModelProperty(value = "账号是否可以用 1 正常 0冻结")
private char isAvalible;
/**
* 用户头像
*/
@ApiModelProperty(value = " 用户头像")
private String picImg;
/**
* 用户关联 QQ 开放ID
*/
@ApiModelProperty(value = "用户关联 QQ 开放ID")
private String qqOpenId;
/**
* 用户关联 微信 开放ID
*/
@ApiModelProperty(value = "用户关联 微信 开放ID")
private String wxOpenId;
}
4.在会员服务taodong-shop-service-member
,新建UserDo
(DO实体类)
/**
* description: 用户实体类DO
* create by: YangLinWei
* create time: 2020/3/2 11:26 上午
*/
@Data
public class UserDo {
/**
* userid
*/
private Long userId;
/**
* 手机号码
*/
private String mobile;
/**
* 邮箱
*/
private String email;
/**
* 密码
*/
private String password;
/**
* 用户名称
*/
private String userName;
/**
* 性别 0 男 1女
*/
private char sex;
/**
* 年龄
*/
private Long age;
/**
* 注册时间
*/
private Date createTime;
/**
* 修改时间
*
*/
private Date updateTime;
/**
* 账号是否可以用 1 正常 0冻结
*/
private char isAvalible;
/**
* 用户头像
*/
private String picImg;
/**
* 用户关联 QQ 开放ID
*/
private String qqOpenid;
/**
* 用户关联 微信 开放ID
*/
private String wxOpenid;
}
3.1.2 替换之前的实体类
1.替换注册接口的实体类
替换前 | 替换后 |
---|---|
![]() | ![]() |
1.替换查询手机号是否存在接口的实体类:
改造前 | 改造后 |
---|---|
![]() | ![]() |
3.2 微信微服务改造
过程大致同上,具体的代码可以从Github clone来看:https://github.com/ylw-github/taodong-shop(版本号:36aaaaae0449b483f82b658dcdda8df9f5a208b9
)
4. 测试
1.启动微信项目,成功:
2.启动会员项目,成功:
公众号测试,成功!