用户登录是小程序的一个常用功能,当用户在浏览文章想要收藏时,在线上购买商品时,只有用户登录自己账号以后,才可以进一步使用这些功能。此文论述了小程序用户登录功能的设计流程
一、设计思路
1、界面
小程序界面效果如下所示:
点击默认头像可以选择用微信头像作为小程序头像;点击“请输入昵称”输入框可以手动填写昵称或使用微信昵称;点击“获取用户积分”按钮时,如果已登录,则显示积分,否则显示“未登录或用户不存在”。
2、知识
(1)登录流程时序
角色:
小程序:用户使用的客户端,即微信小程序。
开发者服务器:小程序的后台服务器,为小程序提供服务。
微信接口服务: 微信为开发者服务器提供的接口。
时序
1.微信小程序获取临时登录凭证code
使用wx.login()方法获取临时登录凭证code,自动生成,有效期5分钟,被微信接口服务验证一次就会失效。
2.微信小程序发送code至开发者服务器
使用wx.request()方法将code发送给开发者服务器
3.开发者服务器通过微信接口服务校验登录凭证
开发者服务器将AppID(微信小程序的唯一标识)、appsercret(微信小程序密钥)和code发送给微信接口服务进行登录凭证校验,校验成功,微信接口服务会返回session_key、openid、unionid等信息。session_key是用户的会话密钥,用于对用户数据进行加密签名。opend是用户唯一标识,同一用户在不同的小程序中的openid是不同的。unionid是用户在微信开发者平台账号下的唯一标识。
4.开发者服务器自定义登录状态
自定义登录状态是指由开发者自由决定如何维持用户的登录状态,常用的做法是,在开发者服务器中为登录成功用户生成一个token,然后通过验证token的有效性来识别用户的登录状态。此文的用户登录功能设计,登录成功时需要保存openid和session_key,然后生成一个 token响应给微信小程序,微信小程序下次请求时,需要携带token,当开发者服务器收到请求后,使用请求的token查询对应用户的openid和session_key,查询成功则已登录,否则未登录。
(2)登录API
微信小程序提供登录API:
wx.login():获取用户登录凭证code,并发送至开发者服务器。
常用选项:
timeout: 超时时间,单位为毫秒。
success: 调用成功的回调函数。
fail: 调用失败的回调函数
complete: 调用结束时的回调函数。
(3)数据缓存API
常见数据缓存
微信小程序利用数据缓存API可从实现数据缓存,从而加快数据的速度,常见的数据缓存方法如下所示:
方式 | 方法 | 说明 |
---|---|---|
异步 | wx.setStorage() | 将数据存储在本地指定的key中 |
wx.getStorage() | 从本地缓存中获取指定key的内容 | |
wx.getStorageInfo() | 获取当前Storage相关信息 | |
wx.removeStoreage() | 从本地缓存中移除指定key | |
同步 | wx.setStorageSync() | 同名的同步版本 |
wx.getStorageSync() | 同名的同步版本 | |
wx.getStorageInfo() | 同名的同步版本 | |
wx.removeStorageSync() | 风名的同步版本 |
注意: 单key允许存储的最大数据长度为1MB,数据存储上限为10MB
(4) 头像昵称填写
头像选择: 将button组件open-type属性值设置为chooseAvatar,绑定bindchooseAvatar事件处理函数获取头像信息。
昵称填写:将input的type的属性值设置为nickname,用户可以选择微信昵称或填写昵称。
(5)App()函数
微信小程序中,若要在小程序启动、显示、隐藏时执行操作,或在各个页面共享数据时,可通过App()函数实现。
App()函数用于注册微信小程序,此函数必须在app.js文件中调用,且只能调用一次。其参数为一对象,通过此对象可以指定应用生命周期回调函数和保存共享数据。应用生命周期函数是指小程序"启动-运行-销毁"期间依次调用的函数。应用周期回调函数如下所示:
函数名 | 说明 |
onLaunch() | 监听小程序初始化,小程序初始化时触发,全局只触发一次 |
onShow() | 监听小程序启动或切前台,小程序启动或从后台切前台时触发 |
onError() | 错误监听函数,微信小程序脚本错误或者API调用报错时触发 |
onHide() | 监听小程序切后台,小程序从前台进入后台时触发 |
onPageNotFound() | 页面不存在监听函数,小程序要打开的页面不存在时触发 |
3、思路
此程序分为小程序和服务器设计,服务器采用nodejs+express框架,其中开发者服务器主要完成向微信服务接口提出验证申请并接收返回的session_key和openid,并生成自定义登录状态token。小程序主要完成界面设计、并完成头像选择或填写,昵称填写等功能。
二、服务器设计
此开发者采用nodejs+express框架,监听端口为3000,主要提供三个服务,分别是 /login ,/checklogin, /credit等服务,login为用户登录服务,checklogin为校验用户登录,credit为查询用户信用分。服务器代码如下所示:
const express = require('express')
const bodyParser = require('body-parser')
const request = require('request')
const app = express()
app.use(bodyParser.json())// 注意:小程序端的appid必须使用真实账号,如果使用测试账号,会出现login code错误
const wx = {appid: '',secret: ''
}var db = {session: {},user: {}
}app.post('/login', (req, res) => {console.log('login code: ' + req.body.code)var url = 'https://api.weixin.qq.com/sns/jscode2session?appid=' + wx.appid + '&secret=' + wx.secret + '&js_code=' + req.body.code + '&grant_type=authorization_code'request(url, (err, response, body) => {console.log('session: ' + body)var session = JSON.parse(body)if (session.openid) {var token = 'token_' + new Date().getTime()db.session[token] = sessionif (!db.user[session.openid]) {db.user[session.openid] = {credit: 100}}}res.json({token: token})})
})app.get('/checklogin', (req, res) => {var session = db.session[req.query.token]console.log('checklogin: ', session)// 将用户是否已经登录的布尔值返回给客户端res.json({is_login: session !== undefined})
})app.get('/credit', (req, res) => {var session = db.session[req.query.token]if (session && db.user[session.openid]) {res.json({credit: db.user[session.openid].credit})} else {res.json({err: '用户不存在,或未登录。'})}
})app.listen(3000, () => {console.log('server running at http://127.0.0.1:3000')
})
部署方法如下:
1. 准备工作
安装Node.js
启动命令行,切换工作目录到当前目录。
2. 打开index.js,找到如下代码,填写你的 appid 和 secret。
const wx = {
appid: '',
secret: ''
}
3. 执行如下命令,启动服务器
node index.js
三、小程序设计
1、界面设计
此程序界面设计比较简单,从上至下分别是头像选择按钮,昵称填写框、获取用户积分按钮等,具体代码如下所示:
<!--index.wxml-->
<button class="avatar-wrapper" open-type="chooseAvatar" bindchooseavatar="onChooseAvatar"><image class="avatar" src="{{ avatarUrl }}"></image>
</button>
<input type="nickname" class="nickname" placeholder="请输入昵称" /><button bindtap="credit">获取用户的积分</button>
wxss代码如下所示:
/**index.wxss**/
.avatar-wrapper {width: 160rpx;height: 160rpx;padding: 0;background: none;
}.avatar {width: 160rpx;height: 160rpx;border-radius: 20rpx;
}.nickname {width: 80%;height: 100rpx;margin: 20px auto;border: 1px solid #000000;text-align: center;
}
2、处理逻辑
(1)用户登录
在app.js文件的App({})中编写代码,实现小程序启动时自动执行登录操作,具体步骤为:
(1)定义页面所需的数据。
(2)启动时调用login()方法。
详细代码如下:
// app.js
App({onLaunch: function () {this.checkLogin(res => {console.log('is_login: ', res.is_login)if (!res.is_login) {this.login()}})},login: function () {wx.login({success: res => {console.log('login code: ' + res.code)wx.request({url: 'http://127.0.0.1:3000/login',method: 'post',data: {code: res.code},success: res => {console.log('token: ' + res.data.token)// 将token保存为公共 数据,用于在所有页面中共享tokenthis.globalData.token = res.data.token// 将token保存到数据缓存wx.setStorage({key: 'token',data: res.data.token})}})}})},checkLogin: function (callback) {var token = this.globalData.tokenif (!token) {// 从数据缓存中获取tokentoken = wx.getStorageSync('token')if (token) {this.globalData.token = token} else {callback({ is_login: false })return}}wx.request({url: 'http://127.0.0.1:3000/checklogin',data: { token: token },success: res => {callback({ is_login: res.data.is_login })}})}, // 定义页面所需的数据 globalData: {token: null // 保存token}
})
2、校验用户登录
此程序中,登录成功后,会将服务器返回的token保存在globalData和数据缓存中,再次启动小程序时,先判断token是否存在,如不存在,则执行登录操作,如存在,先验证token是否有效,如无效则执行登录,否则在控制台输出“is_login: true”,详细代码如上所示。
3。获取用户积分
在小程序中,为“获取用户积分”按钮,绑定tap事件(i文件index.wxml中),代码为:
<button bindtap="credit">获取用户的积分</button>
事件处理函数为credit()在index.js文件中,在函数中,先判断用户是否登录,如未登录则显示"用户不存在,或未登录",如已登录,则调用wx.request()方法向服务器申请查询积分,如请求成功返回积分。详细代码如下所示。
4、获取用户头像和昵称
在界面中定义了button组件和image组件,用于选择头像或展示头像,定义input组件输入昵称。在index.js中定义onChooseAvatar()函数,获取头像信息的临时路径,
index.js 代码如下:
// index.js
const app = getApp()
const defaultAvatar = '/images/avatar.png'
Page({data: {avatarUrl: defaultAvatar,},credit: function () {wx.request({url: 'http://127.0.0.1:3000/credit',data: {token: app.globalData.token},success: res => {console.log(res.data)}})},onChooseAvatar: function (e) {console.log(e)const { avatarUrl } = e.detailthis.setData({ avatarUrl })},
})
此文论述微信小程序的用户登录功能实现方法和步骤,分别思路、知识、界面、逻辑四个方面进行论述,具体方法是在开发者服务器中完成登录请求、登录用户校验、在小程序的app.js 使用onLaunch()函数完成小程序启动时自动登录,在index.js中编写相应的事件处理函数完成头像选择、昵称填写、查询积分等功能。