记录开发微信扫码登录过程遇到的问题(功能尚未完成)

前言

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

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

微信对接

微信对接的基本流程是:微信服务器向开发者在微信公众平台提供的服务器地址发送请求,然后服务器返回原样给微信服务器请求内容,微信服务器验证通过后对接成功。
因为这个过程中涉及到了微信服务器向服务器发起请求,如果服务器位于内网,那么外界就无法访问到,所以需要通过内网穿透将内网的服务器映射到外网。
记录开发微信扫码登录过程遇到的问题(功能尚未完成)_第1张图片
首先尝试使用了ngrok,尝试对接时却发现调用不到后台的方法,但是在本机上使用浏览器访问外网地址就可以出发对应的方法。
发现出现以上情况是因为在访问ngrok提供的外网地址时,会先弹出一个界面记录开发微信扫码登录过程遇到的问题(功能尚未完成)_第2张图片
所以微信服务器接收到的返回值实际上是这个界面,最终也就配置失败了。

ngrok没有成功之后切换使用frp工具来内网穿透,不过使用frp需要有一台公网的服务器。

Invalid Host Header

微信对接完成之后通过外网地址访问服务出现了Invalid Host Header的错误
记录开发微信扫码登录过程遇到的问题(功能尚未完成)_第3张图片
如果在本机访问服务可以正常访问。

出现原因如下:

"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即可。
记录开发微信扫码登录过程遇到的问题(功能尚未完成)_第4张图片

解决问题时发现在浏览器的开发者工具中查看网络请求没有host字段。应该是因为浏览器通常会将请求头分组并隐藏许多头信息,包括 Host 头。
Chrome 浏览器的开发者工具文档
记录开发微信扫码登录过程遇到的问题(功能尚未完成)_第5张图片
记录开发微信扫码登录过程遇到的问题(功能尚未完成)_第6张图片

未获取到sessionId(xAuthToken)

记录开发微信扫码登录过程遇到的问题(功能尚未完成)_第7张图片
这里获取不到sessionId,打印后发现map的内容为空,说明webSocket没有向map中存值,map的值是通过webSocket来获取的。
记录开发微信扫码登录过程遇到的问题(功能尚未完成)_第8张图片
不过这个方法并没有被调用,所以webSocket连接并没有成功。
检查后发现我的项目中建立连接的代码没有执行所以前台无法通过webSocket连接向map存值。

建立webSocket连接。

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

可以扫码绑定,无法扫码登录

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

private currentLoginUser$ = new ReplaySubject(1);

WebsocketService

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

订阅用户,用户变化时重新建立连接。
着陆组件中初始化用户

this.userService.initCurrentLoginUser();

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

this.setCurrentLoginUser(undefined);

接收到的appId与自己的不符

用户扫码后微信服务器向开发服务器推送消息时包含的信息涉及appid。
在后台配置完成之后进行扫码操作时,后台接收到的信息:

image.png

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

记录开发微信扫码登录过程遇到的问题(功能尚未完成)_第9张图片

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

Subject示例

Subject

订阅之后有新值再发布

记录开发微信扫码登录过程遇到的问题(功能尚未完成)_第10张图片

记录开发微信扫码登录过程遇到的问题(功能尚未完成)_第11张图片

BehaviorSubject

订阅时接收到上一次发布的值。创建该对象时需要指定初值。

记录开发微信扫码登录过程遇到的问题(功能尚未完成)_第12张图片

记录开发微信扫码登录过程遇到的问题(功能尚未完成)_第13张图片

ReplaySubject

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

记录开发微信扫码登录过程遇到的问题(功能尚未完成)_第14张图片

记录开发微信扫码登录过程遇到的问题(功能尚未完成)_第15张图片

总结

开发过程也遇到不少问题,发现对一些基本内容的了解上有所欠缺,如SpringBootSecurity登录认证,host等。也学习到了一些新的内容,之后在平常的学习中需要注意多去扩展一些新内容。

你可能感兴趣的:(记录开发微信扫码登录过程遇到的问题(功能尚未完成))