登录用户支持多表存储

用户与客户

  • TOB 用户,指的是通过 PIG 登录后台完成业务能力的用户(比如淘宝的后台管理员等),此部分用户保存在 sys_user 表。
  • TOC 客户,指的是面向大众的客户(比如在淘宝购买东西的客户),此部分客户独立存在

快速上手

新增 TOC 客户表

  • ① 此表对应的实体都会放在 upms 模块,所以表也要和原有 sys_user 在同一个数据库
CREATE TABLE `toc_custom` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nickname` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `username` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
  `password` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='客户表';
  • ② pigx-upms-api 新增 TocCustom 实体
@Data
public class TocCustom implements Serializable {
	private static final long serialVersionUID = 1L;
	private Long id;
	private String nickname;
	private String username;
	private String password;
}
  • ③ pigx-upms-biz 新增 TocCustomMapper 查询工具
@Mapper
public interface TocCustomMapper extends PigxBaseMapper<TocCustom> {
}
  • ④ pigx-upms-biz 新增 custom 查询接口
@Inner
@GetMapping("/custom/{username}")
public R customInfo(@PathVariable String username) {
  TocCustom custom = customMapper.selectOne(Wrappers.<TocCustom>lambdaQuery()
      .eq(TocCustom::getUsername, username));
  return R.ok(custom);
}
custom查询接口
  • ⑤ feign-client 增加调用 custom 接口
@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.UPMS_SERVICE)
public interface RemoteUserService {
	@GetMapping("/user/custom/{username}")
	R<TocCustom> custom(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM) String from);
}

修改认证中心代码

  • ① 增加 custome 客户端
INSERT INTO `sys_oauth_client_details` (`id`,`client_id`,`resource_ids`,`client_secret`,`scope`,`authorized_grant_types`,`web_server_redirect_uri`,`authorities`,`access_token_validity`,`refresh_token_validity`,`additional_information`,`autoapprove`,`del_flag`,`tenant_id`) VALUES (1000,'custom',NULL,'custom','server','password,refresh_token',NULL,NULL,10000,11111111,'{"enc_flag":"0","captcha_flag":"0"}','true','0',1);
  • ② 修改整个框架最核心的代码 创建新的 PigxToCUserDetailsServiceImpl 专门处理 custome 客户端请求
新建UserDetailsService
注意事项

注意如下代码仅是新增,原有代码不要修改。

@RequiredArgsConstructor
public class PigxTocUserDetailsServiceImpl implements PigxUserDetailsService {

	private final RemoteUserService remoteUserService;

	// 登录流程使用
	@Override
	@SneakyThrows
	public UserDetails loadUserByUsername(String username) {

		TocCustom user = remoteUserService.custom(username, SecurityConstants.FROM_IN).getData();

		return new PigxUser(user.getId(), user.getUsername(), 1L, "Phone", "Avatar", user.getNickname(), "Name", "Email", 1L,
				"{noop}" + user.getPassword(), true, true, true, true, AuthorityUtils.NO_AUTHORITIES);
	}

	// check-token 使用
	@Override
	public UserDetails loadUserByUser(PigxUser pigxUser) {
		// 根据 pigxUser 里面的信息 查询对应表 返回 UserDetails,  根据实际情况修改
		return this.loadUserByUsername(pigxUser.getUsername());
	}


	@Override
	public boolean support(String clientId, String grantType) {
		return "custom".equals(clientId);
	}

	/**
	 * 排序值
	 * @return 排序值
	 */
	@Override
	public int getOrder() {
		return 10;
	}

}
重点参数说明

重点说明以上改动代码出现的重要参数

参数说明
clientId这里根据前端登录请求写的的 clientId 区分是否是 toc 请求还是 tob 请求。这里选择 test 客户端
PigxUser此对象是要返回给 spring security 处理的对象,包含当前用户的基本信息、账号密码。由于 toc 用户没有 tob 用户那么多的属性(部门、角色)等这里很多都填写了默认值。
AuthorityUtils.NO_AUTHORITIES这里说明 toc 用户没有角色这一说,当然你可以通过后台创建一个角色 "ROLE_CUSTOM" 赋值给它

调用测试

# 单体请求是  /admin/oauth2/token  , 微服务是: /auth/oauth2/token
curl --location --request POST 'http://pigx-gateway:9999/auth/oauth2/token?grant_type=password' 
--header 'Authorization: Basic Y3VzdG9tOmN1c3RvbQ==' 
--header 'Content-Type: application/x-www-form-urlencoded' 
--data-urlencode 'username=lengleng' 
--data-urlencode 'password=123456' 
--data-urlencode 'scope=server'

其他说明

  • 对于验证码和第三方登录 可以参考以上逻辑 添加根据客户端 ID 查询不同表的逻辑

  • 特别注意针对令牌检验,哪个客户端调用下发的令牌 就使用哪个客户端进行 checkToken