1。新增一张用户表添加一个名为bidu的数据库,并新增一张用户表users,其中id自动递增。请注意字段的数据类型,不要选错。2.配置常量(1).env在服务器根目录新建文件server/.env,配置jwtkey和过期时间、数据库信息、微信小程序相关信息。(注意:不要同步git和.env文件,里面有一些敏感数据)#.env#jwtkey,任意字符串JWT_TOKEN_SECRET=ZM_j3@faF93Mdaie2f#jwt生成的token的过期时间,单位秒JWT_TOKEN_EXPIRATION_TIME=3600#微信小程序appidWECHAT_MINI_APP_ID=wx1f196182a0f906e7#微信小程序secretWECHAT_MINI_APP_SECRET=74d89************47c9f66aaeab#mysql数据库配置MYSQL_HOST=localhostMYSQL_USER=rootMYSQL_PASSWORD=12345678MYSQL_DATABASE=biduMYSQL_PORT=3306MYSQL_CHARSET=utf8mb4_unicode_ci(2)constants.js在后台根目录下,新建server/constants/constants.js文件,用于存放常量。添加微信小程序相关信息/*constants.js*/constWEAPP={APP_ID:process.env.WECHAT_MINI_APP_ID,APP_SECRET:process.env.WECHAT_MINI_APP_SECRET}module.exports={WEAPP}3.微信小程序登录1.创建server/utils/WXBizDataCrypt.js,用于微信解密/*WXBizDataCrypt.js*/varcryptoWx=require('crypto')functionWXBizDataCrypt(appId,sessionKey){//@ts-ignorethis.appId=appId//@ts-ignorethis.sessionKey=sessionKey}WXBizDataCrypt.prototype.decryptData=function(encryptedData,iv){//base64解码varsessionKey=Buffer.from(this.sessionKey,'base64')encryptedData=Buffer.from(encryptedData,'base64'')iv=Buffer.from(iv,'base64')try{//Deciphervardecipher=cryptoWx.createDecipheriv('aes-128-cbc',sessionKey,iv)//设置自动填充为真,删除填充decipher.setAutoPadding(true)vardecoded=decipher.update(encryptedData,'binary','utf8')decoded+=decipher.final('utf8')decoded=JSON.parse(decoded)}catch(err){thrownew错误('IllegalBuffer')}if(decoded.watermark.appid!==this.appId){thrownewError('IllegalBuffer')}returndecoded}module.exports=WXBizDataCrypt2.创建server/utils/jwt.js用于jwt验证和令牌生成/*jwt.js*/constmysql=require('access-db')constjwt=require('jsonwebtoken')constgenToken=(uid)=>{constjwt=require('jsonwebtoken')consttoken=jwt.sign({id:uid},process.env.JWT_TOKEN_SECRET,{expiresIn:parseInt(process.env.JWT_TOKEN_EXPIRATION_TIME||'0')})返回令牌}constauthUse=async(req,res,next)=>{if(!req.headers.authorization){res.send(401,'用户未登录')}constraw=req.headers.authorization.split('').pop()if(raw==='Bearer'){res.send(401,'用户未登录')}const{id}=jwt.verify(raw,process.env.JWT_TOKEN_SECRET)req.user=(awaitmysql.get('users',id).datanext()}module.exports={genToken,authUse}getToken:获取用户id生成的token,expiresIn为过期时间(秒)token,信息写入req.user,方便使用3.创建server/utils/utils.js,工具/*utils.js*///获取当前时间2021-4-716:25:21constgetTime=(type,stamp)=>{letnowTime=stamp?newDate(stamp):newDate()让Y=nowTime.getFullYear()让M=nowTime.getMonth()+1<10?'0'+(nowTime.getMonth()+1):(nowTime.getMonth()+1)让D=nowTime.getDate()<10?'0'+nowTime.getDate():nowTime.getDate()让h=nowTime.getHours()<10?'0'+nowTime.getHours():nowTime.getHours()让m=nowTime.getMinutes()<10?'0'+nowTime.getMinutes():nowTime.getMinutes()让s=nowTime.getSeconds()<10?'0'+nowTime.getSeconds():nowTime.getSeconds()switch(type){case'date':return`${Y}-${M}-${D}`case'date_time':return`${Y}-${M}-${D}${h}:${m}:${s}`case'stamp':returnnowTime.getTime()default:returnnowTime.getTime()}}module.exports={getTime}4.创建server/routes/login.js,登录接口/*login.js*/constexpress=require('express')const{mysql}=require('access-db')constaxios=require('axios')const{WEAPP}=require('../constants/constants')const{getTime}=require('../utils/utils')const{genToken}=require('../utils/jwt')constWXBizDataCrypt=require('../utils/WXBizDataCrypt')constloginRouter=express.Router()//仅获取sessionkeyloginRouter.post('/wechat_session_key',asyncfunction(req,res,next){try{let{code}=req.bodyletsessionRes=awaitaxios({url:'https://api.weixin.qq.com/sns/jscode2session',params:{appid:WEAPP.APP_ID,secret:WEAPP.APP_SECRET,js_code:code,grant_type:'authorization_code',}})res.json({session_key:sessionRes.data.session_key,openid:sessionRes.data.openid})}catch(err){res.status(500).send(err)}})//小程序授权登录loginRouter.post('/wechat',asyncfunction(req,res,next){让{code,userInfo}=req.bodyif(!userInfo){userInfo={nickName:null,avatarUrl:null,}}letsessionRes=awaitaxios({url:'https://api.weixin.qq.com/sns/jscode2session',params:{appid:WEAPP.APP_ID,secret:WEAPP.APP_SECRET,js_code:code,grant_type:'authorization_code',}})//如果小程序绑定了微信开放平台,也会返回unionidletuserRes=awaitmysql.find('users',{p0:['openid','=',sessionRes.data.openid],r:'p0'})letnowTime=getTime('date_time')letresUser={}if(userRes.data.objects.length===0){//不是,新用户(setRes.data.insertId){letgetRes=awaitmysql.get('users',setRes.data.insertId)resUser={...getRes.data,session_key:sessionRes.data.session_key,token:genToken(setRes.数据.insertId)}}}else{//有用户,更新基础信息if(userInfo.avatarUrl){letupdateRes=awaitmysql.update('users',userRes.data.objects[0].id,{nickname:userInfo.nickName,avatar:userInfo.avatarUrl,updated_at:nowTime,})}让getRes=awaitmysql.get('users',userRes.data.objects[0].id)resUser={...getRes.data,session_key:sessionRes.data.session_key,token:genToken(userRes.data.objects[0].id)}}res.json(resUser)})//小程序获取手机号loginRouter.post('/wechat_phone',asyncfunction(req,res,next){let{openid,sessionKey,iv,encryptedData}=req.bodyvarpc=newWXBizDataCrypt(WEAPP.APP_ID,sessionKey)vardata=pc.decryptData(encryptedData,iv)letuserList=(awaitmysql.find('users',{p0:['openid','=',openid],r:'p0'})).data.objectsletnowTime=getTime('date_time')letresUser={}if(userList.length===0){//没有,新用户letid=(awaitmysql.set('users',{phone:data.phoneNumber,created_at:nowTime,updated_at:nowTime,openid:openid,})).data.insertIdif(id){resUser=(awaitmysql.get('users',id)).data}}else{//是用户,更新基本信息if(userList[0].phone!=data.phoneNumber){awaitmysql.update('users',userList[0].id,{phone:data.phoneNumber,updated_at:nowTime,})}resUser=(awaitmysql.get('users',userList[0].id)).data}res.json(resUser)})module.exports=loginRouter并导入server/app.js,/*app.js*/...varindexRouter=require('./routes/index');varusersRouter=require('./routes/users');varloginRouter=require('./routes/login');。..app.use('/',indexRouter);app.use('/users',usersRouter);app.use('/login',loginRouter)5.在mini/app.js中添加接口配置/*app.js*/...globalData:{userInfo:null,},config:{api:'http://localhost:3000',//接口基址文件:'http://localhost:3000',//文件的基地址}...6。修改小程序首页如下