一、前端后端(完整模拟)
需要安装的依赖
express、mongoose、axios、nodemon
package.json
{ "name": "code-express", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "dev": "nodemon ./main.js" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "axios": "^1.3.4", "crypto": "^1.0.1", "express": "^4.18.2", "jsonwebtoken": "^9.0.0", "mongoose": "^7.0.0" }, "devDependencies": { "nodemon": "^2.0.20" } }
小程序登录详细步骤(直接在vs code上模拟)
//使用 Express,我们可以方便、快速的创建 Web 网站的服务器或 API 接口的服务器。 const express = require("express"); const mongoose = require("mongoose"); const jwt = require("jsonwebtoken"); const WXBizDataCrypt = require("./utils/WXBizDataCrypt"); const axios = require("axios"); // 数据库链接地址 const dburl = "mongodb://127.0.0.1:27017/hello"; // 描述数据表的格式 const schema = new mongoose.Schema({ username: String, password: String, phone: String, openid: String, // 微信昵称 nickName: String, // 微信头像 avatarUrl: String, // 性别 gender: Number, }); // 用于操作users表的model对象 const userModel = mongoose.model("user", schema); const appid = "wx7ebb4519149403ff"; const appSecret = "13655691c054c1b84484cbc523c78afc"; const app = express(); // 注册中间件,让req.body可以使用 app.use(express.json()); // 登录接口 app.post("/api/auth/login", async (req, res) => { // 1. 获取前端传递过来的 code 、encryptedData、iv const { code, encryptedData, iv } = req.body; // 2. 调用 微信的 jscode2session 接口 https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html const response = await axios.get( "https://api.weixin.qq.com/sns/jscode2session", { params: { appid, // 小程序appid secret: appSecret, // 要注意安全 js_code: code, grant_type: "authorization_code", }, } ); // 3. 取出 openid、session_key const { openid, session_key } = response.data; // const openid = "oKWcP0ZKMAk5KuUFgsLyBRtAFt08"; console.log("openid", openid); // 4. 判断 openid 是否正确获取到了 if (!openid) { return res.send({ status: response.data.errcode, msg: response.data.errmsg, }); } // 5. 根据 openid 去查看数据库中有没有存在 const userInfo = await userModel.findOne({ openid }); // 6. 判断 userInfo 是否存在 if (!userInfo) { // 解密 encryptedData const pc = new WXBizDataCrypt(appid, session_key); const data = pc.decryptData(encryptedData, iv); console.log("解密后的数据", data); // 直接给注册一下,写入数据库 await userModel.create({ username: "", password: "", phone: "", nickName: data.nickName, avatarUrl: data.avatarUrl, gender: data.gender, openid: openid, }); } // 7. 签发token const token = jwt.sign( { openid, }, "hello" ); // 8. 登录成功, 响应token到前端 res.send({ status: 0, msg: "登录成功", data: token, }); }); // 获取用户信息接口 app.get("/api/profile", async (req, res) => { try { // 1. 从请求头中,获取前端传递过来的 token const token = req.get("Authorization"); // 2. 校验 token const payload = jwt.verify(token, "hello"); console.log("payload", payload); // 3. 根据 openid 查询数据库对应的用户信息 // const { password, ...other } = await userModel.findOne({ // openid: payload.openid, // }); const userInfo = await userModel.findOne({ openid: payload.openid, }); // 4. 响应用户数据出去 res.send({ status: 0, msg: "获取成功", data: userInfo, }); } catch (error) { // token 校验失败 res.send(401, { status: -1, msg: "token 无效", }); } }); app.listen(3000, async () => { // 链接数据库 await mongoose.connect(dburl); console.log("数据库链接成功,服务启动成功, 3000"); });