carcabot / tiktok-signature

Generate tiktok signature token using node
733 stars 283 forks source link

How to obtain the secUID from a Username #167

Closed Huertas97 closed 1 year ago

Huertas97 commented 1 year ago

Describe the bug The link provided to obtain a secUID from a user in examples/user-video.js is not working. This file says:

// Get your SEC_UID from https://t.tiktok.com/api/user/detail/?aid=1988&uniqueId=username&language=it // where username is your TikTok username.

However, this link do not retrieve any information.

Playing around I could get some info using a variant from the link above:

https://t.tiktok.com/api/user/detail/?uniqueId=username

For example for Taylor Swift account: https://t.tiktok.com/api/user/detail/?uniqueId=taylorswift You should get something like this:

{
  "extra": {
    "fatal_item_ids": [],
    "logid": "202211021348580102440870850322C9FA",
    "now": 1667396938000
  },
  "log_pb": {
    "impr_id": "202211021348580102440870850322C9FA"
  },
  "statusCode": 0,
  "status_code": 0,
  "userInfo": {
    "stats": {
      "diggCount": 0,
      "followerCount": 0,
      "followingCount": 0,
      "heart": 0,
      "heartCount": 0,
      "videoCount": 0
    },
    "user": {
      "avatarLarger": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/7158330802453872645~c5_1080x1080.jpeg?x-expires=1667566800&x-signature=g%2FUhlXSzFpaVJxSSK7pYmb6HwnA%3D",
      "avatarMedium": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/7158330802453872645~c5_720x720.jpeg?x-expires=1667566800&x-signature=r1P5hohUxMg9Y8%2FIZlgXmNvqL%2Bc%3D",
      "avatarThumb": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/7158330802453872645~c5_100x100.jpeg?x-expires=1667566800&x-signature=FgzWBm3E24W%2BNK1nPaU2KZPvouU%3D",
      "commerceUserInfo": {
        "commerceUser": false
      },
      "followingVisibility": 1,
      "ftc": false,
      "id": "7158290640144974853",
      "isADVirtual": false,
      "isUnderAge18": false,
      "nickNameModifyTime": 0,
      "nickname": "researchupm",
      "openFavorite": false,
      "privateAccount": false,
      "profileTab": {
        "showPlayListTab": false
      },
      "relation": 0,
      "secUid": "MS4wLjABAAAA58SAnVIeB46UlfX0kYFI9YdnEo3cMWCye7G8JyuDuUGuXj9IehSlD_mV8zjU8Fea",
      "secret": false,
      "signature": "",
      "ttSeller": false,
      "uniqueId": "researchupm",
      "uniqueIdModifyTime": 0,
      "verified": false
    }
  }
}

From the JSON like result obtained from the URL you can acces the secUid field nested inside userInfo > user. Perhaps this helps with #164

To Reproduce Steps to reproduce the behavior:

Huertas97 commented 1 year ago

Well, this only seems to work when I use the browser I am logged into TikTok in. For example, if I log out of my TikTok account and try to use the link shown above (https://t.tiktok.com/api/user/detail/?uniqueId=taylorswift) no information is displayed. The same thing happens when I switch browsers, only the browser I am logged in to shows the user information from the link. When I am not logged in I obtain:

{"userInfo": {"user": {},"stats": {},"shareMeta": {}}}

Also, I have tried to use the signed_url given by the tiktok-signature package as shown below trying to mimic the situation where I am using a browser where I am already logged in:

node browser.js "https://t.tiktok.com/api/user/detail/?uniqueId=taylorswift"

Output looks like this:

{
  "status": "ok",
  "data": {
    "signature": "_02B4Z6wo00f01oe0SvAAAIBBWimlxi878t6HpE5AAMKb38",
    "verify_fp": "verify_5b161567bda98b6a50c0414d99909d4b",
    "signed_url": "https://t.tiktok.com/api/user/detail/?uniqueId=taylorswift&verifyFp=verify_5b161567bda98b6a50c0414d99909d4b&_signature=_02B4Z6wo00f01oe0SvAAAIBBWimlxi878t6HpE5AAMKb38&X-Bogus=DFSzswSOKSbANVRUS02//dOZaxRG",
    "x-tt-params": "oqaILuQCqyTxGLFqfaqkkWOA/Ew7wmC9WUbkgJh/q86EYkvT+gGj9nhk6CvqgQw1pa1yiGXb8otkGYwfcv6z+2MAhyTuvaeaAghz+hkdDgsmfEymZUl11DuHCH8J65zlc5TAZu25SyZubVuD9BxsVyNQgV/yo32NaMGi31hvpTsk+BwvWFlR4308mQxY5hy+FlRgluZeoA4w9z1xkg61vQ==",
    "x-bogus": "DFSzswSOKSbANVRUS02//dOZaxRG",
    "navigator": {
      "deviceScaleFactor": 3,
      "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36",
      "browser_language": "en-US",
      "browser_platform": "Win32",
      "browser_name": "Mozilla",
      "browser_version": "5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36"
    }
  }
}

Then, I have tried to access using requests from python (d variable is the dictionary from cell above).

import requests
r=requests.get(d["data"]["signed_url"], 
               headers={
                   "Content-Type":"text",
                   "user-agent": d["data"]["navigator"]["user_agent"],
                   "x-tt-params": d["data"]['x-tt-params'],
                   }
               )
print(r.text)

Output looks like this:

{
    statusCode: -1,
    userInfo: {}
}

Overall it seems that the signature URL should mimic the proccess of being logged and retrieve information from the link but it doesn't.

codertapsu commented 1 year ago

I am facing this issue too, do we have any solution guys?

lihuelworks commented 1 year ago

Same thing, I don't get how to do it.

greysonn commented 7 months ago

You must sign the request to the /api/user/detail request for it to resolve the SECID

Still working as of now.

singhera-ilmiya commented 7 months ago

Response is not coming Empty details

On Mon, Feb 5, 2024 at 8:40 AM greyson @.***> wrote:

You must sign the request to the /api/user/detail request for it to resolve the SECID

Still working as of now.

— Reply to this email directly, view it on GitHub https://github.com/carcabot/tiktok-signature/issues/167#issuecomment-1926177077, or unsubscribe https://github.com/notifications/unsubscribe-auth/AW7NNCYGN7M3X3D7RHSTBGTYSBICZAVCNFSM6AAAAAARVEBS2CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMRWGE3TOMBXG4 . You are receiving this because you are subscribed to this thread.Message ID: @.***>

trungtin commented 7 months ago

You must sign the request to the /api/user/detail request for it to resolve the SECID

Still working as of now.

I must be missing something. Signed it like this:

https://t.tiktok.com/api/user/detail/?aid=1988&uniqueId=rihanna&language=it&verifyFp=verify_5b161567bda98b6a50c0414d99909d4b&_signature=_02B4Z6wo00f01QZgxEgAAIBCf8SLn3aN1PEGYMDAACRdf1&X-Bogus=DFSzswSLFOtANVmttqRPS09WcBJP

But the response is still empty.

alanfranciscobr commented 5 months ago

One solution I found was: (unfortunately it is only possible via browser or a good alternative "playwright")

In the browser when the page is requested https://www.tiktok.com/@usuarioalvo it returns the page to be displayed in the browser, but inside the page's html contains user data in a tag

<script id="__UNIVERSAL_DATA_FOR_REHYDRATION__">{json with content}</script>

contains the most important information for the rest of the requests: id, secUID

more practical example:

from playwright.sync_api import sync_playwright

class TikTokUserNotFoundError(Exception):
    def __init__(self, message):
        self.message = message
        super().__init__(message)

class TikTokUser:
    def __init__(self, username) -> None:
        self.username = username

    def __str__(self) -> str:
        return f'TikTokUser(id={self.id}, secUid={self.secUid}, username={self.username})'

    def get_info(self):
        with sync_playwright() as playw:
            with playw.chromium.launch() as browser:
                page = browser.new_page()
                page.goto(f'https://www.tiktok.com/@{self.username}')

                userinfo_text = page.query_selector('#__UNIVERSAL_DATA_FOR_REHYDRATION__').inner_text()

        userinfo_json = json.loads(userinfo_text)['__DEFAULT_SCOPE__']['webapp.user-detail'] 
        print(userinfo_json) # imprima se quiser todos os detalhes

        if userinfo_json['statusCode'] in [0, 10222]:
            userinfo = userinfo_json['userInfo']
            self.id = userinfo['user']['id']
            self.username = userinfo['user']['uniqueId']
            self.avatarThumb = userinfo['user']['avatarThumb']
            self.secUid = userinfo['user']['secUid']
            self.privateAccount = userinfo['user']['privateAccount']
            self.description = userinfo['user']['signature']
            self.mediaCount = userinfo['stats']['videoCount']
            self.url_picture = userinfo['user']['avatarThumb']
            self.picture = '/profiles/static/images/tiktok/' + self.username

        elif userinfo_json['statusCode'] == 10221:
            raise TikTokUserNotFoundError('user not found')

tiktokuser = TikTokUser('target_user123')
tiktokuser.get_info()
print(tiktokuser)