毕设之-Hlang后端架构-双系统交互
文章目录
- 前言
- 交互流程
- 基本流程
- 约定公钥
- 人人中台携带公钥获取私钥
- 私钥生成
- 人人中台携带私钥访问
- 私钥验证(博客系统)
- 调试演示
- 总结
前言
前天我们完成了基本的整合,但是还没有整合到我们的业务系统,也就是博客系统。本来昨天要搞一手的,但是在练车,所以就没有完成。那么今天补上,差不多20号去上班实习,这点时间赶紧搞完。
首先的话,我们这里建好了业务表:
并且我们创建好了新的服务:
并且,我们通过人人开源生成好了对应的后端的一个CURD和基本接口。
然后,我们把对应的controller,和feign接口做好对接。
如图:(整合好的feign组件)
然后在我们的人人开源中台系统做好调用
这里的话,我们可以发现是这样的流程
之后的话,在我们的博客系统当中我们有这个:
交互流程
那么这里,我们今天要实现的就是在人人开源中台系统过来调用到我们的具体服务的api的时候要做到的一个权限验证
因为我们这是两个系统,没有共同使用一个用户表,这也就是意味着,我们一个权限不方便公用一个。所以对应的一些服务得像第三方api一样提供。只不过这个api接口,可以通过注册中心知道,然后可以由open-feign调用而已。
基本流程
okey,那么在这里的话,我们先简单梳理一下,我们的基本流程:
那么在这里,我们可以解读到这几个信息:
- 需要一个公钥接口,拿到公钥
- 需要一个申请临时密钥的接口,通过这个密钥去访问服务
那么在人人中台要做:
- 先拿到公钥
- 通过公钥拿到私钥
- 携带私钥去访问
对于博客系统:
- 开发公钥接口
- 开发私钥接口
- 对受保护接口进行私钥验证
同时,由于公钥接口是公开的,得到的公钥在一定时间是一致的,因此我们可以直接做个约定,公钥是啥,也就是可以学一下rouyi,这个写死省下一个接口
所以这里的话,我们在编码阶段,我可以这样干。
约定公钥
我们先约定公钥。
我们可以看到,在我们的博客系统当中的话,有个获取私钥的接口:
这里的话,我们写死了,就是直接指定公钥是HUTEROX。
人人中台携带公钥获取私钥
然后就是人人中台携带公钥获取私钥
这里的话,我们在feign的拦截器当中实现了这个功能。我们先拿到私钥。
私钥生成
那么这个时候,我们自然就要生成私钥了,这个私钥由我们的博客系统生成。
package com.huterox.hlangserver.controller.innocontroller.auto;import com.huterox.common.utils.R;/*** 负责实现对内部服务调用的一个API授权签发* */
public interface AutoInnoApiService {/*** 签发临时授权码* */R SignApiAutoCode();/*** 验证签发的授权码是否通过* */boolean AcceptApiAutoCode(String signKey,String signal);
}
之后的话就是我们具体的实现类了。
package com.huterox.hlangserver.controller.innocontroller.auto.impl;
import com.alibaba.fastjson.JSON;
import com.huterox.common.sysEntity.SignApiCode;
import com.huterox.common.utils.CodeUtils;
import com.huterox.common.utils.R;
import com.huterox.hlangserver.controller.innocontroller.auto.AutoInnoApiService;
import com.huterox.hlangserver.utils.RedisTransKey;
import com.huterox.hlangserver.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;@Service
public class BaseAutoInnoApiServiceImpl implements AutoInnoApiService {private RedisUtils redisUtils;public BaseAutoInnoApiServiceImpl(RedisUtils redisUtils) {this.redisUtils = redisUtils;}@Autowiredpublic void setRedisUtils(RedisUtils redisUtils) {this.redisUtils = redisUtils;}@Overridepublic R SignApiAutoCode() {//生成验证SignString signKey = CodeUtils.creatCode(10);String signal = CodeUtils.creatCode(20);SignApiCode signApiCode = new SignApiCode();signApiCode.setSignal(signal);signApiCode.setSignKey(signKey);//设置30秒过期redisUtils.set(RedisTransKey.setServerSysKey(signKey),signApiCode,30, TimeUnit.SECONDS);return R.ok().put("sign",signApiCode);}@Overridepublic boolean AcceptApiAutoCode(String signKey,String signal) {//验证传回来的签发对不对,然后把这个进行删除Object o = redisUtils.get(RedisTransKey.getServerSysKey(signKey));SignApiCode signApiCode = JSON.parseObject(o.toString(), SignApiCode.class);redisUtils.del(RedisTransKey.getServerSysKey(signKey));return signApiCode.getSignal().equals(signal)&&signApiCode.getSignKey().equals(signKey);}
}
在这里的话,我用了几个工具类。当然这个在先前的whitehole都提到过。这里的话就不复述了,百度都能搞定。当然重要的是,这个项目后期也是开源的,这里只是记录一下具体的做法而已。后期可能会对代码进行优化,但是基本流程是不会发生太大改变的。
人人中台携带私钥访问
之后的话,就是我们的人人中台去携带我们的私钥去访问
package io.renren.config;
import com.huterox.common.sysEntity.SignApiCode;
import com.huterox.common.utils.FastJsonUtils;
import com.huterox.common.utils.R;
import com.huterox.feign.server.FeignAutoInnoApiSeverService;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;import java.util.HashMap;
import java.util.Map;@Configuration
public class FeignRequestInterceptor implements RequestInterceptor {private FeignAutoInnoApiSeverService feignAutoInnoApiSeverService;public FeignRequestInterceptor(FeignAutoInnoApiSeverService feignAutoInnoApiSeverService) {this.feignAutoInnoApiSeverService = feignAutoInnoApiSeverService;}@Autowiredpublic void setFeignAutoInnoApiSeverService(FeignAutoInnoApiSeverService feignAutoInnoApiSeverService) {this.feignAutoInnoApiSeverService = feignAutoInnoApiSeverService;}@Overridepublic void apply(RequestTemplate template) {//先那到临时签证Map<String, String> map = new HashMap<>();map.put("innoHeader","HUTEROX");R sign = feignAutoInnoApiSeverService.getSign(map);//拿到签证去正式访问保护接口String signKey = "";String signal = "";int code = (int) sign.get("code");if(code==0){String sign1 = FastJsonUtils.toJson(sign.get("sign"));SignApiCode signApiCode = FastJsonUtils.fromJson(sign1, SignApiCode.class);signKey = signApiCode.getSignKey();signal = signApiCode.getSignal();}//发送远程调用请求,填写signApiCodetemplate.header("signKey",signKey);template.header("signal",signal);}}
私钥验证(博客系统)
之后的话,我们的博客系统就要去验证我们的密钥对不对。(其实你发现,这玩意不就是服务之间的验证码嘛)
这里的话,我们受保护的接口是这些:
所以的话,我们来创建一个切面来进行处理:
package com.huterox.hlangserver.aspect;
import com.huterox.common.utils.R;
import com.huterox.hlangserver.controller.innocontroller.auto.AutoInnoApiService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;@Aspect
@Component
public class InnoAutoAspect {@Pointcut("within(com.huterox.hlangserver.controller.innocontroller.api..*) && @annotation(org.springframework.web.bind.annotation.RequestMapping)")public void verification() {}private AutoInnoApiService autoInnoApiService;public InnoAutoAspect(AutoInnoApiService autoInnoApiService) {this.autoInnoApiService = autoInnoApiService;}@Autowiredpublic void setAutoInnoApiService(AutoInnoApiService autoInnoApiService) {this.autoInnoApiService = autoInnoApiService;}@Around("verification()")public R verification(ProceedingJoinPoint joinPoint) throws Throwable {HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();String signKey = request.getHeader("signKey");String signal = request.getHeader("signal");if(!autoInnoApiService.AcceptApiAutoCode(signKey, signal)){return R.error();}return (R) joinPoint.proceed();}
}
调试演示
okey,那么之后的话,我们来演示具体流程
(完整的前端怎么整合的我就不演示了,以前的博客都有,或者百度都可以)
我们来看到这个:
拿到私钥,然后扩充访问
之后的话再我们那个博客系统可以看到方行。
总结
okey,以上的就是我们今天的内容,当然这部分还有优化的点,首先就是我们的人人中台,在访问的时候,我们用的是apply,重写了里面的拦截。但是问题在于,这个是全局通用的,如果我们后面有另一个子系统,那么这个时候的话,就建议使用切面了。当然这里这样处理是因为,这里我就只设计两个子系统,上次的whitehole有9个微服务,服务器顶不住。所以这次不乱搞了,省点资源,后面再研究研究这个网站智能助手玩玩。
(ps: 有没有广州的大哥春招再联系联系(狗头))
相关文章:

毕设之-Hlang后端架构-双系统交互
文章目录 前言交互流程基本流程约定公钥人人中台携带公钥获取私钥私钥生成人人中台携带私钥访问私钥验证(博客系统) 调试演示总结 前言 前天我们完成了基本的整合,但是还没有整合到我们的业务系统,也就是博客系统。本来昨天要搞一…...

什么同源策略?
同源 同源指的是URL有相同的协议、主机名和端口号。 同源策略 同源策略指的是浏览器提供的安全功能,非同源的RUL之间不能进行资源交互 跨域 两个非同源之间要进行资源交互就是跨域。 浏览器对跨域请求的拦截 浏览器是允许跨域请求的,但是请求返回…...

破译模式:模式识别在计算机视觉中的作用
一、介绍 在当代数字领域,计算机视觉中的模式识别是关键的基石,推动着众多技术进步和应用。本文探讨了计算机视觉中模式识别的本质、方法、应用、挑战和未来趋势。通过使机器能够识别和解释视觉数据中的模式,模式识别不仅推动了计算机视觉领域…...

c语言-全局变量与局部变量
目录 1、(作用)域的概念 2、全局与局部的相对性 3、生命周期 3、静态变量static 结语: 前言: 在c语言中,全局变量的可见范围是整个工程,而局部变量的可见范围从该变量被定义到该作用域结束,…...

【Spring】00 入门指南
文章目录 1.简介2.概念1)控制反转(IoC)2)依赖注入(DI) 3.核心模块1)Spring Core2)Spring AOP3)Spring MVC4)Spring Data5)Spring Boot 4.编写 Hel…...

BIM 技术:CIM (City Information Modeling) 1-7 级
本心、输入输出、结果 文章目录 BIM 技术:CIM (City Information Modeling) 1-7 级前言城市信息模型(CIM)概述城市信息模型分级介绍CIM 1CIM 2CIM 3CIM 4CIM 5CIM 6CIM 7 花有重开日,人无再少年实践是检验真…...

c++ websocket 协议分析与实现
前言 网上有很多第三方库,nopoll,uwebsockets,libwebsockets,都喜欢回调或太复杂,个人只需要在后端用,所以手动写个; 1:环境 ubuntu18 g(支持c11即可) 第三方库:jsoncpp,openssl 2:安装 jsoncpp 读取json 配置文件 用 自动安装 网…...

kali虚拟机无网络
1.查看虚拟机的网卡模式 在虚拟机设置里,一般选择桥接模式,也可以选择NAT模式。 2、你的IP地址是否写死了(设置为静态IP) vim编辑模式下的命令: 按a或i进入编辑模式,然后按esc键退出编辑模式,s…...

Unity2023.3(Unity6)版本开始将可以发布WebGPU
翻译一段官网上的话: 利用Unity 2023.3(正式发布时应该称为Unity6)中最新的WebGPU图形API集成,尝试最大限度的提升您的网络游戏的真实感。 通过与谷歌的战略合作,Unity实时3D平台的强大的图形功能现在为图形丰富的网络游戏进行微调࿰…...
计算机网络期末考试A卷及答案
一、选择题(30分,每题1分) 世界上第一个网络系统是( C )。 A、ENIAC B、以太网 C、ARPANET D、DECNET 2.在常用的传输介质中,( C )的带宽最宽、信号传输衰减最小、抗干扰能力最强。 A.双绞线 …...

<蓝桥杯软件赛>零基础备赛20周--第10周--二分
报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集 20周的完整安排请点击:20周计划 每周发1个博客,共20周(读者可以按…...
C++友元类,工厂模式和继承的融合案例
//友元没有继承性,没有传递性,所以在animal中定义友元类是无效的class animal{public:animal(){};virtual ~animal(){};};class Cat:public animal{friend class animalFactory;private:Cat(){}private:string m_name;string m_color;public:void about(){cout<&…...
使用 ?? 重新定义逻辑以获得更严格、更安全的 JavaScript 默认值
使用 ?? 重新定义逻辑以获得更严格、更安全的 JavaScript 默认值 JavaScript 中的 ?? 运算符称为 nullish 合并运算符。该运算符接受任一侧的操作数,并且仅当左侧操作数为空值时才返回右侧操作数。这个运算符绝对是一个较新的运算符,它是在 ES2020 …...

Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7
问题描述:Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7 最近在学习如何将YOLO部署在手机端,出现了许多错误,下面这个错误是手机和电脑连结之后,点击run之后出现的错误。 解决办法:将JDK版本将为…...

Python Django Suit:构建现代化的Django后台管理
概要 Django Suit是一款为Django后台管理提供现代、优雅界面的第三方应用,它致力于提升Django开发者的管理体验。本文将深入介绍Django Suit的安装、配置和高级功能,提供详实的示例代码,帮助大家更好地使用和定制Django后台管理界面。 安装与…...

电子学会C/C++编程等级考试2021年09月(六级)真题解析
C/C++等级考试(1~8级)全部真题・点这里 第1题:双端队列 定义一个双端队列,进队操作与普通队列一样,从队尾进入。出队操作既可以从队头,也可以从队尾。编程实现这个数据结构。 时间限制:1000 内存限制:65535输入 第一行输入一个整数t,代表测试数据的组数。 每组数据的…...
SpringBoot 源码解析
前言 本文只是纯源码分析文章,阅读者需要有Spring或者SpringBoot使用经验。 SpringBoot 源码解析 SpringBoot 源码解析1:环境搭建 SpringBoot 源码解析2:启动流程1 SpringBoot 源码解析3:启动流程2 SpringBoot 源码解析4&#…...

dockerfile---创建镜像
dockerfile创建镜像:创建自定义镜像。 包扩配置文件的创建,挂载点,对外暴露的端口。设置环境变量。 docker镜像的方式: 1、基于官方源进行创建 根据官方提供的镜像源,创建镜像,然后拉起容器。是一个白板,…...
Raspberry PI + Codesys + EtherCAT步进驱动ECR60 Motion功能测试
原文连接:Raspberry PI Codesys EtherCAT步进驱动ECR60 Motion功能测试 – 个人资料收集 (rtplc.com) <div class"post_info_wrapper "> <p class"has-drop-cap">运动控制功能是codesys及EtherCAT通讯的重要功能&am…...

03 Temporal 详细介绍
前言 在后端开发中,大家是否有遇到如下类型的开发场景 需要处理较多的异步事件需要的外部服务可靠性较低需要记录保存某个对象的复杂状态 在以往的开发过程中,可能更多的直接使用数据库、定时任务、消息队列等作为基础,来解决上面的问题。然…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...