提供用户登录以及维护用户的登录状态,是一个拥有用户系统的软件应用普遍需要做的事情。像微信这样的一个社交平台,如果做一个小程序应用,我们可能很少会去做一个完全脱离和舍弃连接用户信息的纯工具软件。

让用户登录,标识用户和获取用户信息,以用户为核心提供服务,是大部分小程序都会做的事情。我们今天就来了解下在小程序中,如何做用户登录,以及如何去维护这个登录后的会话(Session)状态。

在微信小程序中,我们大致会涉及到以下三类登录方式:

  • 自有的账号注册和登录
  • 使用其他第三方平台账号登录
  • 使用微信账号登录(即直接使用当前已登录的微信账号来作为小程序的用户进行登录)
第一和第二种方式是目前Web应用中最常见的两种方式,在微信小程序中同样可以使用,但是需要值的注意的是,小程序中没有Cookie的机制,所以在使用这2种方式前,请确认你们或第三方的API是否需要依赖Cookie;还有小程序中也不支持HTML页面,那些需要使用页面重定向来进行登录的第三方API就需要改造,或不能用了。
 
我们今天主要来讨论一下第三种方式,即如何使用微信账号进行登录,因为这种方式和微信平台结合最紧密,用户体验比较好。
 

登录流程

引用小程序官方文档的登录流程图,整个登录流程基本如下图所示:

登录流程图

该图中,“小程序”指的就是我们使用小程序框架写的代码部分,“第三方服务器”一般就是我们自己的后台服务程序,“微信服务器”是微信官方的API服务器。

下面我们来逐步分解一下这个流程图。

步骤1:在客户端获取当前登录微信用户的登录凭证(code)

在小程序中登录的第一步,就是先获取登录凭证。我们可以使用wx.login()方法并得到一个登录凭证。

我们可以在小程序的App代码中发起登录凭证请求,也可以在其他任何Page页面代码中发起登录凭证请求,主要根据你小程序的实际需要。

 App({
onLaunch: function() {
wx.login({
success: function(res) {
var code = res.code;
if (code) {
console.log('获取用户登录凭证:' + code);
} else {
console.log('获取用户登录态失败:' + res.errMsg);
}
}
});
}
})

步骤2:将登录凭证发往你的服务端,并在你的服务端使用该凭证向微信服务器换取该微信用户的唯一标识(openid)会话密钥(session_key)

首先,我们使用wx.request()方法,请求我们自己实现的一个后台API,并将登录凭证(code)携带过去,例如在我们前面代码的基础上增加:

 App({
onLaunch: function() {
wx.login({
success: function(res) {
var code = res.code;
if (code) {
console.log('获取用户登录凭证:' + code); // --------- 发送凭证 ------------------
wx.request({
url: 'https://www.my-domain.com/wx/onlogin',
data: { code: code }
})
// ------------------------------------ } else {
console.log('获取用户登录态失败:' + res.errMsg);
}
}
});
}
})

你的后台服务(/wx/onlogin)接着需要使用这个传递过来的登录凭证,去调用微信接口换取openid和session_key,接口地址格式如下所示:

https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

这里是我使用了Node.js Express构建的后台服务的代码,仅供参考:

 router.get('/wx/onlogin', function (req, res, next) {
let code = req.query.code request.get({
uri: 'https://api.weixin.qq.com/sns/jscode2session',
json: true,
qs: {
grant_type: 'authorization_code',
appid: '你小程序的APPID',
secret: '你小程序的SECRET',
js_code: code
}
}, (err, response, data) => {
if (response.statusCode === 200) {
console.log("[openid]", data.openid)
console.log("[session_key]", data.session_key) //TODO: 生成一个唯一字符串sessionid作为键,将openid和session_key作为值,存入redis,超时时间设置为2小时
//伪代码: redisStore.set(sessionid, openid + session_key, 7200) res.json({ sessionid: sessionid })
} else {
console.log("[error]", err)
res.json(err)
}
})
})

这段后台代码成功执行的话,就可以得到openid和session_key。这个信息就是当前微信账户在微信服务器那边的登录态了。

但是,为了安全方面的原因,请不要直接使用这些信息作为你小程序的用户标识和session标识回传到小程序客户端中去,我们应该在服务器端做一层自己的session,将这个微信账号登录态生成一个session id并维护在我们自己的session机制中,然后把这个session id派发到小程序客户端作为session标识来使用。

关于如何在服务器端做这个session机制,我们现在一般采用键值对存储工具来做,比如redis。我们为每个session生成一个唯一的字符串作为键,然后可以将session_key和openid作为值,存入redis中,为了安全,存入的时候还应设置一个超时的时间。

步骤3:在客户端保存sessionid

开发Web应用的时候,在客户端(浏览器)中,我们通常将session id存放在cookie中,但是小程序没有cookie机制,所以不能采用cookie了,但是小程序有本地的storage,所以我们可以使用storage来保存sessionid,以供后续的后台API调用所使用。

在之后,调用那些需要登录后才有权限的访问的后台服务时,你可以将保存在storage中的sessionid取出并携带在请求中(可以放在header中携带,也可以放在querystring中,或是放在body中,根据你自己的需要来使用),传递到后台服务,后台代码中获取到该sessionid后,从redis中查找是否有该sessionid存在,存在的话,即确认该session是有效的,继续后续的代码执行,否则进行错误处理。

这是一个需要session验证的后台服务示例,我的sessionid是放在header中传递的,所以在这个示例中,是从请求的header中获取sessionid:

router.get('/wx/products/list', function (req, res, next) {
let sessionid = req.header("sessionid")
let sessionVal = redisStore.get(sessionid) if (sessionVal) {
// 执行其他业务代码
} else {
// 执行错误处理
}
})

好了,通过微信账号进行小程序登录和状态维护的简单流程就是这样,了解这些知识点之后,再基于此进行后续的开发就会变得更容易了。

另外,腾讯前端团队也开源了他们封装的相关库,可以借鉴和使用。

文章出处:一斤代码大神

微信小程序中用户登录和登录态维护的更多相关文章

  1. 微信小程序中用户唯一ID的获取

    折腾到半夜,搞得挺兴奋,总结一下,免得忘了: 1.微信小程序直接获得的是一些简单信息,基本无用 2.用户唯一标识是openid,还有一个unionid是关联多个公众号之类情况下用,我不大关心 3.在g ...

  2. 微信小程序中登录操作-----与-----引用

    login.wxml <view> <!-- <image src="./88.png"></image> --> # 在当前目录下 ...

  3. 微信小程序 获取用户信息并保存登录状态

    微信小程序 获取用户信息并保存登录状态:http://www.360doc.com/content/18/0124/11/9200790_724662071.shtml

  4. 微信小程序中如何使用WebSocket实现长连接(含完整源码)

    本文由腾讯云技术团队原创,感谢作者的分享. 1.前言   微信小程序提供了一套在微信上运行小程序的解决方案,有比较完整的框架.组件以及 API,在这个平台上面的想象空间很大.腾讯云研究了一番之后,发现 ...

  5. 全栈开发工程师微信小程序-中(下)

    全栈开发工程师微信小程序-中(下) 微信小程序视图层 wxml用于描述页面的结构,wxss用于描述页面的样式,组件用于视图的基本组成单元. // 绑定数据 index.wxml <view> ...

  6. 在微信小程序中使用LeanCloud(一)

    之前学习了微信小程序前端,使用到LeanCloud线上数据库 [传送门].作为一个前端开发人员,了解后端及数据库是学习工作的需要. LeanCloud直接登录,未注册直接创建账户.它是一款免费的线上数 ...

  7. Laravel wxxcx 微信小程序获取用户信息

    wxxcx 是Laravel5微信小程序登录获取用户信息扩展 部署 12345678 # 安装$ composer require iwanli/wxxcx# 注册服务# 在 /config/app. ...

  8. 微信小程序中的app.js-清除缓存

    微信小程序中的app.js 关于小程序app.js生命周期的介绍 App(Object) App() 函数用来注册一个小程序.接受一个 Object 参数,其指定小程序的生命周期回调等. App() ...

  9. 微信小程序中发送模版消息注意事项

    在微信小程序中发送模版消息 参考微信公众平台Api文档地址:https://mp.weixin.qq.com/debug/wxadoc/dev/api/notice.html#模版消息管理 此参考地址 ...

随机推荐

  1. spring boot(四) 多数据源

    前言 前一篇中我们使用spring boot+mybatis创建了单一数据源,其中单一数据源不需要我们自己手动创建,spring boot自动配置在程序启动时会替我们创建好数据源. 准备工作 appl ...

  2. Spark框架详解

    一.引言 作者:Albert陈凯链接:https://www.jianshu.com/p/f3181afec605來源:简书 Introduction 本文主要讨论 Apache Spark 的设计与 ...

  3. 如何将html特殊字符编码转换成特殊字符_html十进制编码字符转回来

    备注:有时候我们会莫名其妙遇到一些特殊字符:  这些字符在网页上能正常显示,但是在APP特殊情景并不识别这些字符: 如:'     这个其实是单引号:   '     百度后发现,它其实是HTML特殊 ...

  4. Restful API设计规范及实战

    Restful API的概念在此就不费口舌了,博友们网上查哈定义文章很多,直入正题吧: 首先抛出一个问题:判断id为 用户下,名称为 使命召唤14(COD14) 的产品是否存在(话说我还是很喜欢玩类似 ...

  5. C# 设置Excel超链接(一)

    在日常工作中,在编辑文档时,为了方便自己或者Boss能够实时查看到需要的网页或者文档时,需要对在Excel中输入的相关文字设置超链接,那么对于一些在Excel中插入的图片我们该怎么实现超链接呢,下面给 ...

  6. Java小工具 根据文本批量修改文件名

    功能 可以根据使用路径修改文件名,已经测试,可以成功运行 思路 先是读取到txt文本文件,之后使用String的spilt进行分割,每一行的格式为 旧名字 新名字,中间的空格可以使用|或者其他字符代替 ...

  7. vue 组件通信

    组件 组件之间的数据是单向绑定的. 父组件向子组件通信 是通过子组件定义的props属性来实现.通过props定义变量与变量类型和验证方式. props简化定义 在简化定义中,变量是以数组的方式定义. ...

  8. selenium chrome在新标签页打开链接的方法

    目前chrome是我在实现webdriver时运行最稳定的浏览器,如何利用webdriver打开多个标签页和链接呢,到处查找得到的往往只是如何打开标签页.打开标签页很简单,chrome浏览器打开标签页 ...

  9. springboot 使用 redis

    springboot 自己是实现了一套 redis 缓存框架, 地址: https://www.cnblogs.com/huanggy/p/9473822.html, 通过配置即可轻松愉快地实现 某些 ...

  10. Android Studio集成Flutter

    首先Flutter中文网教程地址:https://flutterchina.club/get-started/install/ 1.新建环境变量 变量名:PUB_HOSTED_URL 变量值:http ...