You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.3 KiB
6.3 KiB
微信小程序扫码登录使用指南
概述
本项目已完整实现微信小程序扫码登录功能,支持用户通过小程序扫描网页端二维码快速登录。
功能特性
- ✅ 多种集成方式 - 按钮组件、弹窗组件、专门页面
- ✅ 自动解析二维码 - 支持多种二维码格式(URL、JSON、纯token)
- ✅ 安全可靠 - Token有效期控制,防重复使用
- ✅ 用户体验好 - 实时状态反馈,错误处理完善
- ✅ 微信集成 - 自动获取微信用户信息
后端接口
1. 生成扫码token
POST /api/qr-login/generate
2. 检查登录状态
GET /api/qr-login/status/{token}
3. 确认登录
POST /api/qr-login/confirm
4. 扫码操作(可选)
POST /api/qr-login/scan/{token}
前端使用方式
方式1: 直接扫码按钮
最简单的使用方式,点击按钮直接调用扫码API:
import QRLoginButton from '@/components/QRLoginButton';
// 基础使用
<QRLoginButton />
// 自定义配置
<QRLoginButton
text="扫码登录"
type="primary"
size="large"
onSuccess={(result) => console.log('登录成功', result)}
onError={(error) => console.log('登录失败', error)}
/>
方式2: 弹窗扫码
在当前页面弹出扫码弹窗:
import { useState } from 'react';
import QRScanModal from '@/components/QRScanModal';
const MyComponent = () => {
const [showScan, setShowScan] = useState(false);
return (
<>
<Button onClick={() => setShowScan(true)}>
扫码登录
</Button>
<QRScanModal
visible={showScan}
onClose={() => setShowScan(false)}
onSuccess={(result) => {
console.log('登录成功', result);
setShowScan(false);
}}
onError={(error) => {
console.log('登录失败', error);
}}
/>
</>
);
};
方式3: 跳转到专门页面
跳转到专门的扫码登录页面:
import QRLoginButton from '@/components/QRLoginButton';
// 使用页面模式
<QRLoginButton
text="进入扫码页面"
usePageMode={true}
/>
// 或者自定义跳转
<Button onClick={() => {
Taro.navigateTo({
url: '/pages/qr-login/index'
});
}}>
扫码登录
</Button>
方式4: 使用Hook
直接使用Hook进行更灵活的控制:
import { useQRLogin } from '@/hooks/useQRLogin';
const MyComponent = () => {
const {
startScan,
isLoading,
isSuccess,
isError,
error,
result,
canScan
} = useQRLogin();
return (
<Button
loading={isLoading}
disabled={!canScan()}
onClick={startScan}
>
{isLoading ? '扫码中...' : '扫码登录'}
</Button>
);
};
二维码格式支持
系统支持多种二维码格式:
1. URL格式
https://mp.websoft.top/qr-confirm?qrCodeKey=02278c578d3e4aad87dece6aab2f0296
https://example.com/login?token=abc123
2. JSON格式
{
"token": "02278c578d3e4aad87dece6aab2f0296",
"type": "qr-login"
}
3. 简单格式
qr-login:02278c578d3e4aad87dece6aab2f0296
02278c578d3e4aad87dece6aab2f0296
页面配置
确保在 app.config.ts
中添加了相关页面:
export default {
pages: [
// ... 其他页面
'pages/qr-login/index', // 扫码登录页面
'pages/qr-confirm/index', // 登录确认页面
],
// ...
}
使用示例
完整示例组件
import React, { useState } from 'react';
import { View } from '@tarojs/components';
import { Button } from '@nutui/nutui-react-taro';
import QRLoginButton from '@/components/QRLoginButton';
import QRScanModal from '@/components/QRScanModal';
const LoginPage = () => {
const [showModal, setShowModal] = useState(false);
const handleSuccess = (result) => {
console.log('登录成功:', result);
// 处理登录成功逻辑
};
const handleError = (error) => {
console.error('登录失败:', error);
// 处理登录失败逻辑
};
return (
<View className="p-4">
{/* 方式1: 直接扫码 */}
<QRLoginButton
text="扫码登录"
onSuccess={handleSuccess}
onError={handleError}
/>
{/* 方式2: 弹窗扫码 */}
<Button onClick={() => setShowModal(true)}>
弹窗扫码
</Button>
{/* 方式3: 跳转页面 */}
<QRLoginButton
text="进入扫码页面"
usePageMode={true}
/>
<QRScanModal
visible={showModal}
onClose={() => setShowModal(false)}
onSuccess={handleSuccess}
onError={handleError}
/>
</View>
);
};
注意事项
- 用户登录状态: 使用扫码登录功能前,用户必须已在小程序中登录
- 权限申请: 确保小程序已申请摄像头权限
- 网络环境: 确保网络连接正常,API接口可访问
- 二维码有效期: 二维码有5分钟有效期,过期需重新生成
- 安全性: 只扫描来自官方网站的登录二维码
错误处理
常见错误及解决方案:
请先登录小程序
: 用户未登录,需要先完成小程序登录无效的登录二维码
: 二维码格式不正确或已过期登录确认失败
: 网络问题或服务器错误,可重试扫码失败
: 摄像头权限问题或二维码不清晰
API接口详情
详细的API接口文档请参考:src/api/qr-login/index.ts
组件API
QRLoginButton Props
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
type | string | 'primary' | 按钮类型 |
size | string | 'normal' | 按钮大小 |
text | string | '扫码登录' | 按钮文本 |
showIcon | boolean | true | 是否显示图标 |
usePageMode | boolean | false | 是否使用页面模式 |
onSuccess | function | - | 成功回调 |
onError | function | - | 失败回调 |
QRScanModal Props
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
visible | boolean | false | 是否显示弹窗 |
title | string | '扫描登录二维码' | 弹窗标题 |
description | string | '扫描网页端显示的登录二维码' | 描述文本 |
autoConfirm | boolean | true | 是否自动确认登录 |
onClose | function | - | 关闭回调 |
onSuccess | function | - | 成功回调 |
onError | function | - | 失败回调 |