python

超轻量级php框架startmvc

django与小程序实现登录验证功能的示例代码

更新时间:2020-06-25 03:00 作者:startmvc
之前用小程序做项目,因为后台使用的java开发,一切顺利,但切换成django做RESTfulAPI接口时

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

具体流程

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

django的用户权限认证

django有一套自己的完善用户模型,由于Django Auth自带的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)

用户接口序列化


from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
class Meta:
 model = User
 fields = "__all__"

登陆接口设计


class UserLogin(APIView):
 def post(self,request):
 params = request.data
 userName = get_openid(params.get('code'))
 userInfo = params.get('userinfo')
 try:
 user = User.objects.get(username = userName)
 except Exception as e:
 user = None
 if user:
 # 更新用户信息
 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
 }
 return JsonResponse(ret)

解析code获取openid


class OpenidUtils(object):
 def __init__(self, jscode):
 self.url = "https://api.weixin.qq.com/sns/jscode2session"
 self.appid = APPID
 self.secret = SECRET
 self.jscode = jscode # 前端传回的动态jscode

 def get_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']
 return openid

小程序的登陆验证

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


function getWXUserInfo() {
 const login = promisify(wx.login);
 const getUserInfo = promisify(wx.getUserInfo);

 return new Promise(function (resolve, reject) {
 _wxLogin();
 function _wxLogin() {
 login().then(function (res) {
 getUserInfo().then(function (r) {
 let userInfo = 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('wx login fail');
 }
 }).catch(function (error) {
 reject(error);
 });
 }).catch(function (error) {
 reject(error);
 });
 }
 });
}

//登录接口验证
getWXUserInfo().then(function (data) {
 var result = {
 code: 0,
 data: {}
 };
 var params = {
 '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 {
 var resData = {
 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 = 'get customNum fail';
 resolve(result);
 }
 }
 })
}

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