经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Django » 查看文章
django与小程序实现登录验证功能的示例代码
来源:jb51  时间:2019/2/20 9:17:26  对本文有异议

之前用小程序做项目,因为后台使用的java开发,一切顺利,但切换成django做RESTful API接口时,在登陆注册时一直出现问题,网上搜索,借助一个网友的回答,找到了一种可行的解决方案,现记录如下。

具体流程

  • 用户点击小程序页面上的登录授权认证
  • 通过微信自带的认证获取code
  • 调取登录接口,将code传入后台
  • 后台拿到code调用微信接口获取openid等用户信息
  • 后台将openid作为用户名,若存在则去校验用户信息,否则以此用户名创建新用户,密码随机生成
  • 将校验结果或者创建信息返回给微信小程序端
  • 根据返回的信息完成用户登录校验

django的用户权限认证

django有一套自己的完善用户模型,由于Django Auth自带的User模型字段有限,我们需要对其进行拓展(直接使用也可以)

  1. nickname = models.CharField(verbose_name=u'昵称',max_length=50, blank=True)
  2. user_avatar = models.ImageField(verbose_name=u'用户头像', upload_to='image/%Y/%m/%d', default=u'image/default.png', max_length=500)
  3. user_email = models.EmailField(verbose_name=u'用户邮箱',max_length=254)
  4. user_phone = models.BigIntegerField(verbose_name=u'手机号', null=True,blank=True)
  5. user_birthday = models.DateField(verbose_name=u'出生日期', default = timezone.now)
  6. user_sex = models.CharField(verbose_name=u'性别',max_length=6,choices=(('male','男'),('female','女')),default='male')
  7. user_address = models.CharField(verbose_name=u'地址',max_length=550, blank=True,null=True)
  8. signature = models.CharField(verbose_name=u'个性签名',max_length=550, blank=True,null=True)

用户接口序列化

  1. from rest_framework import serializers
  2.  
  3. class UserSerializer(serializers.ModelSerializer):
  4. class Meta:
  5. model = User
  6. fields = "__all__"

登陆接口设计

  1. class UserLogin(APIView):
  2. def post(self,request):
  3. params = request.data
  4. userName = get_openid(params.get('code'))
  5. userInfo = params.get('userinfo')
  6. try:
  7. user = User.objects.get(username = userName)
  8. except Exception as e:
  9. user = None
  10. if user:
  11. # 更新用户信息
  12. user = User.objects.get(username = userName)
  13. else:
  14. #注册新用户
  15. user = User.objects.create_user(username=userName,password=random_str(10))
  16. #手动生成JWT
  17. # 手动生成token验证
  18. jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
  19. jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
  20. payload = jwt_payload_handler(user)
  21. token = jwt_encode_handler(payload)
  22.  
  23. ret = {'code': '00000', 'msg': None,'data':{}}
  24. ret['msg'] = '授权成功'
  25. ret['data'] = {
  26. 'token': token,
  27. 'user_id': user.id,
  28. 'nickname': user.nickname
  29. }
  30. return JsonResponse(ret)

解析code获取openid

  1. class OpenidUtils(object):
  2. def __init__(self, jscode):
  3. self.url = "https://api.weixin.qq.com/sns/jscode2session"
  4. self.appid = APPID
  5. self.secret = SECRET
  6. self.jscode = jscode # 前端传回的动态jscode
  7.  
  8. def get_openid(self):
  9. url = self.url + "?appid=" + self.appid + "&secret=" + self.secret + "&js_code=" + self.jscode + "&grant_type=authorization_code"
  10. r = requests.get(url)
  11. openid = r.json()['openid']
  12. return openid
  13.  

小程序的登陆验证

具体登录流程可以查阅官方文档。

  1. function getWXUserInfo() {
  2. const login = promisify(wx.login);
  3. const getUserInfo = promisify(wx.getUserInfo);
  4.  
  5. return new Promise(function (resolve, reject) {
  6. _wxLogin();
  7. function _wxLogin() {
  8. login().then(function (res) {
  9. getUserInfo().then(function (r) {
  10. let userInfo = r;
  11. userInfo.code = res.code;
  12. try {
  13. wx.setStorageSync('userInfo', userInfo);
  14. } catch (e) {
  15. console.log(e)
  16. }
  17. if (userInfo && userInfo.code && userInfo.iv) {
  18. resolve(userInfo);
  19. }
  20. else {
  21. reject('wx login fail');
  22. }
  23. }).catch(function (error) {
  24. reject(error);
  25. });
  26. }).catch(function (error) {
  27. reject(error);
  28. });
  29. }
  30. });
  31. }
  32.  
  33. //登录接口验证
  34. getWXUserInfo().then(function (data) {
  35. var result = {
  36. code: 0,
  37. data: {}
  38. };
  39. var params = {
  40. 'code':data.code,
  41. 'userinfo':data.userInfo
  42. }
  43. wx.request({
  44. url: '/api/login',
  45. data: params,
  46. dataType: 'json',
  47. method: 'POST',
  48. success: function (response) {
  49. // 返回成功
  50. if (response.data && response.data.code == '00000') {
  51. try {
  52. var resData = {
  53. custNo: data.user_id,
  54. nickname: data.nickname
  55. };
  56. result.code = 0;
  57. result.data = resData;
  58. resolve(result);
  59. }
  60. catch (e) {
  61. console.warn(result)
  62. // 登录失败
  63. result.code = 2;
  64. resolve(result);
  65. }
  66. }
  67. else {
  68. // 获取 customNum 失败
  69. console.warn(result)
  70. result.code = 1;
  71. result.data = 'get customNum fail';
  72. resolve(result);
  73. }
  74. }
  75. })
  76. }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号