q***@gmail.com
q***@gmail.com
  • 发布:2026-02-18 22:48
  • 更新:2026-02-18 22:49
  • 阅读:133

uniapp多端登录:----=---1.扫码登录, 2.手机端登录,验证码[假号码模拟]登录 3.手机号与微信支付宝账号绑定等平台端的登录.,用同一个后端数据库,

分类:uni-app

我现在想去uniapp中级公司面试了,程序已经做完了,叫"飞度在线网络购物平台"
有前后端,功能已经做完了,
现在就差 登录端的功能了
包括:
1.扫码登录,
2.手机端登录,验证码[假号码模拟]登录
3.手机号与微信支付宝账号绑定等平台端的登录.

请问,这个登录问题如何用uniapp和nodejs(express框架)+mysql实现,
因为本人面试的是中级的uniapp工程师,后端nodejs本人也会,我也会设计mysql数据库,
登录用的是cookie,没有使用jwt(jwt也会,但不想做太多改动,我想会jwt应该也就会cookie了)
这个uniapp的多端登录,有人实现过吗?能讲下思路或者具体的代码实现吗,越详细越好
我有用付费的AI工具,但是他们都只是帮我侧面完成了单个的功能,我无法把他们综合到一个项目中去.

社区有谁做过,能尽量详细点帮我实现这个多端登录的功能吗?

2026-02-18 22:48 负责人:无 分享
已邀请:
Ask小助手

Ask小助手 - Ask社区AI助手

欢迎到专业群( uni-app 官方技术交流群 1 ) 咨询,群中有相关专业的管理员和群友。

下面给出一份“飞度在线网络购物平台”多端登录的完整思路 + 可落地的 uni-app(前端)+ Node.js(express) + MySQL(后端)代码示例。
所有登录方式共用同一张用户表、同一套 cookie-session 机制,方便你直接合并到现有工程。


一、数据库设计(MySQL)

-- 用户主表  
create table fd_user(  
  id            bigint primary key auto_increment,  
  uuid          char(36) unique,               -- 全局唯一用户 id  
  phone         char(11) unique,               -- 手机号(可为空)  
  wx_openid     varchar(64) unique,            -- 微信 openid  
  ali_openid    varchar(64) unique,            -- 支付宝 openid  
  pwd_hash      char(60),                      -- 密码(bcrypt 60 位)  
  nickname      varchar(32),  
  avatar        varchar(255),  
  create_time   datetime default current_timestamp  
);  

-- 验证码表(仅演示用,生产可放 redis)  
create table fd_sms_code(  
  phone      char(11) primary key,  
  code       char(6),  
  expire_at  datetime  
);  

-- pc 扫码登录临时表  
create table fd_qrcode(  
  scene      char(32) primary key,   -- 场景码  
  uid        bigint,                 -- 已绑定的用户 id(扫码后回填)  
  create_at  datetime default current_timestamp,  
  expire_at  datetime  
);

二、后端 Node.js(express) 核心代码

  1. 通用中间件
// app.js  
const express = require('express');  
const session = require('express-session');  
const cors = require('cors');  
const bodyParser = require('body-parser');  
const cookieParser = require('cookie-parser');  
const app = express();  

app.use(cors({ origin: true, credentials: true }));  
app.use(bodyParser.json());  
app.use(cookieParser());  
app.use(session({  
  secret: 'feidu2024',  
  resave: false,  
  saveUninitialized: false,  
  cookie: { httpOnly: true, maxAge: 1000 * 60 * 60 * 24 }  
}));  

// 路由  
app.use('/api', require('./routes/login'));  
app.listen(3000);
  1. 登录路由 routes/login.js
const router = require('express').Router();  
const bcrypt = require('bcrypt');  
const mysql = require('mysql2/promise');  
const db = mysql.createPool({ host:'localhost', user:'root', password:'123456', database:'feidu' });  

// 工具:下发 cookie  
function setLoginCookie(req, res, uid) {  
  req.session.uid = uid;  
  res.cookie('uid', uid, { maxAge: 1000 * 60 * 60 * 24, httpOnly: false });  
}  

/* 1. 手机号 + 验证码登录 */  
router.post('/login/sms', async (req, res) => {  
  const { phone, code } = req.body;  
  const [rows] = await db.query('select * from fd_sms_code where phone=? and code=? and expire_at>now()', [phone, code]);  
  if (!rows.length) return res.json({ code: 400, msg: '验证码错误/过期' });  

  await db.query('delete from fd_sms_code where phone=?', [phone]); // 用完即删  
  let [user] = await db.query('select id from fd_user where phone=?', [phone]);  
  if (!user.length) {  
    const uuid = require('uuid').v4();  
    const [r] = await db.query('insert into fd_user(uuid,phone) values(?,?)', [uuid, phone]);  
    user = [{ id: r.insertId }];  
  }  
  setLoginCookie(req, res, user[0].id);  
  res.json({ code: 0, msg: '登录成功' });  
});  

/* 2. 微信 / 支付宝 OAuth 登录 */  
router.post('/login/oauth', async (req, res) => {  
  const { provider, code } = req.body; // provider = weixin | alipay  
  // 下面演示微信,支付宝同理  
  const axios = require('axios');  
  const appid = '你的微信appid', secret = '你的微信secret';  
  const { data } = await axios.get(`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appid}&secret=${secret}&code=${code}&grant_type=authorization_code`);  
  const openid = data.openid;  
  const [user] = await db.query(`select id from fd_user where wx_openid=?`, [openid]);  
  let uid;  
  if (user.length) {  
    uid = user[0].id;  
  } else {  
    const uuid = require('uuid').v4();  
    const [r] = await db.query('insert into fd_user(uuid,wx_openid) values(?,?)', [uuid, openid]);  
    uid = r.insertId;  
  }  
  setLoginCookie(req, res, uid);  
  res.json({ code: 0, msg: '登录成功' });  
});  

/* 3. PC 扫码登录 */  
// 3.1 生成二维码  
router.get('/qrcode/create', async (req, res) => {  
  const scene = require('crypto').randomBytes(16).toString('hex');  
  await db.query('insert into fd_qrcode(scene,expire_at) values(?,date_add(now(),interval 5 minute))', [scene]);  
  res.json({ code: 0, scene });  
});  

// 3.2 轮询接口  
router.get('/qrcode/check/:scene', async (req, res) => {  
  const [rows] = await db.query('select uid from fd_qrcode where scene=? and expire_at>now()', [req.params.scene]);  
  if (!rows.length) return res.json({ code: 404, msg: '二维码过期' });  
  if (!rows[0].uid) return res.json({ code: 201, msg: '待扫描' });  
  setLoginCookie(req, res, rows[0].uid);  
  res.json({ code: 0, msg: '登录成功' });  
});  

// 3.3 手机端确认扫码  
router.post('/qrcode/confirm', async (req, res) => {  
  const { scene } = req.body;  
  const uid = req.session.uid; // 手机端已登录  
  if (!uid) return res.json({ code: 401, msg: '手机端未登录' });  
  await db.query('update fd_qrcode set uid=? where scene=?', [uid, scene]);  
  res.json({ code: 0 });  
});  

/* 4. 绑定第三方账号(手机号已登录后) */  
router.post('/bind', async (req, res) => {  
  const uid = req.session.uid;  
  if (!uid) return res.json({ code: 401 });  
  const { provider, openid } = req.body;  
  const field = provider === 'weixin' ? 'wx_openid' : 'ali_openid';  
  await db.query(`update fd_user set ${field}=? where id=?`, [openid, uid]);  
  res.json({ code: 0 });  
});  

module.exports = router;

三、uni-app 前端示例

  1. 公共请求封装 utils/request.js
const baseURL = 'http://localhost:3000/api';  
export default function request(url, data = {}, method = 'POST') {  
  return new Promise((resolve, reject) => {  
    uni.request({  
      url: baseURL + url,  
      method,  
      data,  
      withCredentials: true, // 关键:让 cookie 随请求一起发送  
      success: (res) => resolve(res.data),  
      fail: reject  
    });  
  });  
}
  1. 手机号验证码登录页 pages/login/sms.vue
<template>  
  <view>  
    <input v-model="phone" placeholder="手机号" />  
    <input v-model="code" placeholder="验证码" />  
    <button @tap="sendCode">发送验证码</button>  
    <button @tap="loginSms">登录</button>  
  </view>  
</template>  
<script>  
import req from '@/utils/request';  
export default {  
  data() { return { phone: '', code: '' } },  
  methods: {  
    async sendCode() {  
      // 这里只是演示,真实场景需调短信网关  
      await req('/sms/send', { phone: this.phone });  
      uni.showToast({ title: '已发送' });  
    },  
    async loginSms() {  
      await req('/login/sms', { phone: this.phone, code: this.code });  
      uni.switchTab({ url: '/pages/index/index' });  
    }  
  }  
};  
</script>
  1. 微信 / 支付宝登录 pages/login/oauth.vue
<template>  
  <view>  
    <button @tap="login('weixin')">微信登录</button>  
    <button @tap="login('alipay')">支付宝登录</button>  
  </view>  
</template>  
<script>  
import req from '@/utils/request';  
export default {  
  methods: {  
    login(provider) {  
      uni.login({  
        provider,  
        success: async (res) => {  
          await req('/login/oauth', { provider, code: res.code });  
          uni.switchTab({ url: '/pages/index/index' });  
        }  
      });  
    }  
  }  
};  
</script>
  1. PC 扫码登录(H5 端) pages/login/qrcode.vue
内容为 AI 生成,仅供参考

要回复问题请先登录注册