Django+微信小程序开发待办清单:小程序与Token
4280 views, 2023/10/17 updated Go to Comments
上一章中,我们已经从微信接口服务中取到了用户的 openid ,并和 Django 服务器的本地用户关联上了。
但是这还没完啊,小程序客户端还不知道发生了啥,得给它也颁发个密码之类的凭证吧,以便后续发起业务请求时表明自己的身份。这类凭证的形式很多(甚至可以自定义个密钥),为了方便和主流起见,本文就直接采用 JSON Web Token 了。(下文称 Token)
Django 后端
首先安装 simplejwt
库。这是个基于 DRF 的库,用它来操作 Token 非常之方便。
虚拟环境里执行:
(venv) > pip install djangorestframework-simplejwt
按照库文档的指示,在 Django 全局配置中增加下面的代码,指定通过 Token 的形式进行身份认证:
# backend/backend/settings.py
...
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}
接下来处理视图。对原有的 WeixinLogin()
类进行修改,并且新增 UserData()
视图类:
# backend/weixin/views.py
...
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework.permissions import IsAuthenticated
# 获取用户数据
class UserData(APIView):
# 鉴权方式
permission_classes = [IsAuthenticated]
def get(self, request, format=None):
return Response({'code': 'Authenticated.'})
# 微信登录
class WeixinLogin(APIView):
def post(self, request, format=None):
...
try:
...
except KeyError:
...
else:
...
refresh = RefreshToken.for_user(user)
return Response({
'code': 'success',
'refresh': str(refresh),
'access': str(refresh.access_token)
})
- 视图类
UserData()
通过permission_classes
,指定任何通过此类的请求必须是已登录用户。然后定义了一个简单的用于测试的 GET 请求。 - 视图类
WeixinLogin()
新增了一行代码,用于给当前用户生成一个有效期为 5 分钟的 Token,并将 Token 返回给小程序前端。
access
即为 Token 。refresh
是用于 Token 失效后,重新获取新 Token 的令牌。不过本文为了简单起见,并不会用到这个刷新令牌。
老规矩,给新的视图类安排路由:
# backend/weixin/urls.py
...
from weixin.views import WeixinLogin, UserData
urlpatterns = [
...
path('data/', UserData.as_view(), name='data'),
]
Django 部分这样就可以了。
小程序前端
上一章在生命周期 attached()
中写的代码只是测试的,没太大用处。
因此这里将其大幅修改,变为下面这样:
// frontend/pages/index/index.js
...
lifetimes: {
attached() {
// --------------
// 步骤一:获取code
// --------------
wx.login({
success(res) {
if (res.code) {
// --------------
// 步骤二:用code换取token
// --------------
wx.request({
url: 'http://127.0.0.1:8000/api/weixin/login/',
method: 'POST',
data: {
code: res.code
},
success: res => {
// 在小程序调试器中查看是否收到token
console.log(res)
const access = res.data.access
// 将token保存到缓存
wx.setStorage({ key: "access", data: access })
// 保存token的获取时间
wx.setStorage({
key: "access_time",
data: Date.parse(new Date())
})
// --------------
// 步骤三:用token获取用户数据
// --------------
wx.request({
url: 'http://127.0.0.1:8000/api/weixin/data/',
header: {
// 注意字符串 'Bearer ' 尾部有个空格!
'Authorization': 'Bearer ' + access
},
success: res => {
// 在小程序调试器中查看返回值是否正确
console.log(res)
}
})
}
})
} else {
console.log('登录失败!' + res.errMsg)
}
}
})
},
},
这一大坨东西共分为三块功能:
- 步骤一:
wx.login()
获取临时登录凭证 Code。 - 步骤二:
wx.request()
用 Code 从 Django 服务器换取 Token,并将 Token 和获取的时间戳存到缓存中。 - 步骤三:
wx.request()
在请求的 header 中携带 Token,去请求 Django 服务器的UserData()
视图类。
一切顺利的话,这三步都会成功,并且在小程序调试器中打印出获取的数据,像下面这样:
总结
到这里,我们已经打通小程序、Django 和微信接口服务的三端链路了。
接下来的工作就和常规的前后端分离项目基本相同了,即前端和后端通过 Token 进行鉴权和通讯的故事。