c#与access建立连接用作登录_【网页版】使用小程序码登录

efe39fa85ead322dccc6853e6d205dc0.png
导语:目前,大部分网站都是用户扫二维码登录,那是否可以换成更花里胡哨的小程序码呢?从而优雅的给自己小程序带量呢?让阿特来带你飞。

话说最近这段日子,阿特观察到阿美无精打采的

阿特:怎么啦?阿美

阿美:哎,小程序的量,跟你头上的发量一样,涨上不去呀

阿特陷入了深思,过了几天,阿特约上阿美说要给她一个惊喜,原来阿特找到了带量的方式,将网站的微信登录二维码换成小程序码,这样用户在扫码登录的同时就打开了小程序,阿美听后兴奋的抱住了阿特,你真是个天才,从此阿特过上了幸福生活。

网页版接入的是微信开放平台微信登录,用户扫描二维码,打开微信授权登录页,确认登录,网站进行微信登录,现在切换为小程序码,同样是用微信扫码,打开的是自己小程序的登录页,登录成功后,同步登录态给网页,小程序侧则可自由发挥,跳转首页,个性换推荐等场景。整个效果如下【视频】:

d657570b92bbf753c87b5860dc981533.png
小程序码登录https://www.zhihu.com/video/1217525613013184512

那具体是怎么样实现的呢?

一、准备工作

先让我们来看看微信扫码登录,扫web显示的微信二维码,打开一个页面,授权登录后,web页面怎么就有反应了?用户所感知到的只是一个含有二维码的web登录页和一个微信app提供的授权登录页。了解到,码只是信息的载体,是0-1序列,微信扫码后根据特定规则解析为字符串,根据字符串特征或打开一个native页面,或打开一个webview。那这两者如何交互呢?答案是中转后台,用户在小程序登录页上的行为被同步给中转后台,web页通过轮询方式获取到用户行为状态,请看下图:

https://open.weixin.qq.com/connect/confirm?uuid=071fiCyKX-5RgaFI (二维码自动识别)

那是如何登录的呢?在用户确认登录后,微信会生成一个临时code,web页轮询到这个code后,发生真正的业务登录行为,详细请看后面的【微信/QQ等扫码登录的秘密】

还有一个问题是码也需要过期,如何控制码的过期呢?本质上,码只是一张图片,因此需要将码与一个状态绑定,这个状态查询不到了,表明码过期,我们需要后台在一定时间后能自动清除这个状态,redis适合这样的存储场景

因此,要想把二维码切换为自己的小程序码,我们需要替换微信提供的二维码和授权登录页,还有一个使用redis做存储的中转后台。

二维码==》小程序码

微信APP授权登录页 ==》小程序登录页

微信中转后台==》自己的中转后台

二、功能模块设计

老规矩,先上图,整体流程:

cf0a69396f68f208825fce50c2764eaf.png

1、生成小程序码通用node服务

微信小程序有提供后台接口生成小程序码,详细请看微信小程序生成小程序码后台接口,但需要小程序access_token(由小程序appid+appsecret通过微信后台接口获取),我们可以搭建一个通用node服务,集成上述生成小程序码所需调用接口,返回一个小程序码,也方便后续其他小程序生成小程序码。

2、web登录页

鉴于以前接入微信登录的方式是在自己网站嵌入微信开放平台提供的登录页,详细请戳,所以这里我们开发一个单独的页面,替换微信提供的页面就好。这个页面的主要功能是提供一个小程序码,通过websocket和轮询方式获取二维码状态,以获得用户当前操作步骤或判断二维码是否过期,在最终拿到登录态后,同步给父页面即可。

3、小程序扫码登录落地页

这个页面作为用户扫码打开的落地页,会把用户扫码成功、取消登录,确认登录行为同步到node中转后台,进而同步到web登录页。同时,用户登录和登录续期是在这里发生的,如果小程序本地有登陆态,则走登录续期,否则通过wx.login获取临时code再到自己登录后台换取登陆态

4、node中转后台

写服务:一是提供临时状态存储,将二维码生成成功、扫码成功、确认登录、取消登录这些状态写入redis,确认登录时,状态和登录态一并写入,并设置过期时间,过期自动清理;二是通知websocket服务当前写入的状态,websocket服务在通知页面更新UI状态 读服务:主要是供页面轮询当前状态,以显示相应UI,作为一个兜底

5、websocket服务

本身web登录页与node中转后台的通讯是有轮询的,但是为了更快速的通知当前用户操作状态,多加了一层ws。所有状态在写入的时候,同步到ws,ws在同步到页面。这里也可以做成一个通用的ws接入层,对前端提供连接、转发数据请求服务,对后台提供http接口,后台通过调用提供的http接口给前端推送消息。

6、登录后台

可以通过临时code+appid+appsecret换取到业务自己的登录态

三、详细实现

1、生成小程序码node服务

微信是有提供后台api生成指定路径和参数的小程序码,通过小程序appid和appsecret可以获取到小程序接口调用凭证access_token,注意,这access_token跟后面登录态里面的不一样,登录态里面的access_token是访问用户接口调用凭证,主体不一样,再用access_token去换取小程序码 appid+appsecret ==》access_token ==> 微信生成小程序码

2、web登录页

交互流程如下:

344ef2a688f2668cfd1bc2b88073878e.png

一打开这个登录页,就建立与websocket服务的ws连接,获取到贯穿整个登录流程的一个唯一key,如果不支持ws,则前端自己生成一个随机唯一key,并开启轮询,轮询中转后台当前用户操作状态,这里轮询的目的是兜底,万一不支持ws或者ws连接中断,也能保证正常拿到用户操作状态,进而做出相应操作,用ws的目的是更快的同步用户操作状态。

调用生成小程序码服务,获取到小程序码,小程序码中包含了扫码打开的页面路径以及打开这个页面所需参数,包括上面那个唯一key,然后通知中转后台,小程序码生成成功,自此,小程序码生命周期开始。中转后台写入redis是以唯一key为key,以码生成成功状态为value的值键对,加上过期时间,目前为5分钟,一旦页面轮询不到这个唯一key,就说明二维码过期了。

用户在确认登录后,页面需要向中转后台请求,由中转后台将登录态写入cookie,并清除redis中相应key的存储,页面在同步这个cookie到自己的域名下,当然,这里这样做是为了尽量减少改动,还有其他的方式,比如中转后台直接返回登陆态,由页面自己写到cookie。

3、小程序登录落地页

交互流程图如下:

72c893fd5af3ad1ccb91174b6df70324.png

用户扫码成功后,应该尽早的通知中转后台扫码成功(如:onLoad生命周期),进而通知到web登录页显示扫码成功。 然后可预请求登录后台(如:onReady生命周期),获取用户登录态,如果本地有登录态,则走续期,续期可能会失败,因为续期票据也会失效,如果续期失败,重新走登录流程,如果没有,则走登录流程,通过wx.login获取当前微信用户当前小程序下的临时code,登录后台用这个code获取openid,access_token和refresh_token,再用这个openid换取视频自己票据,并保存在本地storage,便于下次续期用。关于openid,access_token和refresh_token的具体含义,下面会有说明。

待用户点确认登录后,可以马上通知中转后台并带上预请求的登录态。

另外需要说明的是,以前小程序的登录流程与微信开放平台流程一致,比较容易获取用户头像和昵称,现在流程如下图(来自官方文档):

62078da4ca0cf06ef0f74c6fc09a6d42.png

可以看到,目前小程序的登录是拿不到用户的access_token和refresh_token,也就意味着后台不能从微信服务器直接拿到用户信息,需要小程序侧通过组件(<button class="info_btn" open-type="getUserInfo" bindgetuserinfo="getWxUserInfo" />)或其他方式拿到后同步给后台。

此外,这个落地页不跟其他页面耦合,完全可以采用独立分包的方式来开发,以加快打开速度,用独立分包,目前你会遇到的一个问题是独立分包不能引用任何主包资源,哈哈哈哈,这就意味着,主包中的请求器、数据上报等模块不能复用,copy???那是不可能的,这里提供一个方法是在独立分包页面下,通过webpack将所有模块打包到一个js文件,页面的js文件加载打包好的这个文件即可。

b4592a255f222d04a83a671eb498027a.png

4、node中转后台 整个小程序码登录的过程有如下几个状态:

const REQ_INIT = 1 // 码成功生成 
const REQ_SCAN_SUCC = 2 //扫码成功 
const REQ_CANCEL_LOGIN = 3 //取消登陆 
const REQ_CONFIRM_LOGIN = 4 //确认登陆 
const REQ_REMOVE_STATUS = 5 //删除登录状态

以上面所说的唯一key为key,状态值为value做为值键对存储于redis,并设置过期时间,一旦过期,整个登录失败。因为登录特殊,为防止意外,在写入状态时,进行了双写,比如申请了两个redis。可以以其中一个redis为主,另外一个redis为辅,当读取主redis失败时,去读取辅redis数据。

一个写接口: 小程序码创建成功后,中转后台写入redis,{key:1},过期时间5分钟,这个时间是整个登录流程的过期时间,过期redis自动清除。

用户扫码成功,中转后台先redis里面读是否有当前key状态的status,如果没有,说明用户扫的是无效码,返回错误码,由小程序侧根据错误码做提示;如果status是2,则不必复写,直接返回成功,因为其他人已经扫码成功,业务侧提示不会变更;如果status是1或3,则需要复写redis,{key:2},因为有人重新扫码成功了,并且继承原来这个key的剩余过期时间;如果status是4,表明当前有用户已经确认登录了,这个时候不做处理,直接返回成功。

用户取消登录,同样先读redis当前key状态status,如果没有,无效码,如果status是1或者2,则复写redis,继承原来这个key的剩余过期时间,{key:3},如果status是3或者4,直接返回,没必要写。

确认登录,同样先读redis当前key状态status,如果没有,无效码,如果status是1、2或者3,则复写redis,继承原来这个key的剩余过期时间,这时候的value就是状态加登录态了,{key:4_登陆态},如果status是4,直接返回。

上面所有状态在写入redis的同时会同步给websocket服务,ws在通知页面。 一个读接口:根据唯一key读取redis中存储的状态和登陆态

四、微信/QQ等扫码登录的秘密

既然说了小程序码,那微信/QQ等提供了扫码登录的平台是如何实现登录的呢?其实大同小异,以微信登录为例,看看整个登录流程,如下图:

511274679f24be58009f493f57f20f17.png

通用web登录页提供二维码和状态轮询,并在轮询到用户临时授权code后重定向到业务侧登录后台,业务侧后台用appid+appsecret+code获取用户当前appid下的openid,access_token和refresh_token,进而用openid获取到关联的业务登录态,用openid+access_token去微信用户信息后台获取用户头像、昵称等信息。

appid:应用id,是微信分配给应用的唯一标识

openid:用户开放id,一个appid下,用户的openid唯一,并且公司内部是可以申请一个应用openid转另外一个应用openid的

access_token:访问令牌,访问用户接口调用凭证,如获取用户头像昵称,必须要这个参数,目前有效期为2个小时

refresh_token:刷新令牌,用来刷新access_token,有效期目前为30天,refresh_token过期后必须要用户重新走一遍上述流程才能拿到,这就是为什么微信登录最长只能维持30天的原因。

五、与微信二维码登录相比,小程序码登录优势

1、如阿特所说,可以给小程序带来网站微信登录用户流量

2、使用小程序码登录,用户真正登录行为发生在小程序上,同步给网页的是登录态,相比于微信二维码登录同步给网页临时code,然后在重定向到业务登录后台换取登录态方式,小程序码方式少了一次请求,带来更佳用户体验

3、整体登录流程,UI更可控,也便于登录问题定位

六、总结

其实,上述切换小程序码的整个服务是通用的,其他网站想切换小程序码登录所需要做的事情将会非常少:

1、自己的小程序登录落地页

2、业务侧登录后台,可用小程序临时code换到自己的登录态

18b0e4fee3b275e13f9f111eb5646b44.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值