微信小程序中做用户登录与登录态维护的实现详解
作者:一斤代码 发布时间:2024-04-08 10:53:44
总结
大家都知道,在开发中提供用户登录以及维护用户的登录状态,是一个拥有用户系统的软件应用普遍需要做的事情。像微信这样的一个社交平台,如果做一个小程序应用,我们可能很少会去做一个完全脱离和舍弃连接用户信息的纯工具软件。
让用户登录,标识用户和获取用户信息,以用户为核心提供服务,是大部分小程序都会做的事情。我们今天就来了解下在小程序中,如何做用户登录,以及如何去维护这个登录后的会话(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 {
// 执行错误处理
}
})
好了,通过微信账号进行小程序登录和状态维护的简单流程就是这样,了解这些知识点之后,再基于此进行后续的开发就会变得更容易了。
另外,腾讯前端团队也开源了他们封装的相关库,可以借鉴和使用。
服务器端库 weapp-session
小程序端库 weapp-session-client
来源:http://www.jianshu.com/p/c5f6c98b2685
猜你喜欢
- 使用 Python 进行数据处理的时候,常常会遇到判断一个数是否在一个区间内的操作。我们可以使用 if else 进行判断,但是,既然使用了
- 内容摘要:最近在做项目的时候,客户要求表格里的数据可以拖选,于是用JS写了个下面的方法。支持IE、FIREFOX等浏览器。实现对整行、整列数
- 什么是 PycharmPycharm 是目前最好用的 Python 编辑器,自带文本高亮、版本管理、数据库连接、断点调试、虚拟环境和包管理的
- 本文实例为大家分享了wxPython色环电阻计算器的具体代码,供大家参考,具体内容如下import wx # 导入wxPythonclass
- 之前有写利用md5方式来做差异备份,但是这种md5方式来写存在以下问题:•md5sum获取有些软连接的MD5值存在问题 •不支持对空目录进行
- 用SHOW显示已有的数据库句法:SHOW DATABASES [LIKE wild]如果使用LIKE wild部分,wild字符串可以是一个
- 在SQL Server数据库的维护或者Web开发中,有时需要在存储过程或者作业等其他数据库操作中调用其它的存储过程,下面介绍其调用的方法一、
- 情景描述在项目开发过程中,不同项目阶段可能会有不同的分支,当创建好一个分支后,就需要将代码切换到这个分支上进行代码同步,例如将当前 orig
- 本文实例讲述了Python 类,property属性(简化属性的操作),@property,property()用法。分享给大家供大家参考,
- 本文实例为大家分享了python openCV自制绘画板的具体代码,供大家参考,具体内容如下import numpy as npimport
- 目录一、梳理功能二、准备数据库三、构造和数据库相关的实体类书籍用户NormalUser类四、封装数据库相关操作数据库链接操作针对书籍表操作针
- 数在 Python 中,对数的规定比较简单,基本在小学数学水平即可理解。那么,做为零基础学习这,也就从计算小学数学题目开始吧。因为从这里开始
- 使用本文给出的方法就可以制作出一个简单的rss阅读器了。用xmldom方法打开xml文件,如果是本地的没有问题,就是用Server.MapP
- 无论是对于刚接触编程的初学者,还是已经工作的程序员,哪一门编程语言更火,更有价值和前景,似乎是永远有争议的话题。下面来对比说以下python
- IE 的 Cookie 文件保存在 ?:\Documents and Settings\<user>\Cookies 目录,后缀
- 在过去的两年里,你能想象的一些很烂的应用设计也入驻了优雅的iPhone。通过它周边的宣传,使得世界各地的设计者们都利用这个新的移动工具来一展
- 切换按钮是QPushButton的特殊模式。它是一个具有两种状态的按钮:按压和未按压。我们通过这两种状态之间的切换来修改其它内容。#!/us
- 在linux服务器部署thinkphp5的时候PHP报了Warning: require(): open_basedir restricti
- 修改密码://选择数据库use mysql;//修改密码update user set password=password('新密码
- 赶快记录一下,只是懂皮毛,或许多积累就好了import sysfrom PyQt4 import QtGuiclass MainWindow