《微信小程序七日谈》系列文章:

  1. 第一天:人生若只如初见
  2. 第二天:你可能要抛弃原来的响应式开发思维
  3. 第三天:玩转Page组件的生命周期
  4. 第四天:页面路径最多五层?导航可以这么玩
  5. 第五天:你可能要在登录功能上花费大力气

本系列的文章并非初学教程,而是笔者在具体开发过程中遇到的问题以及部分解决方案。

前几篇文章的内容主要集中于小程序开发框架中的一些机制细节,基本上都是客户端层面的知识。随着小程序项目的不断深入,我们不得不面对一些需要客户端与服务端协同完成的需求,比如用户登录功能。

大多数的小程序都会有自身的用户体系,然而小程序必须要经过微信账户的验证授权,然后再与第三方服务器(也就是公司自己的服务器)通信实现用户的登录。这里面就涉及到微信账户信息与自身用户信息的耦合。下面就简单介绍一下我们项目目前实现用户登录的技术细节。

浏览器环境下登录的实现方案

在制定具体实现方案之前,我们首先思考一下用户登录功能需要注意哪些细节。通常来讲,实现用户登录功能需要注意以下两点:

  1. 登录状态保存;
  2. 安全验证。

登录状态保存就是登录成功后请求站内数据接口时无需再次登录,客户端与服务器按照既定的规则进行用户有效性验证。浏览器环境下的登录状态保存通常使用cookie实现,这种方案的实现原理是浏览器发出的http请求header中会携带客户端的cookie。如下图:

安全验证是为了应对流量劫持,防止中间人攻击,在我们的页面中插入乱七八糟的内容。大家可能会想到使用https来防止流量劫持。https可以应对绝大部分的应用场景,有效的防止流量劫持。但其实市场上有一些“黑科技”软件可以捕获并且解密https加密信息的,比如Fiddler。所以在https的基础上,再进行一层安全验证是还有必要的。

大家可以参考这篇文章了解fiddler解密https的知识。

自定义安全验证通常的方案是客户端与服务器约定好一个验证签名,客户端在发出http请求之前按照约定好的算法计算出一个签名字符串,并且在http请求中将计算签名的参数传递给服务器。服务器接收到请求之后,解析出签名字符串和客户端传递的计算参数,然后按照同样的算法计算出签名字符串,并将其与客户端的签名进行对比,完全一致则验证通过,否则返回验证未通过的数据。如下图:

上述流程成立的前提条件是:

  1. 浏览器可以获取到UA信息;
  2. 浏览器发出的http请求header中会携带UA信息,服务器可以获取。

那么这套方案在小程序平台上是否可以复用呢?答案是否定的。

小程序的限制

目前我们所知的小程序存在以下限制:

  • 不支持cookie,所以使用cookie储存登录状态的方案不可行;
  • http请求header不携带设备信息,服务器无法获取。

但是我们在吐槽小程序重重限制的同时得到了一个好消息:http请求可以自定义header。我们仿佛看到了解决问题的银弹。

使用自定义header传递敏感信息

登录识别信息在无法使用cookie传递的限制下只有两种传输途径:

  1. url query
  2. http header

小程序提供了获取设备信息的API,提供了在客户端计算签名字符串的参数。按前文提到的验证规则,客户端计算签名的参数必须传递给服务器才能保证两端计算的一致性。所以我们又面临了之前的抉择,是query还是header?

其实使用任何一种途径都可以完成需求,但是url query(通常称为data)的语义应该是与接口功能紧密相关的数据,并且http请求的header比url query数据更保密,所以我们团队最终采用header传递登录识别信息和设备信息的方案。

登录实现方案

确定信息的传递方式只是第一步,在小程序平台下实现自己的用户登录仍然有很多细节需要琢磨。我们首先看一下官方文档给出的第三方登录流程图:

官方文档给出的流程是实现第三方登录的基本流程,但是具体的登录功能中仍然有一些细节上的不同,比如:

  • 手机验证码登录;
  • 3rd_sessionopenId不能明文暴露给客户端,需要进行加密;
  • 登录状态保存的有效期;
  • 用户登录的服务器与基础服务的服务器并不是同一台。

在小程序登录机制的基础上,我们团队在制定安全登录功能时最终采用了如下方案:

对比微信官方的登录流程图,有以下几个细节:

  1. 3rd_sessionopenId不直接暴露给客户端,而是通过可逆的加密算法进行加密后,组合成token暴露给客户端;
  2. 第一次请求基础功能服务器时并不验证签名,此次请求的目的是从微信服务器获取3rd_sessionopenId并且加密后返回客户端,以便后续请求使用;
  3. 第二次请求的目标是用户服务器,携带token的sign。用户服务器首先会进行签名验证和手机验证码校验;
  4. 验证通过后解析token获取3rd_sessionopenId,然后与uid结合重新计算token。最后将uid和token一并返回给客户端。

用户登录成功后,客户端将uid和token储存在本地,以便后续请求数据接口使用。

客户端储存token和uid的方式可以采用storage或者app.globalData

数据接口的请求验证方案

数据接口是在用户登录成功之后才可以进行请求,相比较登录功能,数据接口的请求验证方案要简单很多。如下图:

接口请求只需验证sign以及token即可,如果token错误或者已过期,则返回客户端重新登录的标识。

总结

想在微信小程序中实现自己的用户体系需要花费一些力气,每个公司都有自身的用户登录验证体系,同时还要考虑安全性和状态保存问题。在小程序不支持cookie、http请求header不携带设备信息等限制下,实现登录功能的各种细节都需要采用一些折中的手段。而且往往这些方案显得有些臃肿并且难以维护,非常考验开发者的抽象能力。

本篇文章阐述的是笔者团队目前采用的登录实现方案,并非最佳实践,许多细节仍需打磨。希望可以给大家一些参考。

《微信小程序七日谈》- 第五天:你可能要在登录功能上花费大力气的更多相关文章

  1. 《微信小程序七日谈》- 第四天:页面路径最多五层?导航可以这么玩

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩 微信小 ...

  2. 《微信小程序七日谈》- 第二天:你可能要抛弃原来的响应式开发思维

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩 上篇文 ...

  3. 《微信小程序七日谈》- 第一天:人生若只如初见

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩 微信小 ...

  4. 《微信小程序七日谈》- 第六天:小程序devtool隐藏的秘密

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩: 第五 ...

  5. 《微信小程序七日谈》- 第七天:不要捡了芝麻丢了西瓜

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩: 第五 ...

  6. 《微信小程序七日谈》- 第三天:玩转Page组件的生命周期

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩 前两篇 ...

  7. 微信小程序把玩(五)页面生命周期

    原文:微信小程序把玩(五)页面生命周期 这里只要熟悉页面的基本生命周期即可,业务在指定生命周期函数内书写. 以下是官网给出的生命周期函数方法和状态图 上面的生周期函数图对于做Android 或者IOS ...

  8. 微信小程序从零开始开发步骤(四)自定义分享的功能

    上一章节,实现了小程序的底部导航的功能,这一节开始实现一些简单的功能.本章节介绍的是小程序的自定义分享的功能. 可以分享小程序的任何一个页面给好友或群聊.注意是分享给好友或群聊,并没有分享到朋友圈.一 ...

  9. 1个多商户、多平台版 微信小程序(多商户、多平台版),影城行业、影业连锁 多商户、多平台版微信小程序。(基于多平台版,支持在业务上 可给 每个单独影城 分发定制单独的小程序版本)

    1个 影城行业 微信小程序(多商户.多平台版), 影业连锁 多商户.多平台版微信小程序.(基于多平台版,支持在业务上 可给 每个单独影城 分发定制单独的小程序版本) 资讯QQ: 876635409  ...

随机推荐

  1. Windows Server 2008安装 百度Wifi \ 360Wifi \ 小米Wifi 失败的解决方法

    服务器管理 -> 功能 -> 安装 [无线LAN]服务

  2. 快速构建Windows 8风格应用15-ShareContract构建

    原文:快速构建Windows 8风格应用15-ShareContract构建 本篇博文主要介绍共享数据包.如何构建共享源.如何构建共享目标.DataTransferManager类. 共享数据包 Da ...

  3. 读书笔记—CLR via C#章节8-10

    前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...

  4. jsp解决kindeditor在线编辑器struts图片上传问题

    1.下载 官网下载ckeditor,解压后去掉不需要的部分,仅需保留plugin,lang,theme文件夹,这三个文件夹中用不到的东西可以删除, 比如lang文件下存放所有语言文件js,仅仅 保留e ...

  5. DDD(领域驱动设计)理论结合实践

    DDD(领域驱动设计)理论结合实践   写在前面 插一句:本人超爱落网-<平凡的世界>这一期,分享给大家. 阅读目录: 关于DDD 前期分析 框架搭建 代码实现 开源-发布 后记 第一次听 ...

  6. .NET MVC学习之模型绑定

    ASP.NET MVC学习之模型绑定(2)   继ASP.NET MVC学习之模型绑定继续 3.手工调用模型绑定 很多情况下我们都是通过形参的方式接收来自http流中的数据,这看似是完美的,但是缺少了 ...

  7. Leetcode::Pathsum & Pathsum II

    Pathsum Description: Given a binary tree and a sum, determine if the tree has a root-to-leaf path su ...

  8. cocos2d(CCSprite绑定不规则刚体与精灵一起移动)

    对于不规则的精灵我们可以借助PhysicsEditor来制作shape , 对于地图可以使用Tiled软件制作瓷砖地图. 今天主要记录一下如何把CCSprite与不规则刚体进行绑定,然后一起移动 // ...

  9. 把项目做成jar包

    方法一.在eclipse3.1中把项目做成jar包步骤. 打包前的工作. 在项目下创建一个文件夹,名为META-INF,再在其下创建文件MANIFEST.MF 编辑的内容如下: Manifest-Ve ...

  10. Direct2D

    Direct2D Direct2D教程III——几何(Geometry)对象 摘要: 目前博客园中成系列的Direct2D的教程有1.万一的 Direct2D 系列,用的是Delphi 20092.z ...