IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Uni-id-co 外部系统联登

    obaby发表于 2024-03-12 02:06:32
    love 0

    uni-id 是 uniapp 自带的一套用户用户体系,按照官方文档的说法,具有颇多优势。目前闺蜜圈项目是自建用户体系,但是为了后续的功能规划,可能需要用到 uni-id 的账号体系,所以提前进行了相关可行性测试。

    99%的应用,都要开发用户注册、登录、发送短信验证码、修改密码、密码加密保存、密码防探测、token管理、页面访问权限、注册用户统计等众多功能,从前端到后端都需要。

    为什么不能有一个开源的通用项目,避免大家的重复开发呢?

    uni-id应需而生。

    uni-id为uniCloud开发者提供了开源、易用、安全、丰富、可扩展的用户管理框架。

    clientDB、DB Schema、uni-starter、uni-admin,这些产品都基于uni-id的账户体系。可以说uni-id是uniCloud不可或缺的基础能力。

    同时针对已经有账号体系的系统提供了接口,实现数据互通:https://doc.dcloud.net.cn/uniCloud/uni-id/cloud-object.html#external-register

    本身就提供了三个接口,没有查询用户信息的功能,按照官网文档实现数据对接也比较容易,不过需要注意的是,文档里面有些内容没有写清楚。

    校验算法代码:

    import hmac
    import hashlib
    import time
    
    # https://doc.dcloud.net.cn/uniCloud/uni-id/cloud-object.html#http-reqeust-auth
    class Sign:
        def __init__(self, requestAuthSecret):
            self.requestAuthSecret = requestAuthSecret
    
        def get_signature(self, params, nonce, timestamp):
            params_str = self.get_params_string(params)
            signature = hmac.new(bytes("%s%s" % (self.requestAuthSecret, nonce), 'utf-8'),
                                 bytes("%s%s" % (timestamp, params_str), 'utf-8'),
                                 digestmod=hashlib.sha256).hexdigest().upper()
    
            return signature
    
        def get_params_string(self, params):
            params_str = []
            for k in sorted(params):
                if isinstance(params[k], (list, dict)):
                    continue
                params_str.append("%s=%s" % (k, params[k]))
    
            return "&".join(params_str)
    
    
    if __name__ == "__main__":
        requestAuthSecret = "testSecret"
        nonce = "xxxxxxx"
        timestamp = int(round(time.time() * 1000))
    
        params = {
            "foo": 1,
            "bar": 2,
            "foobar": 4,
            "foo_bar": 3,
        }
    
        sign = Sign(requestAuthSecret)
        signature = sign.get_signature(params, nonce, timestamp)
    
        print(nonce, timestamp, signature)

    对应三个接口的代码封装:

    import datetime
    import json
    import random
    import string
    import requests
    import asyncio
    import traceback
    import time
    
    from reminder.utils.string_util import random_str
    from reminder.utils.uni_sign import Sign as UniSign
    
    requestAuthSecret = 'mysecret' #需要去uniadmin配置文件中设置
    sign = UniSign(requestAuthSecret)
    
    # https://doc.dcloud.net.cn/uniCloud/uni-id/cloud-object.html#external-register
    '''
    uni-id-nonce	string	是	随机字符串
    uni-id-timestamp	string	是	当前时间戳; 单位毫秒
    uni-id-signature	string	是	请求鉴权签名; 签名算法见下
    POST /your-uni-id-co-path/externalRegister HTTP/1.1
    Host: xxx.com
    uni-id-nonce: xxxxxxx
    uni-id-timestamp: 1676882808550
    uni-id-signature: 11c965267a4a02c6978949c7135215b0a75aea22b2b84ed491e792365c8269efa
    Content-Type: application/json
    Cache-Control: no-cache
    
    {"externalUid": "test externalUid", "nickname": "张三", "avatar": "xxxxxxx", "gender": 0}
    externalUid	string	是	自身系统的用户id,必须保证唯一性。
    nickname	string	否	用户昵称
    avatar	string	否	用户头像
    gender	number	否	用户性别;0 未知 1 男性 2 女性
    '''
    
    
    def external_register(external_uid, nickname, avatar, gender):
        body = {
            'externalUid': str(external_uid),
            'nickname': nickname,
            # 'avatar':'',
            # 'gender':''
        }
        timestamp = int(round(time.time() * 1000))
        nonce = random_str(16)
        headers = {
            'Content-Type': 'application/json',
            'Cache-Control': 'no-cache',
            'uni-id-nonce': nonce,
            'uni-id-timestamp': str(timestamp),
            'uni-id-signature': sign.get_signature(body, nonce, timestamp)
        }
        print(body)
    
        req_body = {
            "clientInfo": {'uniPlatform': 'app',
                           'appId': '__UNI__*******'},
            "params": body
        }
    
        resp = requests.post("https://c******/uni-id-co/externalRegister", json=req_body, headers=headers) # 需要将云函数url化
        print('Reg Resp:', resp.text)
        return resp.text
    
    
    '''
    参数名	类型	必填	说明
    uid	string	否	uni-id体系的用户Id;与externalUid 二选一
    externalUid	string	否	自身系统的用户id;与 uid 二选一
    '''
    
    
    def external_login(uid, external_uid):
        body = {
            # 'uid':str(uid),
            'externalUid': str(external_uid),
            # 'nickname': nickname,
            # 'avatar':'',
            # 'gender':''
        }
        timestamp = int(round(time.time() * 1000))
        nonce = random_str(16)
        headers = {
            'Content-Type': 'application/json',
            'Cache-Control': 'no-cache',
            'uni-id-nonce': nonce,
            'uni-id-timestamp': str(timestamp),
            'uni-id-signature': sign.get_signature(body, nonce, timestamp)
        }
        print(body)
    
        req_body = {
            "clientInfo": {'uniPlatform': 'app',
                           'appId': '__UNI__E*******'},
            "params": body
        }
    
        resp = requests.post("https://c*******/uni-id-co/externalLogin", json=req_body, headers=headers)
        print('Reg Resp:', resp.text)
        return resp.text
    
    
    '''
    uid	string	否	uni-id体系的用户Id;与externalUid 二选一
    externalUid	string	否	自身系统的用户id;与 uid 二选一
    username	string	否	用户名
    password	string	否	密码
    nickname	string	否	昵称
    authorizedApp	Array<string>	否	允许登录的app列表
    role	Array<string>	否	用户角色
    mobile	string	否	手机号
    email	string	否	邮箱
    tags	array	否	用户标签
    status	number	否	用户状态,参考:用户状态
    avatar	string	否	用户头像
    gender	number	否	用户性别;0 未知 1 男性 2 女性
    '''
    def external_update(uid, external_uid, username, password, nickname, mobile, email, status,
                        avatar, gender):
        body = {
            # 'uid':str(uid),
            'externalUid': str(external_uid),
            # # 'nickname': nickname,
            # # 'avatar':'',
            # # 'gender':''
            # 'username': username,
            # 'password': password,
            # 'nickname': nickname,
            # # 'authorizedApp': authorizedApp,
            # # 'role': role,
            # 'mobile': mobile,
            # 'email': email,
            # # 'tags': tags,
            # 'status': status,
            # 'avatar': avatar,
            # 'gender': gender,
        }
        if username and username != '':
            body['username'] = username
        if nickname and nickname != '':
            body['nickname'] = nickname
        if password and password != '':
            body['password'] = password
        if mobile and mobile != '':
            body['mobile'] = mobile
        if email and email != '':
            body['email'] = email
        if status and status != '':
            body['status'] = status
        if avatar and avatar != '':
            body['avatar'] = avatar
        if gender and gender != '':
            body['gender'] = gender
    
        timestamp = int(round(time.time() * 1000))
        nonce = random_str(16)
        headers = {
            'Content-Type': 'application/json',
            'Cache-Control': 'no-cache',
            'uni-id-nonce': nonce,
            'uni-id-timestamp': str(timestamp),
            'uni-id-signature': sign.get_signature(body, nonce, timestamp)
        }
        print(body)
    
        req_body = {
            "clientInfo": {'uniPlatform': 'app',
                           'appId': '__UNI__E*******'},
            "params": body
        }
    
        resp = requests.post("https://c*******/uni-id-co/updateUserInfoByExternal", json=req_body, headers=headers)
        print('Reg Resp:', resp.text)
        return resp.text
    
    
    
    if __name__ == "__main__":
        print('uni rest request')
        # external_register('17', 'test', '', '')
        # external_login('', '17')
        # external_update('', '17','test','','','','','','', '')
    
    

    post body需要是下面的格式:

    req_body = {
        "clientInfo": {'uniPlatform': 'app',
                       'appId': '__UNI__E8*******'},
        "params": body
    }

    上述内容在文档中没有说明,需要自己添加clientInfo以及对应的字段。

     

    The post Uni-id-co 外部系统联登 first appeared on obaby@mars.



沪ICP备19023445号-2号
友情链接