当前位置: 首页 > wzjs >正文

兰州商城网站建设网站seo是干什么的

兰州商城网站建设,网站seo是干什么的,衍艺 网站建设,网站开发哪里好如何实现H5端对接钉钉登录并优雅扩展其他平台 钉钉H5登录逻辑后端代码如何实现?本次采用策略模式工厂方式进行定义接口确定会使用的基本鉴权步骤具体逻辑类进行实现采用注册表模式(Registry Pattern)抽象工厂进行基本逻辑定义具体工厂进行对接…

如何实现H5端对接钉钉登录并优雅扩展其他平台

    • 钉钉H5登录逻辑
    • 后端代码如何实现?
    • 本次采用策略模式+工厂方式进行
      • 定义接口确定会使用的基本鉴权步骤
      • 具体逻辑类进行实现
      • 采用注册表模式(Registry Pattern)
      • 抽象工厂进行基本逻辑定义
      • 具体工厂进行对接口中的逻辑步骤具体----实例化----逻辑进行重写
    • 总结

钉钉H5登录逻辑

下图中需要说明的一点是,准确来说步骤3来说是钉钉API返回给前端,前端携带一次性校验码token给后端进行后续的鉴权。
还有一点需要注意获得权限之后,如果前端需要回调接口获取用户信息,则需要增加上下文中的用户信息存储

image-20250407212849539

后端代码如何实现?

具体的伪代码如下所述,下面细聊一下如何进行实现获取用户信息这一步。其中本次采用了设计模式进行实现。

    public Result<LoginResp> h5Login(LoginH5UserReq loginH5UserReq) throws ApiException {// 获取租户信息xxxxx// 查询三方鉴权配置信息xxxxx// 获取用户信息 这一步很关键后面细说如何实现H5AuthHandler H5AuthHandler = H5AuthHandlerRegistry.createHandler(loginH5UserReq.getTypePlatForm());String userUniqueIdentifier = H5AuthHandler.getUserDetail(loginH5UserReq);// 系统校验根据手机号查询用户信息SysUser sysUser = sysUserMapper.selectOne(Wrappers.lambdaQuery(SysUser.class).eq(SysUser::getTel, userUniqueIdentifier), false);// 使用断言进行优雅校验Assert.notNull(sysUser, () -> new BizException(ErrorCodeEnum.NOT_AVAILABLE));// 校验通过下发tokenString accessToken = StpUtil.getTokenInfo().getTokenValue();xxxxreturn Result.success(loginResult);}

本次我的思路是实现针对不同平台,例如对接钉钉、企业微信、飞书、三方,具体的逻辑是不一样的,使用设计模式中的工厂模式进行构建,实现不同的逻辑进行创建不同类进行完成。

简单罗列一下可以采用的设计模式的具体之间的区别

image-20250407214413483

本次采用策略模式+工厂方式进行

定义接口确定会使用的基本鉴权步骤

public interface AuthHandler {// 获取访问令牌(需处理OAuth2 code校验)String getAccessToken(String code) throws AuthException;// 使用令牌换取用户唯一标识(需处理令牌失效场景)String getUserId(String token) throws AuthException;// 获取用户详细信息(需处理多层级JSON解析)UserDetail getUserDetail(String userId) throws AuthException;
}

具体逻辑类进行实现

下面代码是大致思路展示,直接run是会出现问题。涉及公司保密协议不可以直接上我的源码望读者朋友见谅~

public class DingTalkAuthHandler implements AuthHandler {private static final String API_HOST = "https://oapi.dingtalk.com";private final String appKey;private final String appSecret;// 依赖配置注入(参考网页6的钉钉配置)public DingTalkAuthHandler(String appKey, String appSecret) {this.appKey = appKey;this.appSecret = appSecret;}@Overridepublic String getAccessToken(String code) {// 构建认证请求参数(参考网页7的code交换逻辑)Map<String, String> params = new HashMap<>();params.put("appkey", appKey);params.put("appsecret", appSecret);// 调用钉钉API(网页6的接口文档)String url = API_HOST + "/gettoken?" + buildQueryString(params);JsonNode response = HttpUtil.get(url);// 错误码校验(参考网页6的errcode处理)if(response.get("errcode").asInt() != 0) {throw new DingTalkAuthException(response.get("errmsg").asText());}return response.get("access_token").asText();}@Overridepublic String getUserId(String token) {// 安全域名验证(参考网页7的domain校验)String url = API_HOST + "/user/getuserinfo?access_token=" + token;JsonNode userInfo = HttpUtil.get(url);return userInfo.get("userid").asText();}@Overridepublic UserDetail getUserDetail(String userId) {// 多层级数据解析(参考网页6的JSON结构)String url = API_HOST + "/user/get?userid=" + userId;JsonNode data = HttpUtil.get(url).get("result");return UserDetail.builder().mobile(data.at("/mobile").asText()) // JSONPath定位.name(data.get("name").asText()).avatar(data.get("avatar").asText()).build();}// 私有方法封装请求构建private String buildQueryString(Map<String, String> params) {return params.entrySet().stream().map(e -> e.getKey() + "=" + URLEncoder.encode(e.getValue(), StandardCharsets.UTF_8)).collect(Collectors.joining("&"));}
}

上述代码通过接口 + 实现类的方式进行大致逻辑的定义,具体逻辑的展开,不是本次的重点,主要想记录一下如何实现下述的调用:

// 需要实现根据loginH5UserReq.getTypePlatForm() 传入不同的类型,实现实例化对应的实体类进行处理对应逻辑
H5AuthHandler H5AuthHandler = H5AuthHandlerRegistry.createHandler(loginH5UserReq.getTypePlatForm());
// 得到具体逻辑类之后根据请求信息返回用户唯一的id进行后续鉴权
String userUniqueIdentifier = H5AuthHandler.getUserDetail(loginH5UserReq);

采用注册表模式(Registry Pattern)

集中管理平台与工厂映射关系,提供统一访问入口

@Component
// 为什么要采用ApplicationContextAware?文末解释
public class H5AuthHandlerRegistry implements ApplicationContextAware {private static final Map<String, H5AuthHandlerFactory<?>> REGISTRY = new ConcurrentHashMap<>();private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext context) {applicationContext = context;// Spring容器初始化完成后动态注册平台registerPlatforms();}// 具体平台注册private void registerPlatforms() {// 钉钉平台注册(依赖注入已生效)H5DingTalkAuthFactory dingTalkFactory = new H5DingTalkAuthFactory(applicationContext);REGISTRY.put(Platforms.DING_TALK.name(), dingTalkFactory);// 其他平台注册xxxxxxx}// 获取处理器工厂public static H5AuthHandlerFactory<?> getFactory(String platform) {return Optional.ofNullable(REGISTRY.get(platform)).orElseThrow(() -> new IllegalArgumentException("未注册的平台: " + platform));}// 全局同意访问入口public static H5AuthHandler createHandler(String platform) {return getFactory(platform).createHandler();}
}

抽象工厂进行基本逻辑定义

为什么这里要使用抽象类?

首先我想定义基本的创建逻辑,其次抽象类不能被实例化。还有抽象类一般用于设计模式中一种通用写法规范,为子类提供公共的代码实现(如非抽象方法)和强制约束(如抽象方法),子类继承并实现所有抽象方法后才能实例化。

public abstract class H5AuthHandlerFactory<T extends H5AuthHandler> {private final Class<T> handlerClass;protected H5AuthHandlerFactory(Class<T> handlerClass) {this.handlerClass = handlerClass;}// 定义基本创建逻辑,采用反射方式进行。支持反射创建(需无参构造)// PS:如果具体进行逻辑类不涉及采用spring容器管理类,可以使用直接newInstance。不然会出现创建失败,spring容器ioc和Java创建对象是割裂的两派public T createHandler() {try {return handlerClass.getDeclaredConstructor().newInstance();} catch (Exception e) {throw new RuntimeException("H5端登录逻辑抽象工厂---H5AuthHandlerFactory---处理器实例化失败", e);}}}

具体工厂进行对接口中的逻辑步骤具体----实例化----逻辑进行重写

public class H5DingTalkAuthFactory extends H5AuthHandlerFactory<H5DingTalkAuthHandler> {private final ApplicationContext context;// 这里是因为具体实例化处理钉钉H5登录逻辑类会使用到spring容器中的类,所以需要采用上下文的方式public H5DingTalkAuthFactory(ApplicationContext context) {super(H5DingTalkAuthHandler.class);this.context = context;}@Overridepublic H5DingTalkAuthHandler createHandler() {// 从Spring容器获取依赖项ThreePartyLoginRuleConfig ruleConfig = context.getBean(ThreePartyLoginRuleConfig.class);ObjectMapper objectMapper = context.getBean(ObjectMapper.class);// 通过构造器注入依赖return new H5DingTalkAuthHandler(ruleConfig, objectMapper);}
}

总结

总体来说,要实现其他平台的扩展。本次的使用中,由于对接不同平台,具体逻辑中涉及了配置文件配置不同平台JSON数据的解析,所以会使用sping中IOC功能,所以在工厂类中存在上下文部分。

扩展其他平台部分就需要创建两个类,一个类是集成抽象工厂实现其中的createHandler()方法,还有一个是实现接口中定义的三部曲。

H5xxxxxxxAuthFactory extends H5AuthHandlerFactory
H5xxxxxxxxAuthHandler implements H5AuthHandler
http://www.dtcms.com/wzjs/439104.html

相关文章:

  • 如何做营销型网站商城网站开发公司
  • 不用购买域名做网站上海百度推广排名
  • 建什么类型个人网站比较好国家提供的免费网课平台
  • 777fj做最好的网站独立站建站平台有哪些
  • 上海做网站的如何免费找精准客户
  • 怎样做视频播放网站长沙网红打卡景点排行榜
  • 六种常见网络营销方法优化大师专业版
  • 做网站可以用中文域名备案嘛海淀区seo引擎优化
  • java wap网站开发教程搜索引擎营销推广方案
  • 重庆网站有哪些永久域名查询
  • 商城建设方案大连seo按天付费
  • 网站建设的秘诀比较好的搜索引擎
  • 南京网站制作公司招聘seo是什么工作
  • 网络加速器下载上海企业优化
  • 网站建设 北京昌平视频运营管理平台
  • 现在有专业做海鲜的网站没有营销托管全网营销推广
  • 网站要怎样做才能获得市场份额外贸网站制作
  • 现在做网站建设的公司多么最新app推广
  • 江苏建设工程监督合肥百度seo代理
  • 湖南网站建设欧黎明seo网站推广方案
  • 大连网站seoseo关键词找29火星软件
  • 邯郸市设计公司电话网站建设seo
  • 电子商务网站建设的风险分析网站优化包括哪些内容
  • 没有域名如何访问网站店铺推广渠道有哪些
  • 设计网站界面软文营销的五大注意事项
  • 模板网站没有源代码站长工具查询系统
  • 网站技术开发文档模板怎么提交百度收录
  • 郑州网站制作价格seo技术培训岳阳
  • 口碑好的秦皇岛网站建设价格百度识图 上传图片
  • 凤凰县政府网站建设嘉兴seo排名外包