Эх сурвалжийг харах

添加短信验证码登录功能

tanghongbin 5 жил өмнө
parent
commit
d942b74444

+ 5 - 0
Ansjer/urls.py

@@ -122,6 +122,11 @@ urlpatterns = [
     url(r'^v2/account/logout$', UserController.V2LogoutView.as_view()),
     url(r'^v2/account/logout$', UserController.V2LogoutView.as_view()),
     url(r'^v2/account/login$', UserController.v3LoginView.as_view()),
     url(r'^v2/account/login$', UserController.v3LoginView.as_view()),
     url(r'^v3/account/login$', UserController.v3LoginView.as_view()),
     url(r'^v3/account/login$', UserController.v3LoginView.as_view()),
+
+    # 验证码登录
+    url(r'^account/loginCode$', UserController.loginCodeView.as_view()),
+    url(r'^v3/account/loginByCode$', UserController.v3LoginByCodeView.as_view()),
+
     # 新增
     # 新增
     url(r'^detect/detect_group_push$',DetectController.NotificationView.detect_group_push),
     url(r'^detect/detect_group_push$',DetectController.NotificationView.detect_group_push),
     url(r'^detect/add$', DetectController.PushNotificationView.as_view()),
     url(r'^detect/add$', DetectController.PushNotificationView.as_view()),

+ 188 - 32
Controller/UserController.py

@@ -51,7 +51,7 @@ class authCodeView(TemplateView):
 
 
     @method_decorator(csrf_exempt)
     @method_decorator(csrf_exempt)
     def dispatch(self, *args, **kwargs):
     def dispatch(self, *args, **kwargs):
-		# testtest11111111111111
+        # testtest11111111111111
         return super(authCodeView, self).dispatch(*args, **kwargs)
         return super(authCodeView, self).dispatch(*args, **kwargs)
 
 
     @ratelimit(key='ip', rate='2/m')
     @ratelimit(key='ip', rate='2/m')
@@ -441,7 +441,6 @@ class v3ChangePwdView(TemplateView):
             return response.json(177)
             return response.json(177)
 
 
 
 
-
 class ForgetPwdView(TemplateView):
 class ForgetPwdView(TemplateView):
     '''
     '''
     忘记密码
     忘记密码
@@ -973,7 +972,6 @@ class v2registerView(TemplateView):
             return self.do_login(email_qs, response)
             return self.do_login(email_qs, response)
 
 
 
 
-
 # 验证码注册v3
 # 验证码注册v3
 class v3registerView(TemplateView):
 class v3registerView(TemplateView):
     @method_decorator(csrf_exempt)
     @method_decorator(csrf_exempt)
@@ -1149,7 +1147,6 @@ class v3registerView(TemplateView):
             return self.do_login(email_qs, response)
             return self.do_login(email_qs, response)
 
 
 
 
-
 # 重置密码
 # 重置密码
 # 忘记密码获取验证码v2
 # 忘记密码获取验证码v2
 class v2forgetPwdCodeView(TemplateView):
 class v2forgetPwdCodeView(TemplateView):
@@ -1415,7 +1412,6 @@ class v2resetPwdByCodeView(TemplateView):
         return response.json(0, res)
         return response.json(0, res)
 
 
 
 
-
 # 忘记密码v3
 # 忘记密码v3
 class v3resetPwdByCodeView(TemplateView):
 class v3resetPwdByCodeView(TemplateView):
     @method_decorator(csrf_exempt)
     @method_decorator(csrf_exempt)
@@ -1573,7 +1569,6 @@ class v3resetPwdByCodeView(TemplateView):
         return response.json(0, res)
         return response.json(0, res)
 
 
 
 
-
 # 登录
 # 登录
 class v2LoginView(TemplateView):
 class v2LoginView(TemplateView):
     @method_decorator(csrf_exempt)  # @csrf_exempt
     @method_decorator(csrf_exempt)  # @csrf_exempt
@@ -1673,7 +1668,7 @@ class v2LoginView(TemplateView):
 class v3LoginView(TemplateView):
 class v3LoginView(TemplateView):
     @method_decorator(csrf_exempt)  # @csrf_exempt
     @method_decorator(csrf_exempt)  # @csrf_exempt
     def dispatch(self, *args, **kwargs):
     def dispatch(self, *args, **kwargs):
-        #chong 
+        # chong
         return super(v3LoginView, self).dispatch(*args, **kwargs)
         return super(v3LoginView, self).dispatch(*args, **kwargs)
 
 
     @ratelimit(key='ip', rate='5/m')
     @ratelimit(key='ip', rate='5/m')
@@ -1715,13 +1710,13 @@ class v3LoginView(TemplateView):
                     password = password.decode('utf-8')
                     password = password.decode('utf-8')
                     # 截去第一位,最后一位
                     # 截去第一位,最后一位
                     password = password[1:-1]
                     password = password[1:-1]
-                if i==2:
+                if i == 2:
                     # 第2次先解密
                     # 第2次先解密
                     password = base64.b64decode(password)
                     password = base64.b64decode(password)
                     password = password.decode('utf-8')
                     password = password.decode('utf-8')
                     # 去前2位,后2位
                     # 去前2位,后2位
                     password = password[2:-2]
                     password = password[2:-2]
-                if i==3:
+                if i == 3:
                     # 第3次先解密
                     # 第3次先解密
                     password = base64.b64decode(password)
                     password = base64.b64decode(password)
                     password = password.decode('utf-8')
                     password = password.decode('utf-8')
@@ -1820,7 +1815,7 @@ class InitInfoView(View):
         tz = request_dict.get('tz', '0')
         tz = request_dict.get('tz', '0')
         lang = request_dict.get('lang', '')  # 语言区域
         lang = request_dict.get('lang', '')  # 语言区域
         now_time = int(time.time())
         now_time = int(time.time())
-        if all([token_val, push_type, appBundleId,userID]):
+        if all([token_val, push_type, appBundleId, userID]):
             push_type = int(push_type)
             push_type = int(push_type)
             if push_type == 0:
             if push_type == 0:
                 if appBundleId not in APNS_CONFIG.keys():
                 if appBundleId not in APNS_CONFIG.keys():
@@ -2581,11 +2576,12 @@ class alexaAuthView(TemplateView):
         #     uid_arr.append({'uid': uid_q['UID'], 'nick': uid_q['NickName'], 'password': uid_q['View_Password']})
         #     uid_arr.append({'uid': uid_q['UID'], 'nick': uid_q['NickName'], 'password': uid_q['View_Password']})
         res = {
         res = {
             'userID': userID,
             'userID': userID,
-        #     'uid_arr': uid_arr
+            #     'uid_arr': uid_arr
         }
         }
-        return response.json(0,res)
+        return response.json(0, res)
         # return response.json(0, res)
         # return response.json(0, res)
 
 
+
 class alexaUidView(TemplateView):
 class alexaUidView(TemplateView):
     def post(self, request, *args, **kwargs):
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
@@ -2610,11 +2606,11 @@ class alexaUidView(TemplateView):
             uid_list = []
             uid_list = []
             for uid_q in uid_qs:
             for uid_q in uid_qs:
                 uid_list.append(uid_q['UID'])
                 uid_list.append(uid_q['UID'])
-                uid_arr.append({'uid': uid_q['UID'], 'nick': uid_q['NickName'], 'password': uid_q['View_Password'],})
+                uid_arr.append({'uid': uid_q['UID'], 'nick': uid_q['NickName'], 'password': uid_q['View_Password'], })
             res = {
             res = {
                 'uid_arr': uid_arr
                 'uid_arr': uid_arr
             }
             }
-            return response.json(0,res)
+            return response.json(0, res)
         else:
         else:
             return response.json(107)
             return response.json(107)
 
 
@@ -2627,16 +2623,16 @@ class alexaUidView(TemplateView):
             uid_dict = {}
             uid_dict = {}
             uid_list = []
             uid_list = []
             for uid_q in uid_qs:
             for uid_q in uid_qs:
-                #追加
+                # 追加
                 uid_list.append(uid_q['UID'])
                 uid_list.append(uid_q['UID'])
-                #给uid_q['UID']赋值
+                # 给uid_q['UID']赋值
                 uid_dict[uid_q['UID']] = {'nick': uid_q['NickName'], 'password': uid_q['View_Password']}
                 uid_dict[uid_q['UID']] = {'nick': uid_q['NickName'], 'password': uid_q['View_Password']}
             us_qs = UidSetModel.objects.filter(uid__in=uid_list, is_alexa=2).values('uid', 'region_alexa')
             us_qs = UidSetModel.objects.filter(uid__in=uid_list, is_alexa=2).values('uid', 'region_alexa')
             # uid,password,region的列表
             # uid,password,region的列表
             uid_arr = []
             uid_arr = []
             for us in us_qs:
             for us in us_qs:
                 uid = us['uid']
                 uid = us['uid']
-                #设备alexa区域
+                # 设备alexa区域
                 region_alexa = us['region_alexa']
                 region_alexa = us['region_alexa']
                 if region_alexa == '':
                 if region_alexa == '':
                     region_alexa = "en"
                     region_alexa = "en"
@@ -2651,6 +2647,7 @@ class alexaUidView(TemplateView):
         else:
         else:
             return response.json(107)
             return response.json(107)
 
 
+
 # 登出
 # 登出
 class V2LogoutView(TemplateView):
 class V2LogoutView(TemplateView):
     @method_decorator(csrf_exempt)
     @method_decorator(csrf_exempt)
@@ -2812,14 +2809,14 @@ class Image_Code_RegisterView(TemplateView):
         request_dict = request.GET
         request_dict = request.GET
         return self.validates(request_dict)
         return self.validates(request_dict)
 
 
-    #检测验证码,并注册
-    def validates(self,request_dict):
+    # 检测验证码,并注册
+    def validates(self, request_dict):
         print("__________request_dict:%s" % request_dict)
         print("__________request_dict:%s" % request_dict)
-        userEmail = request_dict.get('userEmail',None)
-        password = request_dict.get('userPwd',None)
-        lang = request_dict.get('lang',None)
-        #前端传进来的uuid
-        imageCodeId = request_dict.get('imageCodeId',None)
+        userEmail = request_dict.get('userEmail', None)
+        password = request_dict.get('userPwd', None)
+        lang = request_dict.get('lang', None)
+        # 前端传进来的uuid
+        imageCodeId = request_dict.get('imageCodeId', None)
         # 页面输入的验证码
         # 页面输入的验证码
         response = ResponseObject(lang)
         response = ResponseObject(lang)
         valid_code = request_dict.get('id_v_code', None)
         valid_code = request_dict.get('id_v_code', None)
@@ -2840,7 +2837,7 @@ class Image_Code_RegisterView(TemplateView):
                     password = base64.b64decode(password)
                     password = base64.b64decode(password)
                     password = password.decode('utf-8')
                     password = password.decode('utf-8')
                     password = password[3:-3]
                     password = password[3:-3]
-            print("password%s"%password)
+            print("password%s" % password)
         except Exception as e:
         except Exception as e:
             return response.json(111)
             return response.json(111)
         try:
         try:
@@ -2857,7 +2854,7 @@ class Image_Code_RegisterView(TemplateView):
                     valid_code = base64.b64decode(valid_code)
                     valid_code = base64.b64decode(valid_code)
                     valid_code = valid_code.decode('utf-8')
                     valid_code = valid_code.decode('utf-8')
                     valid_code = valid_code[3:-3]
                     valid_code = valid_code[3:-3]
-            print("valid_code:%s"%valid_code)
+            print("valid_code:%s" % valid_code)
         except Exception as e:
         except Exception as e:
             return response.json(121)
             return response.json(121)
         if not userEmail:
         if not userEmail:
@@ -2871,16 +2868,16 @@ class Image_Code_RegisterView(TemplateView):
             emailValid = Device_User.objects.filter(userEmail=userEmail)
             emailValid = Device_User.objects.filter(userEmail=userEmail)
             if emailValid:
             if emailValid:
                 return response.json(103)
                 return response.json(103)
-        #根据uuid拼接的key
-        image_code_key = "image_code_%s" %imageCodeId
-        #判断验证码是否过期
+        # 根据uuid拼接的key
+        image_code_key = "image_code_%s" % imageCodeId
+        # 判断验证码是否过期
         if image_code_key is None:
         if image_code_key is None:
             return response.json(120)
             return response.json(120)
         redisObj = RedisObject(db=6)
         redisObj = RedisObject(db=6)
-        #redis里面的验证码
+        # redis里面的验证码
         redis_image_code = redisObj.get_data(key=image_code_key)
         redis_image_code = redisObj.get_data(key=image_code_key)
-        #验证用户输入的验证码和redis中的验证码
-        if valid_code.lower()!=redis_image_code.lower():
+        # 验证用户输入的验证码和redis中的验证码
+        if valid_code.lower() != redis_image_code.lower():
             return response.json(121)
             return response.json(121)
         # 删除redis中的图片验证码,防止用户使用同一个图片验证码验证多次
         # 删除redis中的图片验证码,防止用户使用同一个图片验证码验证多次
         redisObj.del_data(key=image_code_key)
         redisObj.del_data(key=image_code_key)
@@ -3008,4 +3005,163 @@ class UserAppFrequencyView(TemplateView):
                     return response.json(444, 'month')
                     return response.json(444, 'month')
 
 
 
 
+class loginCodeView(View):
+    @method_decorator(csrf_exempt)  # @csrf_exempt
+    def dispatch(self, *args, **kwargs):
+        return super(loginCodeView, self).dispatch(*args, **kwargs)
+
+    @ratelimit(key='ip', rate='2/m')
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        lang = request.POST.get('lang', None)
+        if not lang:
+            lang = request.POST.get('language', None)
+        response = ResponseObject(lang)
+        request_dict = request.POST
+        phone = request_dict.get('phone', None)
+        if phone is not None:
+            was_limited = getattr(request, 'limited', False)
+            if was_limited is True:
+                return response.json(5)
+        return self.validate(request_dict, response)
+
+    @ratelimit(key='ip', rate='2/m')
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        lang = request.GET.get('lang', None)
+        if not lang:
+            lang = request.GET.get('language', None)
+        response = ResponseObject(lang)
+        was_limited = getattr(request, 'limited', False)
+        if was_limited is True:
+            return response.json(5)
+        request_dict = request.GET
+        return self.validate(request_dict, response)
+
+    def validate(self, request_dict, response):
+        phone = request_dict.get('phone', None)
+        country_code = request_dict.get('country_code', None)
+        sign_name = request_dict.get('sign_name', None)
+
+        if phone and sign_name:
+            du_qs = Device_User.objects.filter(username=phone)
+            if not du_qs.exists():
+                return response.json(104)
+            else:
+                redisObject = RedisObject()
+                login_code_key = '{phone}_login_code'.format(phone=phone)
+                login_code = redisObject.get_data(key=login_code_key)
+                login_code_ttl = redisObject.get_ttl(key=login_code_key)
+                if login_code_ttl > 240 and login_code:
+                    return response.json(90)
+                login_code = RandomStr(6, True)
+                aliSms = AliSmsObject()
+                if sign_name == 'zosi':
+                    sign_sms = '周视'
+                else:
+                    sign_sms = 'Ansjer'
+
+                res = aliSms.send_code_sms(phone=phone, code=login_code, sign_name=sign_sms, temp_msg='SMS_151600991')
+
+                if res['Code'] == 'OK':
+                    if redisObject.set_data(key=login_code_key, val=login_code, expire=300) is not True:
+                        return response.json(48)
+                    return response.json(0)
+                else:
+                    return response.json(10, res['Message'])
+        else:
+            return response.json(444)
+
+
+class v3LoginByCodeView(View):
+    @method_decorator(csrf_exempt)  # @csrf_exempt
+    def dispatch(self, *args, **kwargs):
+        return super(v3LoginByCodeView, self).dispatch(*args, **kwargs)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        lang = request.POST.get('lang', None)
+        if not lang:
+            lang = request.POST.get('language', None)
+        response = ResponseObject(lang)
+        request_dict = request.POST
+        phone = request_dict.get('phone', None)
+        if phone is not None:
+            was_limited = getattr(request, 'limited', False)
+            if was_limited is True:
+                return response.json(5)
+        return self.validate(request_dict, response)
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        lang = request.GET.get('lang', None)
+        if not lang:
+            lang = request.GET.get('language', None)
+        response = ResponseObject(lang)
+        was_limited = getattr(request, 'limited', False)
+        if was_limited is True:
+            return response.json(5)
+        request_dict = request.GET
+        return self.validate(request_dict, response)
 
 
+    def validate(self, request_dict, response):
+        phone = request_dict.get('phone', None)
+        code = request_dict.get('code', None)
+
+        if phone and code:
+            redisObject = RedisObject()
+            login_code_key = '{phone}_login_code'.format(phone=phone)
+            login_code = redisObject.get_data(key=login_code_key)
+
+            if login_code is not False:
+                print(code)
+                code = CommonService.decode_data(code)
+                print(code)
+                if login_code == code:
+                    if response.lang is None:
+                        response.lang = 'en'
+                    return self.do_phone_login(phone, response)
+                else:
+                    return response.json(121)
+            else:
+                return response.json(120)
+
+    def do_phone_login(self, phone, response):
+        user_qs = Device_User.objects.filter(Q(phone=phone) | Q(username=phone), is_active=True,
+                                             user_isValid=True)
+        return self.valid_login(user_qs, response)
+
+    def valid_login(self, user_qs, response):
+        if not user_qs.exists():
+            return response.json(104)
+        # users = user_qs.values('role__rid', 'role__roleName', 'userID', 'role', 'NickName', 'username', 'userEmail',
+        #                        'phone', 'password', 'userIconPath', 'user_isValid', 'is_active')[0]
+        users = user_qs.values('role__rid', 'role__roleName', 'userID', 'NickName', 'username', 'userEmail',
+                               'phone', 'password', 'userIconPath')[0]
+
+        userID = users['userID']
+        tko = TokenObject()
+        res = tko.generate(
+            data={'userID': userID, 'lang': response.lang, 'user': users['username'],
+                  'm_code': '123413243214'})
+        if tko.code == 0:
+            now_time = datetime.datetime.utcnow().replace(tzinfo=utc).astimezone(utc)
+            user_qs.update(last_login=now_time, language=response.lang)
+            res['rid'] = users['role__rid']
+            res['roleName'] = users['role__roleName']
+            res['permList'] = ModelService.own_permission(userID)
+            res['userID'] = userID
+            # 昵称,邮箱,电话,刷新,头像
+            userIconPath = str(users['userIconPath'])
+            if userIconPath and userIconPath.find('static/') != -1:
+                userIconPath = userIconPath.replace('static/', '').replace('\\', '/')
+                res['userIconUrl'] = SERVER_DOMAIN + 'account/getAvatar/' + userIconPath
+            else:
+                res['userIconUrl'] = ''
+            res['NickName'] = users['NickName'] if users['NickName'] is not None else ''
+            res['username'] = users['username'] if users['username'] is not None else ''
+            res['userEmail'] = users['userEmail'] if users['userEmail'] is not None else ''
+            res['phone'] = users['phone'] if users['phone'] is not None else ''
+            return response.json(0, res)
+        else:
+            return response.json(tko.code)

+ 24 - 1
Service/CommonService.py

@@ -1,4 +1,5 @@
 # -*- coding: utf-8 -*-
 # -*- coding: utf-8 -*-
+import base64
 import datetime
 import datetime
 import time
 import time
 from pathlib import Path
 from pathlib import Path
@@ -221,4 +222,26 @@ class CommonService:
         random = Random()
         random = Random()
         for index in range(randomlength):
         for index in range(randomlength):
             str += characterSet[random.randint(0, length)]
             str += characterSet[random.randint(0, length)]
-        return str
+        return str
+
+    @staticmethod
+    def decode_data(content):
+        try:
+            for i in range(1, 4):
+                if i == 1:
+                    content = base64.b64decode(content)
+                    content = content.decode('utf-8')
+                    content = content[1:-1]
+                if i == 2:
+                    content = base64.b64decode(content)
+                    content = content.decode('utf-8')
+                    content = content[2:-2]
+                if i == 3:
+                    content = base64.b64decode(content)
+                    content = content.decode('utf-8')
+                    content = content[3:-3]
+
+            return content
+        except Exception as e:
+            print(e)
+            return None