问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

微信小程序登录流程详解:从code到openid的完整解析

创作时间:
作者:
@小白创作中心

微信小程序登录流程详解:从code到openid的完整解析

引用
CSDN
1.
https://blog.csdn.net/qq_42750982/article/details/145011455

微信小程序的登录流程涉及多个技术细节,包括code、openid、session_key等关键概念。本文将通过问答形式,深入解析这些概念的作用和必要性,帮助开发者更好地理解微信小程序的登录机制。

首先需要调用微信的API wx.login,告诉微信的后端服务器,我要登录小程序,请给我一个临时登录凭证code。有点像用户的临时身份证。

而开发者在微信公众平台就可以注册生成AppID(小程序ID)、AppSecret(小程序秘钥),相当于开发者的的身份证。

然后开发者服务器说你把code给我,我把你的“身份证”还有我的“身份证”一并拿去给微信服务器“签合同”,所以在微信服务器的见证下他们签了“三方协议”。就像我们刚毕业和公司签的也是三方协议,学校是见证人,防止公司赖账不承认,可能这也有点那个意思?言归正传,微信服务器把openid和session_key返回给开发者服务器,那么这两个又是有什么用处呢?听名字也感觉云里雾里的

我们先回顾一下流程:

  1. 调用wx.login()获取临时登录凭证code,并回传到开发者服务器。
  2. 调用auth.code2Session接口,换取用户唯一标识 OpenID会话密钥 session_key

之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。

好了,整个流程梳理完了,为什么有了code,还需要openid呢?因为code是临时身份证,微信开发文档还有一句话:临时登录凭证 code 只能使用一次,也就是这个规定让code变成一张废纸了,也就是一次性的票据,有效期较短,一般为5分钟。所以为什么要这样设计呢?安全性考虑!

问题一:为什么要把code设计成一次性的呢?

code 设计为一次性使用的机制是为了增强安全性,防止潜在的安全风险和滥用。以下是几个关键原因,解释了为什么微信和其他类似平台选择将 code 设计为一次性:

  1. 防止重放攻击
  • 定义:重放攻击(Replay Attack)是指攻击者拦截并记录一次合法的通信会话中的数据包,然后在稍后的时间重复发送这些数据包以欺骗系统。
  • 解决方案:通过使 code 只能使用一次,即使攻击者成功截获了一个 code,他们也无法再次使用它来获取 openidsession_key。这大大降低了重放攻击成功的可能性。
  1. 提高时效性
  • 短生命周期:每个 code 都有一个短暂的有效期(通常为5分钟)。这种设计确保了 code 的时效性,减少了因长时间有效的令牌而带来的风险。
  • 即时验证:用户每次登录时都会生成一个新的 code,这意味着开发者服务器需要及时与微信服务器交互以验证用户身份。这有助于保持系统的实时性和响应速度。
  1. 防止滥用和泄露
  • 限制使用次数:一次性使用的特性限制了 code 的使用次数,从而减少了恶意用户或攻击者滥用的可能性。
  • 降低泄露风险:如果 code 被泄露或意外暴露给第三方,由于它的单次有效性和短生命周期,造成的损害是有限的。攻击者无法利用已失效的 code 进行进一步的操作。
  1. 简化管理
  • 减少状态维护:一次性 code 简化了微信服务器的状态管理和清理工作。微信服务器不需要长期存储和管理大量的 code,只需处理当前有效的 code 即可。
  • 提升效率:对于微信服务器而言,处理一次性 code 更加高效,因为它可以快速判断 code 是否已经使用过或是否仍在有效期内,而无需进行复杂的查询或匹配操作。
  1. 增强用户体验
  • 无缝切换设备:用户可以在多个设备上同时使用同一个微信账号登录小程序。由于 code 是一次性且具有短生命周期,用户在不同设备上的登录体验更加流畅,不会因为某个设备上的 code 仍然有效而导致其他设备无法正常登录。
  1. 符合安全最佳实践
  • 遵循标准:一次性 code 的设计符合现代网络安全的最佳实践,类似于 OAuth 2.0 授权码模式等协议中的一次性令牌机制。这确保了微信小程序的身份验证流程符合行业标准,并提供了高水平的安全保障。

总结
综上所述,将 code 设计为一次性使用的机制是出于多方面的考虑,包括但不限于防止重放攻击、提高时效性、防止滥用和泄露、简化管理以及提升用户体验。这种设计不仅增强了系统的安全性,也使得整个身份验证过程更加可靠和高效。

问题二:每次请求的code都是不一样的,微信服务器怎么识别到是同一个用户(返回同一个openid)的?

每次调用 wx.login() 获取的 code 确实是不同的,但微信服务器能够通过这个临时的 code 关联到用户的微信账号。这背后涉及到了安全性和隐私保护的设计原则,确保了用户身份的正确识别和数据的安全传输。以下是详细的解释:

  1. code 的生成与作用
  • 唯一性:每个 code 是由微信服务器根据特定的时间戳、设备信息和其他参数生成的,因此它是唯一的,并且具有时效性(通常有效期为5分钟)。
  • 一次性使用code 只能使用一次,一旦用于换取 openidsession_key 后就失效。
  1. codeopenid 的映射过程
    当客户端调用 wx.login() 获取 code 并将其发送到开发者服务器后,开发者服务器会调用微信提供的 /sns/jscode2session 接口来换取 openidsession_key。具体步骤如下:
  • 开发者服务器请求 /sns/jscode2session

  • 请求参数

  • appid:小程序的 AppID。

  • secret:小程序的 AppSecret。

  • js_code:从 wx.login() 获取的 code

  • grant_type:固定值 authorization_code

  • 示例请求
    GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

  • 微信服务器的处理逻辑

  • 验证 code:微信服务器接收到请求后,首先验证传入的 code 是否有效。由于 code 包含了时间戳等信息,微信服务器可以确认它是由自己在一定时间内生成的,并且没有被篡改或重复使用。

  • 关联用户账户:微信服务器内部维护了一个映射表,将每个 code 与生成它的用户账户(即微信账号)关联起来。尽管 code 每次都不一样,但它包含了足够的信息让微信服务器能够找到对应的用户账户。

  • 返回 openidsession_key:如果验证成功,微信服务器会返回该用户账户对应的 openidsession_key。对于同一个微信账号,在同一个小程序中,无论用户使用什么设备,微信服务器都会返回相同的 openid

  1. 总结
    尽管每次调用 wx.login() 获取的 code 都是不同的,但微信服务器通过内部的映射机制和严格的验证流程,能够在验证 code 的同时准确地关联到用户的微信账号。这样不仅保证了用户身份的一致性和准确性,也提高了系统的整体安全性。用户无论在哪台设备上登录同一个小程序,微信服务器都能识别出这是同一个用户,并返回一致的 openid

openid 的应用场景

  1. 用户身份识别:通过 openid,可以准确地识别出每一个独立的用户,即使他们在不同的设备或平台上使用同一个微信账号。
  2. 数据统计与分析:开发者可以利用 openid 来追踪和分析用户的行为,从而优化小程序的功能和服务。
  3. 交易与支付:在进行微信支付等敏感操作时,openid 作为用户身份的一种验证手段,确保交易的安全性和准确性。

注意事项

  • openid 具有唯一性,但仅限于同一小程序内。即,不同小程序间的 openid 并不通用。
  • 在处理用户数据时,应严格遵守相关隐私保护法规,确保用户信息安全。

问题三:为什么最后还需要生成一个自定义登录态token给用户?有什么作用?

在微信小程序开发中,除了使用微信提供的 openidsession_key 进行用户身份验证外,生成自定义登录态(即自定义的 token)也是常见的做法。这样做有多个重要的原因和作用:

  1. 增强安全性
  • 避免频繁调用微信接口:每次需要验证用户身份时都去调用 /sns/jscode2session 接口获取 openidsession_key 是不现实的,因为这会增加网络延迟,并且频繁调用可能会触发微信的安全限制。
  • 保护敏感信息session_key 是非常敏感的信息,它用于解密用户的加密数据。将 session_key 直接存储在客户端或频繁在网络上传输是不安全的做法。通过引入自定义 token,可以避免直接暴露 session_key
  1. 简化用户会话管理
  • 统一的会话机制:自定义 token 可以作为服务器端维护用户会话的一种方式。与传统的基于 Session 的会话管理相比,token 方式更加灵活,适合无状态的服务架构(如 RESTful API),并且可以更容易地实现分布式部署。
  • 跨平台支持:如果开发者同时拥有多个平台(如 Web、移动端应用等),自定义 token 可以用于统一这些平台的用户认证流程,确保不同平台之间的一致性和互操作性。
  1. 扩展功能和服务
  • 权限控制:自定义 token 可以携带更多的信息,例如用户角色、权限级别等,从而实现更细粒度的访问控制。这对于复杂的应用场景非常重要,比如某些页面或API只允许特定类型的用户访问。
  • 个性化推荐和服务:基于 token 中包含的用户信息,可以为用户提供个性化的体验,如推荐内容、定制化服务等。
  1. 提升用户体验
  • 无缝切换设备:通过自定义 token,用户可以在多个设备上保持一致的登录状态。即使用户在同一时间从多个设备登录,也能享受无缝的体验,而不需要重复输入凭证。
  • 减少登录频率:有了长期有效的 token,用户无需每次都进行完整的登录流程,提高了使用的便捷性。
  1. 符合最佳实践
  • 遵循现代认证标准:使用 JWT(JSON Web Token)或其他形式的自定义 token 符合现代互联网应用的身份验证和授权的最佳实践。这种方式不仅安全可靠,而且易于集成和扩展。

自定义 token 的典型生命周期

  1. 首次登录
  • 用户首次登录时,通过 wx.login() 获取 code,然后在服务器端调用 /sns/jscode2session 接口获取 openidsession_key
  • 服务器端根据 openid 创建一个自定义 token,并将 token 返回给客户端。
  1. 后续请求
  • 客户端在之后的所有请求中附带这个 token,服务器端通过验证 token 来确认用户身份。
  • 如果 token 失效或即将过期,可以通过刷新机制重新获取新的 token,而不需要用户再次登录。
  1. 登出或失效
  • 当用户主动登出或者 token 超过有效期时,token 将被标记为无效,用户需要重新登录。

总结
生成自定义登录态 token 是为了提供一种更加安全、高效、灵活的用户身份验证机制。它不仅简化了会话管理和权限控制,还提升了用户体验,同时遵循了现代网络安全的最佳实践。通过这种方式,开发者可以在微信小程序中构建更为强大和安全的应用程序。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号