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

新增友盟一键登录接口

locky 3 жил өмнө
parent
commit
c6fefd1821

+ 1 - 0
Ansjer/urls.py

@@ -137,6 +137,7 @@ urlpatterns = [
     url(r'^v2/account/logout$', UserController.V2LogoutView.as_view()),
     url(r'^v2/account/login$', UserController.v3LoginView.as_view()),
     url(r'^v3/account/login$', UserController.v3LoginView.as_view()),
+    url(r'^account/oneClickLogin$', UserController.oneClickLoginView.as_view()),
 
     #用户删除/注销
     url(r'^account/delete$', UserController.deleteAccount),

+ 93 - 0
Controller/UserController.py

@@ -48,6 +48,8 @@ from io import BytesIO
 from PIL import Image, ImageDraw, ImageFont
 from django.shortcuts import HttpResponse
 from Ansjer.config import BASE_DIR
+from Object.UVerifyObject import UVerifyObject
+
 
 # 获取验证码
 class authCodeView(TemplateView):
@@ -2004,6 +2006,97 @@ class v3LoginView(TemplateView):
             return response.json(tko.code)
 
 
+# 一键登录接口
+class oneClickLoginView(TemplateView):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        return self.validation(request.GET)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        return self.validation(request.POST)
+
+    def validation(self, request_dict):
+        token = request_dict.get('token', None)
+        language = request_dict.get('language', 'en')
+        response = ResponseObject(language)
+
+        if not token:
+            return response.json(444)
+
+        try:
+            # 友盟一键登录验证
+            UVerify = UVerifyObject(token)
+            verify = UVerify.verify_request()
+            if not verify:
+                return response.json(309)
+            phone = UVerify.phone
+
+            if not phone:
+                return response.json(102)
+
+            user_qs = Device_User.objects.filter(phone=phone).values('userID', 'username', 'NickName', 'phone')
+            # 用户已存在的响应
+            if user_qs.exists():
+                tokenObj = TokenObject()
+                res = tokenObj.generate(
+                    data={
+                        'userID': user_qs[0]['userID'],
+                        'lang': response.lang,
+                        'user': user_qs[0]['username'],
+                        'm_code': '123413243214'
+                    }
+                )
+                if tokenObj.code != 0:
+                    return response.json(tokenObj.code)
+
+                res['userID'] = user_qs[0]['userID']
+                res['username'] = user_qs[0]['username']
+                res['NickName'] = user_qs[0]['NickName']
+                res['phone'] = user_qs[0]['phone']
+                res['userEmail'] = ''
+                res['userIconUrl'] = ''
+                res['subscribe_email'] = ''
+                return response.json(0, res)
+
+            # 新用户
+            userID = CommonService.getUserID(μs=False, setOTAID=True)
+            create_data = {
+                "userID": userID,
+                "username": phone,
+                "NickName": phone,
+                "phone": phone,
+                "is_active": True,
+                "user_isValid": True,
+            }
+            users = Device_User.objects.create(**create_data)
+
+            tokenObj = TokenObject()
+            res = tokenObj.generate(
+                data={
+                    'userID': userID,
+                    'lang': response.lang,
+                    'user': users.username,
+                    'm_code': '123413243214'
+                }
+            )
+            if tokenObj.code != 0:
+                return response.json(tokenObj.code)
+
+            # 组织响应数据
+            res['userID'] = userID
+            res['username'] = users.username
+            res['NickName'] = users.NickName
+            res['phone'] = users.phone
+            res['userEmail'] = ''
+            res['userIconUrl'] = ''
+            res['subscribe_email'] = ''
+            return response.json(0, res)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+
 # 用户登录后初始化接口
 class InitInfoView(View):
 

+ 119 - 0
Object/UVerifyObject.py

@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import base64
+import hashlib
+import hmac
+import json
+import random
+import string
+import time
+import requests
+from datetime import datetime, timedelta
+
+
+class UVerifyObject:
+
+    '''
+    【友盟+】智能认证 U-Verify(一键登录)
+    开发文档:
+    https://developer.umeng.com/docs/143070/detail/144785
+    https://developer.umeng.com/docs/143070/detail/144783
+    '''
+
+    def __init__(self, token):
+        # aliyun config
+        self.ali_appkey = '204024884'
+        self.ali_app_secret = 'lD7AXxc0ji0HzrNXZmfJaz3AecAboItD'
+
+        # umeng config
+        self.host_url = 'https://verify5.market.alicloudapi.com'
+        self.path_url = '/api/v1/mobile/info'
+        self.umeng_app_key = '5d8da0670cafb2a6b5000bc3'
+
+        self.token = token
+        self.phone = ''
+
+        self.body_data_str = json.dumps({'token': self.token})
+        content_md5_str = base64.b64encode(hashlib.md5(self.body_data_str.encode("UTF-8")).digest()).decode("UTF-8")
+
+        now_date_time = datetime.utcnow() + timedelta(hours=8)
+        timestamp = str(int(time.mktime(now_date_time.timetuple()) * 1000))
+
+        sign_headers_dict = {
+            'X-Ca-Key': self.ali_appkey,
+            'X-Ca-Stage': 'RELEASE',
+            'X-Ca-Timestamp': timestamp,
+            'X-Ca-Version': '1'
+        }
+
+        sign_headers_str = ''
+        for key in sorted(sign_headers_dict.keys()):
+            value = sign_headers_dict[key]
+            sign_headers_str = sign_headers_str + key + ':' + value + '\n'
+
+        sign_dict = {
+            'HTTPMethod': 'POST',
+            'Accept': 'application/json',
+            'Content-MD5': content_md5_str,
+            'Content-Type': 'application/json; charset=UTF-8',
+            'Date': None,
+            'Headers': sign_headers_str,
+            'Url': self.path_url + '?' + 'appkey=' + self.umeng_app_key,
+        }
+
+        string_to_sign = ""
+        for key in sign_dict.keys():
+            value = sign_dict[key]
+            if key not in ['Headers', 'Url']:
+                if value:
+                    string_to_sign = string_to_sign + value + "\n"
+                else:
+                    string_to_sign = string_to_sign + "\n"
+            else:
+                string_to_sign = string_to_sign + value
+
+        key_bytes = self.ali_app_secret.encode('utf-8')
+        text_bytes = string_to_sign.encode('utf-8')
+        hash_bytes = hmac.new(key_bytes, text_bytes, hashlib.sha256).digest()
+        signature_str = base64.b64encode(hash_bytes).decode('utf-8')
+
+        nonce_str = self.generate_code(8) + '-' + self.generate_code(4) + '-' + self.generate_code(4) + '-' + \
+                    self.generate_code(4) + '-' + self.generate_code(12)
+
+        self.headers_dict = {
+            'Content-Type': 'application/json; charset=UTF-8',
+            'Accept': 'application/json',
+            'X-Ca-Version': '1',
+            'X-Ca-Signature-Headers': 'X-Ca-Version,X-Ca-Stage,X-Ca-Key,X-Ca-Timestamp',
+            'X-Ca-Stage': 'RELEASE',
+            'X-Ca-Key': self.ali_appkey,
+            'X-Ca-Timestamp': timestamp,
+            'X-Ca-Nonce': nonce_str,
+            'Content-MD5': content_md5_str,
+            'X-Ca-Signature': signature_str
+        }
+
+        self.request_url = self.host_url + self.path_url + '?' + 'appkey=' + self.umeng_app_key
+
+
+    def generate_code(self, length):
+        key = string.digits + 'abcdef'
+        str_list = random.sample(key + key, length)  # length >= len(key+key)
+        result_str = ''.join(str_list)
+        return result_str
+
+    def verify_request(self):
+        response = requests.post(url=self.request_url, data=self.body_data_str.encode("UTF-8"), headers=self.headers_dict)
+        print(response)
+        print(response.headers)
+        print(response.text)
+        # 定义变量防止将字符串转为字典时报错
+        true = 'true'
+        false = 'false'
+        null = 'null'
+        res = eval(response.text)
+        print(res['success'])
+        if res['success'] == 'false':
+            return False
+        self.phone = res['data']['mobile']  # 获取手机号
+        return True