基于token的用户权限认证机制——以微信公众号授权网页为例

项目背景

最近在开发一个微信公众号商城,在调用下单、支付、查询订单等等接口时,需要验证用户的身份。微信提供了openid作为识别用户身份的凭证,可以结合openid设计一套用户身份权限认证机制。考虑到安全性和易实现程度,备选的方案有Session认证机制和Token认证机制,本文在比较了两者的特点后选择了Token认证机制,然后详细阐述了如何实现Token认证机制。

接口设计

在寻找合适的认证方式之前,先说明一下项目前后端的设计。项目的前后端是分离的,前端使用AJAX的方式向后端请求操作资源(增、删、改);后端接口设计遵循RESTful API原则,结果以JSON格式返回

身份认证备选方案

Session认证

在web网站中,session可以将访客状态记录在服务器中,并分配一个唯一的session id给访客,并将该id附加在headers中返回给客户端。客户端接收到session id后,会将id存储在cookie,之后客户端每次访问服务器,传送的cookie中都会携带session id,服务器以此来识别访客的身份。
Session认证流程

Token认证

token认证方式中客户端和服务器的交互过程与session的类似,客户端向服务端请求token,拿到token后,客户端可以在之后的请求中将token附加在header,以验证用户的身份和权限。
Token认证流程

比较两种认证方式

【此处应该列举诸多不同,但是一定要提到为什么token更适合,而不是session】

  1. token认证更灵活。对于session认证,客户端每次发送求情都会发送cookie;而对于token认证,可以在需要身份验证的场景下才发送token。
  2. token允许多域名认证。cookie是绑定单域名的,在a域名生成的cookie无法用于b域名,所以session id无法作为不同域名的共同认证id。而token认证则不受限制,token可以附加在任何请求上。
  3. 在客户端的存储方式不同。session自动存储在cookie,而token则需要定义存储的方式。token通常可以存储在localStorage(永久存储,浏览器关闭时不清除token)、sessionStorage(浏览器关闭时token会被清除)、cookie。值得一提的是,即使将token存储在cookie,也可以免疫CSRF,因为cookie中的token并不用于认证。
  4. CSRF(跨站请求伪造)。认证免疫CSRF(跨站请求伪造),而session认证则存在遭受CSRF的可能性。
  5. 跨站脚本攻击(XSS)。相对于session认证,token认证更容易遭受跨站脚本攻击(XSS)。

本项目考虑到Token认证机制更灵活,例如token可以控制是否附加在请求、token本身可以进行自定义加密、可以将token存储在cookie以外的地方,所以选定Token认证机制作为商城应用的用户身份权限认证机制。

获取token的流程

获取token的流程

  1. 客户端向服务端token接口提交code,请求获取token。此处的code是引导用户进入授权页面后微信服务器附加上去的,详细方法见微信公众平台的微信授权网页文档
  2. 服务端通过code向微信公众平台换取用户的openid。微信授权网页有两种授权scope,本项目只需要用户的openid,不需要用户更多的信息,所以将scope设为snsapi_base
  3. 微信公众平台向服务端返回了openid等等信息。
  4. 服务端生成token,将token和用户信息以键值对的形式存储后,服务端返回token给客户端。

存储token及用户信息的流程

存储token及用户信息的流程

  1. 服务端获取用户的openid后,在数据库中登记用户的信息,并取出用户的id。
  2. 服务端以token为key,以openid、user id、权限信息等为value,将该键值对存入缓存中。在存入缓存时,注意设置缓存有效时间,过长的有效期存在安全隐患,对于本项目,用户办理业务后短时间内不会再访问,所以将token的有效期设置为2小时。

调用接口时的token认证流程

token认证流程

  1. 客户端将token附加在header,向业务接口发送请求。
  2. 业务接口在执行业务逻辑前,凭token验证用户的身份。分别验证以下三点:

    • token的合法性(有记录)
    • token的有效性(没过期)
    • Token对应的用户权限Auth

总结

Token机制的特点

  • 使用灵活,可以选择性认证。
  • 可以多个域名使用同一token认证体系。
  • 在客户端的存储灵活,除了存储在cookie,还可以选择localStorage、sessionStorage。
  • 免疫CSRF(跨站请求伪造)。

Token认证机制的三个流程

  • 获取Token的流程。
  • 存储Token及身份权限信息的流程。
  • 调用接口时的Token认证流程。特别注意需要验证token的合法性、时效性、关联的用户权限。
### 通过 UnionID 获取微信公众号用户信息 为了利用 UnionID 来获取微信公众号中的用户信息,开发者需遵循特定流程来实现这一目标。UnionID 是指当同一开放平台账号下的不同应用被同一个微信用户关注或绑定时,这些应用间可以获取到该用户的统一标识符——即 UnionID。 #### 准备工作 确保已获得用户的同意并通过 OAuth2.0 授权码模式获得了 `code` 参数以及对应的 OpenID 和 Access Token。对于已经绑定了相同开放平台账户的应用程序来说,在获取到了某个用户的 OpenID 后还可以进一步得到其 UnionID[^2]。 #### 正确构建 API 请求 URL 一旦拥有了必要的参数(如 AppID, Secret, Code),就可以向微信服务器发送请求以换取 access_token: ```http GET https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code ``` 接着使用返回的结果中的 openid 或者 unionid 构建如下形式的信息查询URL: ```http GET https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN ``` 如果要基于 UnionID 查询,则替换其中的 OPENID 字段为 UNIONID 即可[^1]。 需要注意的是,并不是所有的场景下都能直接拿到 UnionID;只有在同一开放平台内的多个应用之间共享数据时才会涉及到此字段。因此,在设计应用程序逻辑前应当确认当前环境是否满足条件[^3]。 另外值得注意的一点是在本地环境中调试可能会遇到一些权限上的限制,建议按照官方指南完成相应的配置调整以便顺利进行开发测试工作[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值