使用摘要签名认证的方式调用CSDN API获取博文评论

本文主要参考了以下文章:

使用摘要签名认证方式调用API - API 网关 - 阿里云 (aliyun.com)

关于CSDN获取博客内容接口的x-ca-signature签名算法研究_Hello_wshuo-CSDN博客

站在巨人的肩膀上,假装自己也很厉害


在实际工作中,经常需要调用网关API获取后台的一些数据进行分析研究,例如,经过调试,得到评论的API接口为:

名称:获取收到的评论
URL:https://bizapi.csdn.net/blog-console-api/v1/comment/list?type=in&page=1&page_size=20
Method:GET

名称:获取发出的评论
URL:https://bizapi.csdn.net/blog-console-api/v1/comment/list?type=out&page=1&page_size=20
Method:GET

同时,在request header中发现有以下字段:

x-ca-key: 203803574
x-ca-nonce: 2e1920c7-21f7-409b-860e-f2e20086dc05
x-ca-signature: h0X+/8/znGBSByA/rtGF/UeATVtdYIvBAlVuLvToPNE=
x-ca-signature-headers: x-ca-key,x-ca-nonce

nonce,signature让人很容易联想到rtsp,sip中也使用了这种认证方式。

因此,通过构造签名的方式实现API接口的调用:

import hashlib
import hmac
import math
import time
import json
from base64 import b64decode,b64encode
import random
import requests
import http.cookiejar as cookielib
from urllib.parse import urlparse
import re

def get_sign(uuid,url):
    s = urlparse(url)
    print(s.query)
    ekey = "9znpamsyl2c7cdrr9sas0le9vbc3r6ba".encode()
    to_enc = f"GET\n*/*\n\n\n\nx-ca-key:203803574\nx-ca-nonce:{uuid}\n{s.path+'?'+s.query}".encode()
    print(to_enc)
    sign = b64encode(hmac.new(ekey, to_enc, digestmod=hashlib.sha256).digest()).decode()
    return sign


def get_comment_out_articles(session):
    comment_articles_list = []
    headers = {}
    page_current = 1
    url_out_base = "https://bizapi.csdn.net/blog-console-api/v1/comment/list?page={page_index}&page_size=20&type=out"
    while True:
        _uu = url_out_base.format(page_index=page_current)
        print(_uu)
        uuid = createUuid()
        sign = get_sign(uuid,_uu)
        headers['x-ca-key'] = "203803574"
        headers['x-ca-nonce'] = uuid
        headers['x-ca-signature'] = sign
        headers['x-ca-signature-headers'] = "x-ca-key,x-ca-nonce"
        response = session.get(_uu,headers=headers)
        #print(headers)
        #print(response.headers)
        if response.status_code != 200:
            break
        random.seed(time.time())
        _tt = random.uniform(random.random() * 2, random.random() * 5)
        print('sleep ' + str(_tt) + 's')
        time.sleep(_tt)

        res = response.json()
        #print(res)
        if {'msg', 'code', 'data'}.issubset(res.keys()) and res['code'] == 200:
            __list = res['data']['list']
            for comment in __list:
                comment_article_id = comment['ArticleId']
                comment_articles_list.append(comment_article_id)
            pages = math.ceil(res['data']['total']/20)
            page_current = page_current + 1
            if page_current > pages:
                break
        else:
            print('response data invalid')
            break

    print(comment_articles_list)
    print(len(comment_articles_list))
    return comment_articles_list

如果请求失败,可以打印response的header进行分析,例如,本文在请求https://bizapi.csdn.net/blog-console-api/v1/comment/list?type=out&page=1&page_size=20接口时,一直返回403,打印后发现有如下信息:
'X-Ca-Error-Message': 'Invalid Signature, Server StringToSign:`GET#*/*####x-ca-key:203803574#x-ca-nonce:e8cfbc95-b29f-4b8e-2148-5ce2bde195a6#/blog-console-api/v1/comment/list?page=1&page_size=20&type=out`'
表示signature错误,并给出需要加密的字符串,#表示'\n',原来加密的源字符串中type=out是要放到后面的。要保证实际加密时使用的字符串和这个严格一致,才能计算出正确的signature

 

相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页