Vue3+Node.js实现微信扫码登录
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
最近刚刚实习,接到了个简单又不简单的需求:前端实现内嵌微信二维码扫码登录,而公司的技术栈用的是Vue3+Pinia+TypeScript
。而我之前也仅仅只接触过微信小程序的微信授权登录,这种第三方web应用的微信授权登录还是头一次遇到。上网查了好多资料+问了GPT好久,最后整理了一下流程和大致的实现,希望对大家有所帮助~!
流程梳理
官方流程概述
- 设置回调 URL:在微信开放平台注册应用时,需要指定一个回调 URL,微信会在用户授权后使用这个 URL。
- 用户授权:用户扫描二维码并在微信中同意授权。
- 微信重定向:微信将用户重定向到设置的回调 URL,同时附带一个授权码。
- 后端接口处理:需要在这个回调 URL 上实现一个接口来接收授权码,并使用它向微信服务器请求access_token和用户信息。
开发者的任务
- 编写回调接口:需要在自己的服务器上编写处理微信重定向的接口。这个接口应该能够处理微信的请求,提取授权码,并使用它来进行后续的操作。
- 安全性和稳定性:确保这个接口能够安全、稳定地处理微信的请求,包括处理可能的错误情况。
- 获取用户信息:利用获取到的access_token和OpenID向微信请求用户信息,并完成应用的登录或其他业务逻辑。
1. 前端(Vue 3)生成登录二维码
- 用户访问登录页面:用户打开 Vue 应用中的登录页面。
- 请求后端获取二维码:在页面上,通过 Vue 应用向 Express 后端发送请求以获取微信登录的二维码。
- 后端处理请求:Express 后端接收到请求后,调用微信的 API 来生成一个微信登录的 URL。
- 生成二维码:后端将微信登录的 URL 转换成二维码数据,并将这个二维码数据发送回 Vue 前端。
- 显示二维码:前端 Vue 应用接收到二维码数据后,展示给用户。
2. 用户扫码并授权
- 用户扫描二维码:用户使用微信扫描页面上显示的二维码。
- 微信处理扫码:微信处理用户的扫码请求,并要求用户确认登录授权。
- 用户授权登录:用户在微信中确认授权,允许应用获取其信息。
3. 后端(Express)处理授权回调
- 微信重定向:一旦用户授权,微信将用户重定向到在微信开放平台注册应用时指定的回调 URL。
- 接收授权码: Express 后端接收到包含授权码(code)的回调请求。
- 请求访问令牌:后端使用这个授权码向微信服务器请求访问令牌和用户的 OpenID。
- 获取用户信息:使用访问令牌,后端可以请求微信 API 获取用户的个人信息。
4. 完成用户登录
- 创建用户会话:根据获取到的用户信息,后端在应用中创建用户会话。
- 发送响应到前端:后端将登录成功的确认和必要的用户信息发送回前端。
- 前端展示用户信息:Vue 应用接收到后端的响应后,更新页面以显示用户已登录,展示用户的信息。
后端API接口相关
接口列举
如果要实现上述的登录流程,Express后端需要编写如下的几个接口:
- 获取登录二维码接口:
- 功能:这个接口用于生成微信登录的 URL,并将其转换为二维码,供前端展示给用户。
- 流程:前端发起请求 -> 后端调用微信 API 获取授权 URL -> 后端生成二维码 -> 后端将二维码数据返回给前端。
- 处理微信回调接口:
- 功能:这个接口用于接收微信在用户授权后的回调。
- 流程:微信重定向用户到这个接口,携带授权码(code) -> 后端使用授权码请求微信服务器以获取访问令牌和用户信息 -> 后端处理并存储用户信息,创建用户会话。
- (可选)用户信息接口:
- 功能:如果用户信息需要在不同的页面或组件中使用,可能需要一个专门的接口来获取当前登录用户的信息。
- 流程:前端发起请求 -> 后端验证用户会话 -> 后端返回当前登录用户的信息。
- (可选)登出接口:
- 功能:用于处理用户登出操作。
- 流程:前端发起登出请求 -> 后端销毁用户会话 -> 后端返回登出成功的确认。
这些是实现微信扫码登录功能最基本的后端接口,根据具体需求可能还需要添加其他接口,比如用于用户注册、密码找回、用户权限管理等。
代码示例
const express = require('express');
const axios = require('axios'); // 用于发起网络请求
const app = express();
const port = 3000;
// 假设已经有了微信的 AppID 和 AppSecret
const WECHAT_APPID = 'AppID';
const WECHAT_SECRET = 'AppSecret';
const WECHAT_REDIRECT_URI = '回调地址'; // 微信授权后的回调地址
// 获取微信登录二维码的接口
app.get('/api/wechat-login-qrcode', async (req, res) => {
try {
// 这里应该是调用微信 API 来获取授权 URL,并转换为二维码
const wechatUrl = `https://open.weixin.qq.com/connect/qrconnect?appid=${WECHAT_APPID}&redirect_uri=${encodeURIComponent(WECHAT_REDIRECT_URI)}&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect`;
// 这里简化处理,直接返回 URL
res.json({ url: wechatUrl });
} catch (error) {
res.status(500).send('服务器错误');
}
});
// 微信回调接口,也就是用户扫码之后在手机上点击同意之后,需要进行重定向的目标URL
app.get('/wechat-callback', async (req, res) => {
const code = req.query.code; // 获取微信回调返回的授权码
try {
// 使用授权码换取 access_token
const tokenResponse = await axios.get(`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${WECHAT_APPID}&secret=${WECHAT_SECRET}&code=${code}&grant_type=authorization_code`);
const accessToken = tokenResponse.data.access_token;
const openId = tokenResponse.data.openid;
// 这里可以根据 accessToken 和 openId 获取用户信息,并进行登录处理
res.send('登录成功');
} catch (error) {
res.status(500).send('授权失败');
}
});
app.listen(port, () => {
console.log(`服务器运行在 http://localhost:${port}`);
});
前端Vue组件二维码展示、接口调用相关
用户点击微信登录时,需要有个组件负责显示登录二维码,并处理用户点击事件来获取二维码。
<template>
<div class="login-window">
<button @click="getWechatQRCode">微信扫码登录</button>
<div v-if="qrCodeUrl">
<img :src="qrCodeUrl" alt="微信登录二维码"/>
</div>
</div>
</template>
<script lang="ts">
import { ref, defineComponent } from 'vue';
import axios from 'axios';
export default defineComponent({
setup() {
const qrCodeUrl = ref<string | null>(null);
const getWechatQRCode = async () => {
try {
// 请求后端接口获取二维码 URL
const response = await axios.get('/api/wechat-login-qrcode');
qrCodeUrl.value = response.data.url; // 这里假设后端返回的数据中有 url 字段
} catch (error) {
console.error('获取二维码失败:', error);
}
};
return {
qrCodeUrl,
getWechatQRCode
};
}
});
</script>
<style scoped>
.login-window {
text-align: center;
padding: 20px;
}
.login-window img {
margin-top: 20px;
max-width: 200px;
border: 1px solid #ddd;
}
</style>
比较迷惑的几个问题
微信重定向到底是重定向到哪里?
当在微信开放平台创建应用时,会被要求提供一个“回调 URL”(也称为重定向 URI)。这个URL应该指向服务器上的一个接口,在上述的应用当中应该指的是/wechat-callback
这个接口。在用户通过微信完成扫码并授权之后,微信会自动将用户的浏览器重定向到这个URL。
这个重定向动作的主要目的是将用户带回应用或网站,并在这个过程中,微信会向提供一些关键信息,主要是“授权码”(code)。
授权码(Code)起到什么作用?
授权码是OAuth 2.0授权流程的一个重要组成部分。它是一种短暂有效的码,用来在用户授权之后安全地在微信和服务器之间传递信息。
- 用户授权后获取授权码:当用户在微信中扫码并同意授权后,微信会生成这个授权码,并将它附加在重定向请求中发送给服务器。
- 服务器使用授权码获取access_token:服务器接收到授权码后,需要立即使用它来向微信请求access_token。这个过程通常是通过在服务器后端发起另一个HTTP请求来完成的。
- 用access_token获取用户信息:一旦服务器获取了access_token,就可以使用它来访问微信的API,获取用户的信息,例如用户的OpenID、昵称、头像等。
实际的登陆操作流程是什么?
- 设置回调URL:在微信开放平台的应用设置中,需要设定一个回调URL,比如
https://yourdomain.com/wechat-callback
。 - 用户扫码授权后的流程:
- 用户在网站上点击“微信登录”,扫描二维码。
- 用户在微信中确认授权。
- 微信将用户的浏览器重定向到提供的回调URL,并在URL中附加授权码,如
https://yourdomain.com/wechat-callback?code=AUTHORIZATION_CODE
。 - 服务器在接收到带有授权码的请求后,使用这个授权码向微信请求access_token。
- 微信响应access_token请求,并发送access_token给服务器。
- 服务器使用这个access_token来获取用户信息,并完成登录或其他业务逻辑。
前端Vue3应用怎么知道用户已经在微信平台授权登录?
1. 轮询(Polling)
在这种方法中,前端 Vue 应用在用户开始扫描二维码后,会定期向后端发送请求以查询登录状态。
流程:
- 用户扫描二维码并在微信中授权。
- 前端开始定期发送请求到后端,询问用户是否已经成功登录。
- 一旦用户在微信中授权,后端处理微信的回调,并更新用户的登录状态。
- 在下一次轮询时,前端得知用户已登录,并进行相应的UI更新或页面跳转。
2. WebSocket
如果应用已经使用了WebSocket,这是一种更现代且实时的方法。WebSocket允许服务器主动向前端推送信息。
流程:
- 用户打开登录页面,前端建立WebSocket连接。
- 用户扫描二维码并在微信中授权。
- 后端在处理微信回调后,通过WebSocket向前端发送用户已登录的消息。
- 前端接收到消息后更新UI或执行其他逻辑。
3. 重定向和前端路由
在这种方法中,微信授权后的重定向不仅仅是到后端接口,而是重定向回整个前端应用的特定路由。
流程:
- 用户扫描二维码并在微信中授权。
- 微信将用户重定向回前端应用的特定路由,比如
https://yourapp.com/login/callback
。 - 当用户到达这个路由时,前端发起请求到后端以确认登录状态。
- 后端确认用户已登录,并向前端返回确认消息。
- 前端根据这个消息更新UI或跳转到用户的主页。
GitHub 加速计划 / vu / vue
207.55 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:3 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 5 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 6 个月前
更多推荐
已为社区贡献1条内容
所有评论(0)