前言

尝试开发微信扫码性能,参考了两位学长的文章:
https://segmentfault.com/a/1190000043395324
https://segmentfault.com/a/1190000043413908?utm_source=sf-similar-article
性能尚未实现,不过记录一下目前为止在此实现形式上遇到的一些问题;
记录一下相干变量含意:

wsAuthToken:前台生成的uuid。xAuthToken: 用户身份验证令牌map(WebSocketService): 绑定wsAuthToken和xAuthTokenmap(UserServiceImpl): 绑定loginUid和usernameopenid: 微信向开发者提供的用户惟一标识符

微信对接

微信对接的根本流程是:微信服务器向开发者在微信公众平台提供的服务器地址发送申请,而后服务器返回原样给微信服务器申请内容,微信服务器验证通过后对接胜利。
因为这个过程中波及到了微信服务器向服务器发动申请,如果服务器位于内网,那么外界就无法访问到,所以须要通过内网穿透将内网的服务器映射到外网。

首先尝试应用了ngrok,尝试对接时却发现调用不到后盾的办法,然而在本机上应用浏览器拜访外网地址就能够登程对应的办法。
发现呈现以上状况是因为在拜访ngrok提供的外网地址时,会先弹出一个界面
所以微信服务器接管到的返回值实际上是这个界面,最终也就配置失败了。

ngrok没有胜利之后切换应用frp工具来内网穿透,不过应用frp须要有一台公网的服务器。

Invalid Host Header

微信对接实现之后通过外网地址拜访服务呈现了Invalid Host Header的谬误

如果在本机拜访服务能够失常拜访。

呈现起因如下:

"Invalid Host Header" 是由 Web 服务器的平安机制所触发的谬误,通常是为了避免 HTTP Host 坑骗攻打。当 Web 服务器收到一个申请时,它会查看申请头中的 Host 字段是否与服务器上的域名匹配。如果不匹配,则服务器会回绝该申请并返回 "Invalid Host Header" 谬误。

通过浏览器拜访服务器时,申请的Host为abc.com:7005,而后通过nginx将申请转发到服务器上4200端口的web服务上。
在这个过程中,如果nginx设置了proxy_set_header Host $host,nginx在转发时就会将host批改为客户端申请的主机名,也就是abc.com:7005;如果不设置,发送到web服务的host的值就会是nginx所在服务器的域名或IP地址。
因为我这里曾经配置该项,所以我的web服务接管到的申请的host的值是abc.com:7005。而进行测验之后发现申请头中的Host字段与服务器的域名不匹配最终呈现了invalid host header的谬误。
解决该问题只须要在启动开发服务器时候禁用hostCheck即可。

解决问题时发现在浏览器的开发者工具中查看网络申请没有host字段。应该是因为浏览器通常会将申请头分组并暗藏许多头信息,包含 Host 头。
Chrome 浏览器的开发者工具文档

未获取到sessionId(xAuthToken)


这里获取不到sessionId,打印后发现map的内容为空,阐明webSocket没有向map中存值,map的值是通过webSocket来获取的。

不过这个办法并没有被调用,所以webSocket连贯并没有胜利。
查看后发现我的我的项目中建设连贯的代码没有执行所以前台无奈通过webSocket连贯向map存值。

建设webSocket连贯。

在开发扫码登录时,一方面因为代码逻辑问题导致连贯建设失败之外。还有就是没有引入相干的js文件。
在参考文章中,SockJS,Stomp两个类须要独自引入文件来提供,别离是sockjs.min.jsstomp.min.js(见参考文章源码的assets)。
连贯办法:
前台WebsocketService->onInit() => 后盾 WebSocketController->bindToXAuthToken()

能够扫码绑定,无奈扫码登录

通过排查之后,发现是因为在登录界面时,webSocket连贯还未建设,所以扫码之后,后盾服务器无奈向前台推送用于登录的loginUid。前台也就无奈发送登录申请进行登录。问题解决只须要实现在登录界面就建设连贯即可。学长的示例中连贯建设如下:

private currentLoginUser$ = new ReplaySubject<User>(1);

WebsocketService

private onInit(): void {  this.userService?.getCurrentLoginUser$().pipe(first())    .subscribe(() => {      // 连贯代码    });}

订阅用户,用户变动时从新建设连贯。
着陆组件中初始化用户

this.userService.initCurrentLoginUser();

执行error代码,设置用户为undefined,并且前台此时开始尝试建设websocket连贯。

this.setCurrentLoginUser(undefined);

接管到的appId与本人的不符

用户扫码后微信服务器向开发服务器推送音讯时蕴含的信息波及appid。
在后盾配置实现之后进行扫码操作时,后盾接管到的信息:

toUser这个字段值之后被作为WechatUserappid属性的值。
而收到值的始终是如图的gh_d7exxx
与微信公众平台测试号理论的appid不雷同。

可能是因为应用的测试号,不过还没有验证,之后再进行测试。

Subject示例

Subject

订阅之后有新值再公布

BehaviorSubject

订阅时接管到上一次公布的值。创立该对象时须要指定初值。

ReplaySubject

订阅时接管到之前缓存的值,数量在创立该对象时指定。

总结

开发过程也遇到不少问题,发现对一些根本内容的理解上有所欠缺,如SpringBootSecurity登录认证,host等。也学习到了一些新的内容,之后在平时的学习中须要留神多去扩大一些新内容。