bilibili

用户与客户

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

快速上手

新增 TOC 客户表

  1. 此表对应的实体都会放在 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='客户表';

INSERT INTO `toc_custom`(`id`, `nickname`, `username`, `password`) VALUES (1, 'lengleng', 'lengleng', '123456');
  1. pig-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;
}
  1. pig-upms-biz 新增 TocCustomMapper 查询工具
@Mapper
public interface TocCustomMapper extends BaseMapper<TocCustom> {
}
  1. pig-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);
}
  1. 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);
}

修改认证中心代码

  1. 增加 custom 客户端
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`) VALUES (20000,'custom',NULL,'custom','server','password,refresh_token',NULL,NULL,10000,11111111,'','true');
  1. 修改整个框架最核心的代码 custom 客户端的专用 UserDetailsService
@Slf4j
@RequiredArgsConstructor
public class PigCustomUserDetailsServiceImpl implements PigUserDetailsService {

    private final RemoteUserService remoteUserService;
    private final CacheManager cacheManager;

    /**
     * 用户名密码登录
     * @param username 用户名
     * @return
     */
    @Override
    @SneakyThrows
    public UserDetails loadUserByUsername(String username) {
        R<TocCustom> result = remoteUserService.custom(username, SecurityConstants.FROM_IN);
        // 根据 result 构建 security 框架需要的 用户对象
        TocCustom custom = result.getData();
        if (custom == null) {
            throw new UsernameNotFoundException("用户不存在");
        }

        // 构造 security 用户
        return new PigUser(custom.getId(), null, custom.getUsername(), "{noop}" + custom.getPassword(), null, true, true,
            true, true, AuthorityUtils.NO_AUTHORITIES);
    }

    /**
     * 是否支持此客户端校验
     * @param clientId 目标客户端
     * @param grantType
     * @return true/false
     */
    @Override
    public boolean support(String clientId, String grantType) {
        return "custom".equals(clientId);
    }

    @Override
    public int getOrder() {
        return Integer.MIN_VALUE + 1;
    }
}
  1. 配置 SPI 加载 CustomUserDetailsService

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

参数说明
clientId这里根据前端登录请求写的的 clientId 区分是否是 toc 请求还是 tob 请求。这里选择 test 客户端
AuthorityUtils.NO_AUTHORITIES这里说明 toc 用户没有角色这一说,当然你可以通过后台创建一个角色 “ROLE_CUSTOM” 赋值给它

调用测试

curl --location --request POST 'http://127.0.0.1:3000/oauth2/token' \
--header 'Authorization: Basic Y3VzdG9tOmN1c3RvbQ==' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'username=lengleng' \
--data-urlencode 'password=YehdBPev' \
--data-urlencode 'scope=server' \
--data-urlencode 'grant_type=password'

♥️ 获取支持

遇到问题?

如果您在使用过程中遇到任何问题、有功能建议或需求,请点击此卡片前往 Gitee 仓库提交 Issue。