使用go + gin + jwt + qrcode实现网站生成登录二维码在app中扫码登录功能
Go  /  管理员 发布于 2小时前   4
最近接到一个需求: 同一个用户体系下,在app上扫码网站上的登录二维码实现登录功能
环境架构go+ gin + jwt + go-qrcode
思路步骤
1.在网站登录页面生成带uuid的url登录二维码,接口已通过uuid生成临时tk;
2.在app上用户登录后扫码网站上的二维码,获取url, 通过url及uuid获取临时tk接口, 然后验证临时tk及确认绑定真实tk;
3.在网站上轮询查询uuid登录状态;
配置路由:
g.POST("loginQRCode", v1.LoginQRCode)
g.POST("loginCheckStatus", v1.LoginCheckStatus)
//登录app后才能调用
r.POST("getLoginQRCode", v1.GetLoginQRCode)
r.POST("loginQRCodeScan", v1.LoginQRCodeScan)接口实现: (注意 : 这里的token就是uuid)
1.
func LoginQRCode(c *gin.Context) {
j := middleware.NewJWT()
claims := api.CustomClaims{}
// 生成随机token,生成JWT包含token和过期时间
token := utils.GenerateRandomToken()
claims.Token = token
claims.ExpiresAt = j.GetExpire60()
jwtToken, err := j.CreateToken(claims)
if err != nil {
resp.ERRWithMsg(c, resp.USER_PARAM_ERR, "生成令牌失败")
return
}
// 存储初始状态
loginMap[token] = jwtToken
// 生成二维码图片
qrcode := utils.UrlToQrcode(jwtToken)
resp.OkWithData(gin.H{"QRcode": qrcode, "Token": claims.Token, "Exp": claims.ExpiresAt}, c)
}2.1 根据uuid获取临时tk
func GetLoginQRCode(c *gin.Context) {
type Request struct {
Token string `json:"token"`
}
var req Request
if err := c.ShouldBindJSON(&req); err != nil {
resp.ERRWithMsg(c, resp.USER_PARAM_ERR, "无效请求")
return
}
status, exists := loginMap[req.Token]
if !exists {
resp.ERRWithMsg(c, resp.USER_PARAM_ERR, "Token error")
return
}
resp.OkWithData(gin.H{"QRToken": status}, c)
}2.2 验证临时tk及确认绑定真实tk
// 在app中扫码验证接口
func LoginQRCodeScan(c *gin.Context) {
type Request struct {
QRToken string `json:"qr_token"`
UserToken string `json:"user_token"`
}
var req Request
if err := c.ShouldBindJSON(&req); err != nil {
resp.ERRWithMsg(c, resp.USER_PARAM_ERR, "无效请求")
return
}
j := middleware.NewJWT()
// 验证JWT令牌
claims, err := j.VerifyJWTToken(req.QRToken)
if err != nil {
resp.ERRWithMsg(c, resp.USER_PARAM_ERR, "无效二维码")
return
}
token := claims.Token
_, exists := loginMap[token]
if !exists {
resp.ERRWithMsg(c, resp.USER_PARAM_ERR, "二维码已失效")
return
}
// 更新登录状态
loginMap[token] = req.UserToken
resp.OkWithMessage("success", c)
}3.在网站上轮询查询uuid登录状态
func LoginCheckStatus(c *gin.Context) {
type Request struct {
Token string `json:"token"`
}
var req Request
if err := c.ShouldBindJSON(&req); err != nil {
resp.ERRWithMsg(c, resp.USER_PARAM_ERR, "无效请求")
return
}
status, exists := loginMap[req.Token]
if !exists {
resp.ERRWithMsg(c, resp.USER_PARAM_ERR, "no exists")
return
}
j := middleware.NewJWT()
claims, err := j.ParseToken(status)
if err != nil {
resp.ERRWithMsg(c, resp.USER_PARAM_ERR, "token error")
return
}
result := resp.RespWithToken{
UserInfo: model.RespUser{
UserId: claims.User.UserId,
Email: claims.User.Email,
Mobile: claims.User.Mobile,
AuthorityId: claims.User.AuthorityId,
Img: claims.User.Img,
Country: claims.User.Country,
NickName: claims.User.NickName,
},
Token: status,
Expire: claims.ExpiresAt,
}
resp.OkWithData(result, c)
}后端接口已经完成, 后续就是前端调用接口及对接联调.
效果图不发了, 因为功能已经上线!
有需要自行执行代码测试!
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号
