微信小程序登录后端开发流程(附go后端实现代码)

参考:
微信官方文档 * 小程序登录流程
微信官方文档 * 小程序

本文参考以上文档, 加上自己理解整合写出.

登录流程

  1. 前端调用wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
  2. 后端调用 auth.code2Session 接口,换取 用户唯一标识OpenID会话密钥 session_key
  3. 开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。
    在这里插入图片描述

    上图就是小程序登录的基本流程.

作为一个后端开发人员, 看完上述描述后, 内心是这样的:


image

嗯, 道理我都懂, 代码怎么写?

接下来我们用go实现这个流程:

首先code是前端获取传到后端的, 我们不用管, 只要在HTTP请求种拿到这个参数即可.
ok, 第一步的code已经拿到.

然后第二步, 利用code获取openIDsession_key, 这里我们看微信官方文档给的接口:

https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

到这里有接口. 有返回值, 我们就可以通过HTTP请求获取openIDsession_key了.

现在开始写代码实现, 我使用的是go语言, 其实道理都是一样的.

定义返回值数据结构:

type WXLoginResp struct {
    OpenId string           `json:"openid"`
    SessionKey string       `json:"session_key"`
    UnionId string          `json:"unionid"`
    ErrCode int             `json:"errcode"`
    ErrMsg string           `json:"errmsg"`
}

定义实现函数:

// 这个函数以 code 作为输入, 返回调用微信接口得到的对象指针和异常情况
func WXLogin(code string) (*WXLoginResp, error) {
    url := "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
    
    // 合成url, 这里的appId和secret是在微信公众平台上获取的
    url = fmt.Sprintf(url, appId, secret, code)  

    // 创建http get请求
    resp,err := http.Get(url)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    // 解析http请求中body 数据到我们定义的结构体中
    wxResp := WXLoginResp{}
    decoder := json.NewDecoder(resp.Body)
    if err := decoder.Decode(&wxResp); err != nil {
        return nil, err
    }
        
    // 判断微信接口返回的是否是一个异常情况
    if wxResp.ErrCode != 0 {
        return nil, errors.New(fmt.Sprintf("ErrCode:%s  ErrMsg:%s", wxResp.ErrCode, wxResp.ErrMsg))
    }

    return &wxResp, nil
}

ok, 到这里, 我们已经获得了openidsession_key .

接下来实现第三步, 这一步比较灵活, 根据自己的需求生成自定义登录态, 并返回前端;

这里我们用gin框架实现一个路由接口, 将上面的内容串联起来, 形成一个完整的流程;下面的代码仅供参考

// /wechat/applet_login?code=xxx [get]  路由
// 微信小程序登录
func AppletWeChatLogin(c *gin.Context) {
    code := c.Query("code")     //  获取code
    // 根据code获取 openID 和 session_key
    wxLoginResp,err := models.WXLogin(code)
    if err != nil {
        c.JSON(400, util.Fail(err.Error()))
        return
    }
    // 保存登录态
    session := sessions.Default(c)
    session.Set("openid", wxLoginResp.OpenId)
    session.Set("sessionKey", wxLoginResp.SessionKey )
    
    // 这里用openid和sessionkey的串接 进行MD5之后作为该用户的自定义登录态
    mySession := GetMD5Encode(wxLoginResp.OpenId + wxLoginResp.SessionKey)
    // 接下来可以将openid 和 sessionkey, mySession 存储到数据库中, 
    // 但这里要保证mySession 唯一, 以便于用mySession去索引openid 和sessionkey
    c.String(200, mySession)
    
}
// 将一个字符串进行MD5加密后返回加密后的字符串
func GetMD5Encode(data string) string {
    h := md5.New()
    h.Write([]byte(data))
    return hex.EncodeToString(h.Sum(nil))
}

可能代码部分不太能看懂, 这里再用文字解释一下:

  1. 获取路由中的code 参数
  2. 利用code调用我们之前写好的函数获取openidsession_key
  3. 利用得到的 openidsession_key 生成我们自定义的登录态(这里方式有很多, 保证生成的值全局唯一即可, 这里我们简单化了, 直接利用openidsession_key进行MD5加密, 将得到的字符串作为我们的登录态(这里登录态理解为索引即可, 本质是一个字符串))
  4. 最后将我们定义的登录态以及openidsession_key存储到数据库中, 并且保证能用自定义的登录态唯一查询到该用户的openidsession_key. 以便我们后期用到的时候可以查询到.

到这里微信小程序登录已经基本完成了.

这里, 微信官方还提供了一个校验接口, 用于校验小程序端获取的用户信息是否完整,这个也是我们之前获得的session_key的意义,

这里可以参考: 微信官方文档 * 后台校验与解密数据

我们也给出校验代码, 非常简单:
实际上就是将前端提供的微信原始数据和我们之前获取的session_key进行MD5加密, 得到signature2, 与微信加密的结果进行比较, 相同即为没有改变, 不同即是原始数据发生了改变.

// 校验微信返回的用户数据
func ValidateUserInfo(rawData, sessionKey, signature string) bool {
    signature2 := GetSha1(rawData + sessionKey)
    return signature == signature2
}
// SHA-1 加密
func GetSha1(str string) string {
    data := []byte(str)
    has := sha1.Sum(data)
    res := fmt.Sprintf("%x", has) //将[]byte转成16进制
    return res
}

以上就是微信小程序登录, 后台涉及到的所有操作.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容

  • 背景 微信小程序的使用可以快速的基于场景进行用户圈的建立推广,其中根据业务需要使用用户信息以及授权过程,主要用到的...
    极乐叔阅读 1,166评论 1 4
  • 小程序调用wx.login得到code. 调用接口获取登录凭证(code)进而换取用户登录态信息,包括用户的唯一标...
    T_ttt阅读 10,917评论 0 1
  • 最近公司项目不是很忙,有时间研究研究微信小程序。参考了目前市场上各类答题类的app、小程序等等,做了一款自己的微信...
    阳呀呀阅读 1,824评论 0 18
  • 简介: 微信登陆,在新建一个微信小程序Hello World项目的时候,就可以看到项目中出现了我们的微信头像,其实...
    大海_e68f阅读 1,792评论 1 4
  • 通过 wx.login() 获取到用户登录态之后,需要维护登录态。开发者要注意不应该直接把 session_key...
    奇点一氪阅读 7,107评论 2 4