微信小程序登录功能实现(前后端)

登录流程

大致流程

  1. 前端调用wx.login获取随机code,再调用后端接口传递code。注意:code是临时的,只有5分钟的使用时间,而且只能使用一次
  2. 后端用获取的code与微信接口服务换取openid(用户唯一标识)与session_key(可以用于解密私密信息encrydata,现在只能获取头像和昵称),关联openid和session_key自定义登录态session,利用session生成token
  3. 将token返回给前端
  4. 前端缓存token
  5. 用户登录时,登录接口获取到token,再调用其他接口时,拦截器进行拦截,如果token有效,则放行请求;如果token失效(不存在、过期、格式不正确等原因),则无法访问该接口,需要重新登录。

代码

小程序代码

// 通过wx.login获取临时登录code
wx.login({
  success (res) {
    if (res.code) {
      //发起网络请求
      wx.request({
        url: 'https://后端服务器/Login',
        data: {
          code: res.code
        }dataType:"json",
         // 获取成功将后端生成的token存入storage,之后发起请求都携带token
         success:function(res){
             result = res.data.result
             wx.setStorageSync('token', result.token)
              //页面跳转  ... 
             },
      })
    } else {
      console.log('登录失败!' + res.errMsg)
    }
  }
})

获取appid和密钥

在注册微信开发者账号后,可以在微信小程序管理后台获取appid和密钥,保存在配置文件或者系统环境中
使用Get请求调用微信服务接口
https://api.weixin.qq.com/sns/jscode2session?

//返回值
{
        "session_key": "xxxxx",
        "openid": "xxxxx"
}

go后端代码

v1.POST("/api/v1/user/login", api.UserLogin)           //用户登陆 2
// UserLogin 用户登陆接口
// 前端点击登录按钮获取用户信息,没有从存储器找到用户信息,就携带空token到后端服务器的校验token接口,后端服务器的校验接口中间件发现没有token,就返回前端没有token的代码
// 1 无token就发起请求并携带生成的有效期验证码和用户信息发送给后端服务器 3 后端服务器携带配置文件中的小程序密钥和有效期验证码发送给微信授权服务器 4 检验成功后返回给后端服务器唯一的openid
// 5 服务器拿到openid就把用户信息存入数据库并生成token返回给前端
// 6 前端把token解析出来用户信息并存储在存储器
// 7 下次前端校验到token直接加载用户信息,不用再登录直到token过期失效
func UserLogin(c *gin.Context) {
   session := sessions.Default(c)
   status := 200
   userID := session.Get("userId")
   code := c.Request.Header.Get("AuthCode")
   var loginService service.UserLoginService
   if err := c.ShouldBind(&loginService); err == nil {
      res := loginService.Login(userID, code, status)
      c.JSON(200, res)
   } else {
      c.JSON(200, ErrorResponse(err))
      logging.Info(err)
   }
}
// 用户登陆
func (service *UserLoginService) Login(userID interface{}, wx_code string, status int) serializer.Response {
   var user model.User
   code := e.Success
   // 微信服务器接口
   url := fmt.Sprintf("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code", conf.AppID, conf.Secret, wx_code)
   var session WxSession
   client := &http.Client{}
   // 使用Get请求调用微信服务接口
   request, err := http.NewRequest("GET", url, nil)
   if err != nil {
      return serializer.Response{
         Status: e.ErrorCodeReq,
         Msg:    e.GetMsg(e.ErrorCodeReq),
      }
   }
   response, _ := client.Do(request)
   body, err := ioutil.ReadAll(response.Body)
   if err := json.Unmarshal(body, &session); err != nil {
      return serializer.Response{
         Status: e.ErrorCodeResp,
         Msg:    e.GetMsg(e.ErrorCodeResp),
      }
   }

   if session.Errcode != 0 {
      return serializer.Response{
         Status: e.ErrorCodeOrder,
         Data:   nil,
         Msg:    session.Errmsg,
      }
   }
   fmt.Println(session.OpenID)
   err = model.DB.Where("open_id=?", session.OpenID).Find(&user).Error
   //如果查询不到,就新建用户
   if err != nil {
      user.Avatar = service.Avatar
      user.UserName = service.UserName
      user.OpenID = session.OpenID
      if err := model.DB.Create(&user).Error; err != nil {
         logging.Info(err)
         code = e.ErrorDatabase
         return serializer.Response{
            Status: code,
            Msg:    e.GetMsg(code),
            Error:  err.Error(),
         }
      }
   }
   // 返回生成的token
   token, err := util.GenerateToken(user.ID, service.UserName, session.OpenID, 0)
   if err != nil {
      logging.Info(err)
      code = e.ErrorAuthToken
      return serializer.Response{
         Status: code,
         Msg:    e.GetMsg(code),
      }
   }
   return serializer.Response{
      Status: code,
      Data:   serializer.TokenData{User: serializer.BuildUser(user), Token: token},
      Msg:    e.GetMsg(code),
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值