简单了解小程序+node梳理登陆流程

时间:2021-05-18

希望通过小程序+node来整体的了解下小程序登陆的流程。如有不对欢迎在评论区指出

1. client: wx.login()

wx.login({success: ([code]) => {// 发送 code 到后台换取 openId, sessionKey, unionId}})

2. service: request()

服务端请求,需要的参数(js_code:client传的code;appid:小程序唯一标识申请账号时拿到;secret:小程序密钥申请账号时拿到;grant_type:默认值为 authorization_code)

// 请求方法const request = require('request')const url = https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_codemodule.exports = {async getSession(code) {return new Promise((resolve, reject) => {request(url,{method: 'GET',json: true},(error, res, body) => {if (error) {reject(error)} else {if (body.errcode) {reject(new Error(body.errmsg))} else {resolve(body)}}})})}}

3.service:加密解密处理

const crypto = require('crypto')const secret = '2019_06'const algorithm = 'aes-256-cbc'function encode(id) {const encoder = crypto.createCipher(algorithm, secret)const str = [id, Date.now(), '2019'].join('|')let encrypted = encoder.update(str, 'utf8', 'hex')encrypted += encoder.final('hex')return encrypted}function decode(str) {const decoder = crypto.createDecipher(algorithm, secret)let decoded = decoder.update(str, 'hex', 'utf8')decoded += decoder.final('utf8')const arr = decoded.split('|')return {id: arr[0],timespan: parseInt(arr[1])}}module.exports = {encode,decode}

4.service:返回登陆态

const { encode } = require('./lib/crypto')const jsonMine = 'application/json'const now = Date.now()function handle(ctx, data, code = 0, message = 'success') {ctx.type = jsonMinectx.body = {code,data,message}}router.get('/login', async (ctx, next) => {const { code } = ctx.request.queryconst session = await login(code)if (session) {const { session_key, openid } = session// 查找数据库中是否已经存有openid,如果 hasOpenid 为null说明是新用户const hasOpenid = await User.findByPk(openid)if(!hasOpenid){// 数据库存储openid,时间戳User.create({openid,timespan:Date.now()})}handle(ctx, { token: encode(openid) })} else {throw new Error('登陆失败')}})

5.client:存储登陆态在storage

import { LOGIN_TOKEN } from '../../utils/localStorage'// 拿到token存储到客户端wx.setStorageSync(LOGIN_TOKEN, token)

我在发起请求时将登陆态放在请求头中,相应的服务端可以从请求头中获取

header: {'x-session': wx.getStorageSync(LOGIN_TOKEN)},

6.service:校验登陆态

module.exports = async function(ctx, next) {const sessionKey = ctx.get('x-session')const { id, timespan } = decode(sessionKey)// 查找数据库中是否存在该 openid,返回是一个数组,如果不存在则返回[]const targetList = await getOpenid(id)if (targetList.length > 0) {// 如果超过设定的过期时间,标记isExpired字段为登陆过期const oneHour = 1000 * 60 * 60 * 24if (Date.now() - timespan > oneHour) {ctx.state.isExpired = true// 跟前台约定,如果code=2说明登陆过期跳登陆页面handle(ctx, '', 2, '登陆过期')} else {handle(ctx, '', 0, '登陆成功')}} else {// 通过ctx.throw可以直接抛出错误ctx.throw(401, '登陆失败')}

整体流程图

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章