go语言实现微信扫码登录,涵盖微信登录超详细流程并附带时序图

微信扫码登录

  • 1. 简述:此文章目的主要是web网站进行微信扫码登录
  • 2. 微信登录过程时序图
  • 3. 全部微信登录组成元素
    • 3.1. 微信扫码登录后端总共只需要两个接口,
    • 3.2. 微信登录的各个对象:
    • 3.3. 微信登录的主要参数:
  • 4. 流程解释:
  • 5. 容易产生的误解

1. 简述:此文章目的主要是web网站进行微信扫码登录

  1. 目的:希望用户通过微信扫码确认用户身份为其返回token
  2. 准备工作:网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。 在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者账号,并拥有一个已审核通过的网站应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程。(没有审核过的没法使用完整版微信登录)
    流程图:

2. 微信登录过程时序图

微信登录过程时序图

3. 全部微信登录组成元素

3.1. 微信扫码登录后端总共只需要两个接口,

  1. 接口一:即返回微信url的接口,参数有appId和redirectUrl,其中redirectUrl本身也是一个url,且这个url也携带了一些参数
    代码一:

func Redirect(c *gin.Context) {
	path := c.Query("Url")
	state := Pcaptcha.RandString(5)                                           
	redirectURL := url.QueryEscape("http://" + path + "/api/v1/wechat/callback") //userinfo,
	wechatLoginURL := fmt.Sprintf("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&state=%s&scope=snsapi_userinfo#wechat_redirect", "你的appid", redirectURL, state)
	wechatLoginURL, _ = url.QueryUnescape(wechatLoginURL)
	// 生成二维码
	qrCode, err := qrcode.Encode(wechatLoginURL, qrcode.Medium, 256)
	if err != nil {
		// 错误处理
		c.String(http.StatusInternalServerError, "Error generating QR code")
		return
	}
	// 将二维码图片作为响应返回给用户
	c.Header("Content-Type", "image/png")
	c.Writer.Write(qrCode)
}

  1. 接口二:通过前端传来的code向微信服务器发送获取用户信息的请求,然后返回token
    代码二:

func Callback(c *gin.Context) {
	// 获取微信返回的授权码
	code := c.Query("code")
	// 向微信服务器发送请求,获取access_token和openid
	tokenResp, err := http.Get(fmt.Sprintf("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code", "appid", "appsecret", code))
	if err != nil {
		fmt.Println(err)
		resp := &ResponseData{
			Data:    nil,
			Message: "error,获取token失败",
			Code:    CodeServerBusy,
		}
		c.JSON(http.StatusBadRequest, resp)
		return
	}
	// 解析响应中的access_token和openid
	var tokenData struct {
		AccessToken  string `json:"access_token"`
		ExpiresIn    int    `json:"expires_in"`
		RefreshToken string `json:"refresh_token"`
		OpenID       string `json:"openid"`
		Scope        string `json:"scope"`
	}
	if err1 := json.NewDecoder(tokenResp.Body).Decode(&tokenData); err1 != nil {
		resp := &ResponseData{
			Data:    nil,
			Message: "error,获取token失败",
			Code:    CodeServerBusy,
		}
		c.JSON(http.StatusBadRequest, resp)
		return
	}
	userInfoURL := fmt.Sprintf("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s", tokenData.AccessToken, tokenData.OpenID)
	userInfoResp, err := http.Get(userInfoURL)
	if err != nil {
		// 错误处理
		zap.L().Error("获取失败")
		return
	}
	defer userInfoResp.Body.Close()

	//------------------------------------
	var userData struct {
		OpenID   string `json:"openid"`
		Nickname string `json:"nickname"`
	}
	if err1 := json.NewDecoder(userInfoResp.Body).Decode(&userData); err1 != nil {
		// 错误处理
		zap.L().Error("获取用户信息失败")
		return
	}
	//用户的名字
	var user1 model.User
	nickname := userData.Nickname
	if err2 := mysql.DB.Where("user_name=?", nickname).First(&user1).Error; err2 != nil {
		if errors.Is(err2, gorm.ErrRecordNotFound) {
			user1.UserName = nickname
			user1.UserID, _ = snowflake.GetID()
			user1.Identity = "普通用户"
		} else {
			zap.L().Error("验证登录信息过程中出错")
			ResponseError(c, CodeServerBusy)
			return
		}
	}
	//添加jwt验证
	atoken, rtoken, err3 := jwt.Token.GetToken(uint64(user1.UserID), user1.UserName, user1.Identity)
	if err3 != nil {
		zap.L().Error("生成JWT令牌失败")
		return
	}
	c.Header("Authorization", atoken)
	//发送成功响应
	ResponseSuccess(c, &model.LoginData{
		AccessToken:  atoken,
		RefreshToken: rtoken,
	})
	zap.L().Info("登录成功")
	return
}

3.2. 微信登录的各个对象:

用户,前端(浏览器),前端服务器,后端服务器,微信服务器,手机

3.3. 微信登录的主要参数:

  1. appId:微信服务器确定是哪一个网站的凭证,向微信开发者平台申请获得
  2. redirectUrl:用户扫码完成后微信二维码页面根据这个url发送请求,如果这个redirectUrl是指向后端服务器的,后端根据code确认用户信息返回token,如果这个redirectUrl是指向前端服务器的,浏览器会向前端服务器发送请求,前端可以返回页面,在这个页面进行其他操作再向后端服务器发送携带code的获取token请求,后端再确认信息,返回token,
  3. code:用户扫码授权的凭证

4. 流程解释:

  1. 用户点击前端页面微信登录,前端发送获取微信url的请求,前端通过微信url向微信服务器发送获取微信二维码页面,并进行页面跳转,跳转到微信二维码页面供用户手机扫码,且微信二维码会一直轮询获取用户是否扫码,如果一定时间后用户没有扫码则二维码过期,停止轮询,页面可以点击刷新二维码,
  2. 用户扫码后并点击授权,微信二维码页面将轮询获得微信服务器中用户已授权的信息并获得code(code只能使用一次,且会过期)。微信二维码页面再根据code和接口一中的redirectUrl向后端服务器发送获取token的请求,后端根据code向微信服务器发送获取用户信息的http请求,获得的用户信息和数据库进行对比,如果一直则根据用户信息生成token并返回给前端,前端跳转页面实现微信登录

5. 容易产生的误解

  1. 前端向微信服务器发送获取微信二维码的请求之后跳转微信二维码页面,之后的扫码、轮询、是否授权、以及调用redirectUrl的链接都是微信页面在做的,不用我们去管他是如何实现的
  2. 微信二维码携带code发送的获取token请求,是在用户浏览器上发送的,我们返回token也是返回给了浏览器,浏览器会存储token的,但是如果要进行其他操作(业务方面的,如是否微信绑定,手机号绑定等)最好先跳转到自己的页面(redirect指向前端服务器,并获得前端的页面)。

最后有完整的微信登录项目代码包,可私信发送

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/676473.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于Android Studio 垃圾分类助手App--原创

一、高质量源码(非开源,白嫖低价勿扰) 关注公众号:《编程乐学》 后台回复:24060301 二、项目演示视频 基于Android Studio 垃圾分类助手App--原创 三、开发环境 四、设计与实现 1.启动页 1.设置延迟三秒后执行 runna…

HDL-A/1-110VAC-2电流继电器 JOSEF约瑟 导轨安装

一. 应用 HDL系列电流继电器是静态型,不带方向性的、瞬动、交流电流继电器。可用于电力系统输电线,电机过负荷和短路保护中,作为启动元件。 继电器对短路电流中的直流分量不敏感,因此可用于要求哲态超小的线路中,改继电器由集成…

SpringBoot启动流程分析之设置系统属性spring.beaninfo.ignore、自定义banner图(五)

SpringBoot启动流程分析之设置系统属性spring.beaninfo.ignore、自定义banner图(五) 参考 目录 文章目录 SpringBoot启动流程分析之设置系统属性spring.beaninfo.ignore、自定义banner图(五)1、设置sping.beaninfo.ignore属性2、…

一文带你搞懂单模光纤和多模光纤的区别

单模光纤和多模光纤的区别及常见疑问解答 随着网络技术的飞跃,光纤因其高速传输与大容量特性,成为通信领域的佼佼者。光纤主要分为单模与多模,两者在几何与传输特性上迥异,实际应用中表现显著不同。本文将深入剖析两者的差异与应用…

记一次黑群晖折腾的过程

Tips: 建议先完整看完这篇文章,理解大致流程后再上手操作,其中有一些注意点需要事先了解 安装黑群晖的教程网上很多,我是参考了这篇: https://post.smzdm.com/p/am3epen4/前言在上一盘文章中组装了一台黑群晖&#…

Docker基础篇之将本地镜像发布到私有库

文章目录 1. Docker Registry简介2. 将本地镜像推送到私有库 1. Docker Registry简介 Docker Registry是官方提供的工具,可以用于构建私有镜像仓库。 2. 将本地镜像推送到私有库 下载Docker Registry docker pull registry现在我们可以从镜像中看到下载的Regist…

数据持久化第七课-URL重写与Ajax

数据持久化第七课-URL重写与Ajax 一.预习笔记 1.URL重写(对网页地址进行保护) 首先编写module,实现对网络地址的处理 其次就是module的配置 最后验证url重写技术 2.Ajax数据交互 编写后端响应数据 处理跨域的配置问题 运行项目得到后端响应数据的地址 编写前端ajax进行数据请…

基于VGG16的猫狗数据集分类

目录 1. 作者介绍2. VGG16介绍2.1 背景介绍2.2 VGG16 结构 3. Cat VS Dog数据集介绍4. 实验过程4.1 数据集处理4.2 训练部分设置4.3 训练结果4.4 问题分析4.5 单张图片测试 5.完整训练代码与权重参考文献 1. 作者介绍 孙思伟,男,西安工程大学电子信息学…

Accelerate 笔记:保存与加载文件

保存和加载模型、优化器、随机数生成器和 GradScaler 使用 save_state() 将上述所有内容保存到一个文件夹位置使用 load_state() 加载之前通过 save_state() 保存的状态通过使用 register_for_checkpointing(),可以注册自定义对象以便自动从前两个函数中存储或加载 …

epoll源码分析

epoll源码分析 主要数据结构epoll_create()函数实现ep_alloc():初始化结构初始化eventpoll epoll_ctl()函数实现ep_insert回调函数的实现ep_ptable_queue_proc函数ep_poll_callback epoll_wait函数SYSCALL_DEFINE4(epoll_wait, ...)ep_pollep_send_events 主要数据结…

百度/迅雷/夸克,网盘免费加速,已破!

哈喽,各位小伙伴们好,我是给大家带来各类黑科技与前沿资讯的小武。 之前给大家安利了百度网盘及迅雷的加速方法,详细方法及获取参考之前文章: 刚刚!度盘、某雷已破!速度50M/s! 本次主要介绍夸…

基于DeepLabv3+实现图像分割

目录 1. 作者介绍2. DeepLabv3算法2.1 DeepLabv3算法介绍2.2 DeepLabv3模型结构 3. 实验过程基于DeepLabv3实现图像分割3.1 VOC数据集介绍3.2 代码实现3.3 问题分析 4. 参考连接 1. 作者介绍 吴天禧,女,西安工程大学电子信息学院,2023级研究…

派派派森02

目录 1.容器 1.列表 2.元组 3.字符串 3.序列 4.集合 5.字典 2.数据容器通用操作 • max最大元素 • min最小元素 • 容器的通用转换功能 • 通用排序功能 3.字符串大小比较 4.函数中多个返回值 5.函数参数多种传递方式 1.位置参数 2.关键字参数 3.缺省参数 …

(函数)判断字符串元音字母(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>//声明判断元音函数&#xff1b; void vowel(char a[100], char b[100]);int main() {//初始化变量值&#xff1b;char a[100] { 0 };char b[100] { 0 };//获取…

Python 图书馆管理系统 有GUI界面 【含Python源码 MX_031期】

使用python3&#xff0c;PyQt5&#xff0c;Sqlite3数据库搭建 数据库版本为MySQL&#xff1a;Python 图书馆管理系统&#xff08;MySQL数据库&#xff09; 有GUI界面 【含Python源码 MX_032期】-CSDN博客 主要功能&#xff1a; 用户注册、登录、修改密码、用户管理存储图书信…

Springboot校园美食推荐系统的开发-计算机毕业设计源码44555

摘要 随着人们生活水平的提高&#xff0c;人们对美食的要求也越来越高&#xff0c;对各类美食信息需求越来越大。因此&#xff0c;结合计算机快速发展、普及&#xff0c;在此基础上制作一个页面简单、美观,功能实用的校园美食推荐系统势在必行&#xff0c;满足用户分享美食的需…

【科学文献计量】使用Endnote软件打开中国知网导出的文献期刊解析不正确问题解决

使用Endnote软件打开中国知网导出的文献期刊解析不正确问题解决 问题解决问题 新建一个Endnote的材料库,然后把下载好的中国知网文献数据(知网数据导出的是Endnote格式样式)导入进来。找到文件所在路径,导入的类型选择是“Endnote import”,然后点击确定,界面结果如下 …

【Web API DOM04】事件类型、对象、解绑

一&#xff1a;事件类型 1 鼠标事件 常见鼠标事件 鼠标点击事件&#xff1a;’click‘ 鼠标移入事件&#xff1a;‘mouseenter’ 鼠标离开事件&#xff1a;‘mouseleave’ 鼠标经过事件区别 mouseover和mouseout会有冒泡效果 mouvseenter和mouseleave没有冒泡效果 2 焦…

有哪些挣钱软件一天能赚几十元?盘点十个能长期做下去的挣钱软件

在这个信息爆炸的时代&#xff0c;每个人都在寻找快速赚钱的秘诀。很多人做兼职副业的目标并不是获得很大的成功&#xff0c;大部分人一天能赚几十就心满意足了。 今天&#xff0c;我要带你一探究竟&#xff0c;揭秘那些能让你日赚几十元的挣钱软件。准备好了吗&#xff1f;让我…

vue3+typescript 使用Codemirror

安装 // npm npm install codemirror-editor-vue3 codemirror^5.65.12// ts版 还需安装&#xff1a; npm install types/codemirror全局注册 修改main.ts&#xff1a; import { createApp } from vueimport App from ./App.vueimport { InstallCodemirro } from "code…