簡(jiǎn)單了解小程序+node梳理登陸流程
希望通過小程序+node來整體的了解下小程序登陸的流程。如有不對(duì)歡迎在評(píng)論區(qū)指出
1. client: wx.login()
wx.login({
success: ([code]) => {
// 發(fā)送 code 到后臺(tái)換取 openId, sessionKey, unionId
}
})
2. service: request()
服務(wù)端請(qǐng)求,需要的參數(shù)(js_code:client傳的code;appid:小程序唯一標(biāo)識(shí)申請(qǐng)賬號(hào)時(shí)拿到;secret:小程序密鑰申請(qǐng)賬號(hào)時(shí)拿到;grant_type:默認(rèn)值為 authorization_code)
// 請(qǐng)求方法
const request = require('request')
const url = https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
module.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:返回登陸態(tài)
const { encode } = require('./lib/crypto')
const jsonMine = 'application/json'
const now = Date.now()
function handle(ctx, data, code = 0, message = 'success') {
ctx.type = jsonMine
ctx.body = {
code,
data,
message
}
}
router.get('/login', async (ctx, next) => {
const { code } = ctx.request.query
const session = await login(code)
if (session) {
const { session_key, openid } = session
// 查找數(shù)據(jù)庫(kù)中是否已經(jīng)存有openid,如果 hasOpenid 為null說明是新用戶
const hasOpenid = await User.findByPk(openid)
if(!hasOpenid){
// 數(shù)據(jù)庫(kù)存儲(chǔ)openid,時(shí)間戳
User.create({openid,timespan:Date.now()})
}
handle(ctx, { token: encode(openid) })
} else {
throw new Error('登陸失敗')
}
})
5.client:存儲(chǔ)登陸態(tài)在storage
import { LOGIN_TOKEN } from '../../utils/localStorage'
// 拿到token存儲(chǔ)到客戶端
wx.setStorageSync(LOGIN_TOKEN, token)
我在發(fā)起請(qǐng)求時(shí)將登陸態(tài)放在請(qǐng)求頭中,相應(yīng)的服務(wù)端可以從請(qǐng)求頭中獲取
header: {
'x-session': wx.getStorageSync(LOGIN_TOKEN)
},
6.service:校驗(yàn)登陸態(tài)
module.exports = async function(ctx, next) {
const sessionKey = ctx.get('x-session')
const { id, timespan } = decode(sessionKey)
// 查找數(shù)據(jù)庫(kù)中是否存在該 openid,返回是一個(gè)數(shù)組,如果不存在則返回[]
const targetList = await getOpenid(id)
if (targetList.length > 0) {
// 如果超過設(shè)定的過期時(shí)間,標(biāo)記isExpired字段為登陸過期
const oneHour = 1000 * 60 * 60 * 24
if (Date.now() - timespan > oneHour) {
ctx.state.isExpired = true
// 跟前臺(tái)約定,如果code=2說明登陸過期跳登陸頁(yè)面
handle(ctx, '', 2, '登陸過期')
} else {
handle(ctx, '', 0, '登陸成功')
}
} else {
// 通過ctx.throw可以直接拋出錯(cuò)誤
ctx.throw(401, '登陸失敗')
}
整體流程圖

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,
相關(guān)文章
詳解nodejs解壓版安裝和配置(帶有搭建前端項(xiàng)目腳手架)
這篇文章主要介紹了詳解nodejs解壓版安裝和配置(帶有搭建前端項(xiàng)目腳手架) ,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12
從零開始學(xué)習(xí)Node.js系列教程六:EventEmitter發(fā)送和接收事件的方法示例
這篇文章主要介紹了Node.js EventEmitter發(fā)送和接收事件的方法,結(jié)合實(shí)例形式分析了EventEmitter發(fā)送和接收事件的原理、實(shí)現(xiàn)方法與相關(guān)操作技巧,需要的朋友可以參考下2017-04-04
Node升級(jí)后vue項(xiàng)目node-sass報(bào)錯(cuò)問題及解決
這篇文章主要介紹了Node升級(jí)后vue項(xiàng)目node-sass報(bào)錯(cuò)問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
node.js [superAgent] 請(qǐng)求使用示例
這篇文章主要介紹了node.js [superAgent] 請(qǐng)求使用示例,分別給大家匯總了post請(qǐng)求、get請(qǐng)求、delete請(qǐng)求和put請(qǐng)求的示例,推薦給大家,希望大家能夠喜歡。2015-03-03
使用pm2自動(dòng)化部署node項(xiàng)目的方法步驟
這篇文章主要介紹了使用pm2自動(dòng)化部署node項(xiàng)目的方法步驟,pm2是一個(gè)進(jìn)程管理工具,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-01-01

