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

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指向前端服务器,并获得前端的页面)。

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

  • 28
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Boot框架是一种轻量级、开箱即用的Java开发框架,它大大简化了企业级应用的开发过程。要实现微信扫码登录,可以使用Spring Boot框架结合微信开放平台的API来实现。以下是实现微信扫码登录的步骤: 1. 注册微信开放平台账号并创建应用,获取AppID和AppSecret。 2. 创建Spring Boot项目并导入相关依赖,如web、httpclient等。 3. 在配置文件application.properties中配置微信开放平台的AppID和AppSecret。 4. 创建一个控制器,用于处理登录相关的请求。 5. 定义一个生成微信扫码登录链接的方法,该方法使用AppID、重定向URI和state等参数生成微信登录链接。 6. 在控制器中定义一个登录请求的接口,该接口返回生成的微信扫码登录链接。 7. 创建一个回调接口,用于处理微信登录成功后的回调请求。 8. 在回调接口中获取微信的授权code,通过code和AppID、AppSecret等参数向微信服务器发送请求,获取用户的唯一标识openid。 9. 将获取到的openid存储到数据库或Session中,表示用户已登录。 10. 在需要验证用户登录状态的接口中,通过openid验证用户是否已登录。 以上是使用Spring Boot实现微信扫码登录的基本步骤,通过控制器处理登录和回调接口,以及与微信服务器的交互,可以实现用户使用微信扫码登录系统的功能。当然,具体实现中还需要考虑安全性、数据持久化等问题,以及前端页面的设计和展示等方面的内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值