django与小程序实现登录验证功能的示例代码
之前用小程序做项目,因为后台使用的java开发,一切顺利,但切换成django做RESTfulAPI接口时,在登陆注册时一直出现问题,网上搜索,借助一个网友的回答,找到了一种可行的解决方案,现记录如下。
具体流程
- 用户点击小程序页面上的登录授权认证
- 通过微信自带的认证获取code
- 调取登录接口,将code传入后台
- 后台拿到code调用微信接口获取openid等用户信息
- 后台将openid作为用户名,若存在则去校验用户信息,否则以此用户名创建新用户,密码随机生成
- 将校验结果或者创建信息返回给微信小程序端
- 根据返回的信息完成用户登录校验
django的用户权限认证
django有一套自己的完善用户模型,由于DjangoAuth自带的User模型字段有限,我们需要对其进行拓展(直接使用也可以)
nickname=models.CharField(verbose_name=u'昵称',max_length=50,blank=True) user_avatar=models.ImageField(verbose_name=u'用户头像',upload_to='image/%Y/%m/%d',default=u'image/default.png',max_length=500) user_email=models.EmailField(verbose_name=u'用户邮箱',max_length=254) user_phone=models.BigIntegerField(verbose_name=u'手机号',null=True,blank=True) user_birthday=models.DateField(verbose_name=u'出生日期',default=timezone.now) user_sex=models.CharField(verbose_name=u'性别',max_length=6,choices=(('male','男'),('female','女')),default='male') user_address=models.CharField(verbose_name=u'地址',max_length=550,blank=True,null=True) signature=models.CharField(verbose_name=u'个性签名',max_length=550,blank=True,null=True)
用户接口序列化
fromrest_frameworkimportserializers classUserSerializer(serializers.ModelSerializer): classMeta: model=User fields="__all__"
登陆接口设计
classUserLogin(APIView): defpost(self,request): params=request.data userName=get_openid(params.get('code')) userInfo=params.get('userinfo') try: user=User.objects.get(username=userName) exceptExceptionase: user=None ifuser: #更新用户信息 user=User.objects.get(username=userName) else: #注册新用户 user=User.objects.create_user(username=userName,password=random_str(10)) #手动生成JWT #手动生成token验证 jwt_payload_handler=api_settings.JWT_PAYLOAD_HANDLER jwt_encode_handler=api_settings.JWT_ENCODE_HANDLER payload=jwt_payload_handler(user) token=jwt_encode_handler(payload) ret={'code':'00000','msg':None,'data':{}} ret['msg']='授权成功' ret['data']={ 'token':token, 'user_id':user.id, 'nickname':user.nickname } returnJsonResponse(ret)
解析code获取openid
classOpenidUtils(object): def__init__(self,jscode): self.url="https://api.weixin.qq.com/sns/jscode2session" self.appid=APPID self.secret=SECRET self.jscode=jscode#前端传回的动态jscode defget_openid(self): url=self.url+"?appid="+self.appid+"&secret="+self.secret+"&js_code="+self.jscode+"&grant_type=authorization_code" r=requests.get(url) openid=r.json()['openid'] returnopenid
小程序的登陆验证
具体登录流程可以查阅官方文档。
functiongetWXUserInfo(){ constlogin=promisify(wx.login); constgetUserInfo=promisify(wx.getUserInfo); returnnewPromise(function(resolve,reject){ _wxLogin(); function_wxLogin(){ login().then(function(res){ getUserInfo().then(function(r){ letuserInfo=r; userInfo.code=res.code; try{ wx.setStorageSync('userInfo',userInfo); }catch(e){ console.log(e) } if(userInfo&&userInfo.code&&userInfo.iv){ resolve(userInfo); } else{ reject('wxloginfail'); } }).catch(function(error){ reject(error); }); }).catch(function(error){ reject(error); }); } }); } //登录接口验证 getWXUserInfo().then(function(data){ varresult={ code:0, data:{} }; varparams={ 'code':data.code, 'userinfo':data.userInfo } wx.request({ url:'/api/login', data:params, dataType:'json', method:'POST', success:function(response){ //返回成功 if(response.data&&response.data.code=='00000'){ try{ varresData={ custNo:data.user_id, nickname:data.nickname }; result.code=0; result.data=resData; resolve(result); } catch(e){ console.warn(result) //登录失败 result.code=2; resolve(result); } } else{ //获取customNum失败 console.warn(result) result.code=1; result.data='getcustomNumfail'; resolve(result); } } }) }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。