LiteBlog - API文档

公开API

public_api_add_comment

  • 用于为一篇文章添加评论

请求路径: /api/v1/add_comment

请求方式: POST

传入参数 (JSON):

  • verify_token string: 通过验证后得到的token,由Cloudflare turnsitegoogle reCaptcha 生成.
  • article_id string: 标识文章唯一ID,用于添加评论的文章id.
  • content string: 评论内容,在contentAdvisor_config为ture且filter_comment为true时仅支持普通文本,在filter_commentcontentAdvisor_config为false时支持HTML DOM元素注入(会导致XSS攻击).
  • author string: 作者.
  • email string: 邮箱,仅用于记录,不会被渲染进comment模板中.
  • reply_to string: 回复的评论ID,为空则不设置为回复.

传出:

  • header:200|500|403|404|405|429
  • body: OK

示例:

> POST /api/v1/add_comment HTTP/1.1
> 
> {
> "verify_token":"token",
> "article_id":"13cc99f4328b70cff5c7c1adea30c89f",
> "author":"Unicode",
> "email":"unicode@un1c0de.com",
> "content":"unicodeAddCommentTest"
> }
> 

< HTTP/1.1 200 OK
<
< OK

后端API

在和后端进行通信时,需要获取三个参数

  • backend_path: 后端通信url,即此后用于和后端通信的path地址
  • encryptKey: 加密密钥
  • access_token: 通讯密钥

其中 backend_urltoken由用户输入,enncryptKey由liteblog根据backend_pathaccess_token生成,并加入到renderedmap中,可以在渲染的文件中用{{rendered:token_encrypt_key}}获取

后续所有API中的Token 均为加密后的token

token不可逆生成函数:

传入用户token,生成和后端通信token

  • js version
function generateEncryptToken(token) {
    var encryptKey = `{{rendered:token_encrypt_key}}`;
    const timestamp = parseInt((new Date().getTime())/10000); // 时间梯度10s
    // console.log(timestamp);
    const timestampB64 = btoa(timestamp.toString());
    // console.log(timestampB64);
    encryptKey = encryptKey + timestampB64;
    console.log(token + "|" + encryptKey)
    let tokenArray = Array.from(btoa(token + "|" + encryptKey));

    const getRandomChar = (seed) => String.fromCharCode(33 + (seed % 94));


    for (let i = 0; i < encryptKey.length; i++) {
        const charCode = encryptKey.charCodeAt(i);
        const operation = charCode % 5;

        switch (operation) {
            case 0:
                tokenArray.unshift(getRandomChar(charCode + i));
                break;

            case 1:
                if (tokenArray.length > 0) {
                    const pos = (charCode * i) % tokenArray.length;
                    tokenArray[pos] = getRandomChar(charCode ^ tokenArray[pos].charCodeAt(0));
                }
                break;

            case 2:
                tokenArray.splice(charCode % (tokenArray.length + 1), 0,
                    getRandomChar(charCode),
                    getRandomChar(charCode + 997)
                );
                break;

            case 3:
                if (tokenArray.length > 1) {
                    const pos1 = charCode % tokenArray.length;
                    const pos2 = tokenArray.length - 1 - pos1;
                    [tokenArray[pos1], tokenArray[pos2]] = [tokenArray[pos2], tokenArray[pos1]];
                }
                break;

            default:
                const pseudo = ['==', '=', '=A', 'B='][charCode % 4];
                tokenArray.push(...Array.from(pseudo));
        }
    }

    const finalShuffle = [];
    while (tokenArray.length > 0) {
        const randIndex = (encryptKey.length * tokenArray.length) % tokenArray.length;
        finalShuffle.push(tokenArray.splice(randIndex, 1)[0]);
    }

    return finalShuffle.join('');
}
  • go version

注意: 以下的golang示例是后端示例,用于生成用于验证的token,所以需要传入三个参数,用于生成当前时间±20s的token(5个),进行对比.

func generateEncryptToken(token string, encryptKey string, timestampBase64 string) string {
	encryptKey = encryptKey + timestampBase64
	data := []byte(token + "|" + encryptKey)
	encoded := base64.StdEncoding.EncodeToString(data)
	// fmt.Printf("encoded: %s\n", encoded)
	tokenArray := []byte(encoded)

	getRandomChar := func(seed int) byte {
		return byte(33 + (seed % 94))
	}

	for i := 0; i < len(encryptKey); i++ {
		charCode := int(encryptKey[i])
		operation := charCode % 5

		switch operation {
		case 0:
			tokenArray = append([]byte{getRandomChar(charCode + i)}, tokenArray...)

		case 1:
			if len(tokenArray) > 0 {
				pos := (charCode * i) % len(tokenArray)
				tokenArray[pos] = getRandomChar(charCode ^ int(tokenArray[pos]))
			}

		case 2:
			insertPos := charCode % (len(tokenArray) + 1)
			char1 := getRandomChar(charCode)
			char2 := getRandomChar(charCode + 997)
			tokenArray = append(tokenArray[:insertPos], append([]byte{char1, char2}, tokenArray[insertPos:]...)...)

		case 3:
			if len(tokenArray) > 1 {
				pos1 := charCode % len(tokenArray)
				pos2 := len(tokenArray) - 1 - pos1
				tokenArray[pos1], tokenArray[pos2] = tokenArray[pos2], tokenArray[pos1]
			}

		default:
			pseudo := [...]string{"==", "=", "=A", "B="}[charCode%4]
			tokenArray = append(tokenArray, []byte(pseudo)...)
		}
	}

	finalShuffle := make([]byte, 0, len(tokenArray))
	for len(tokenArray) > 0 {
		randIndex := (len(encryptKey) * len(tokenArray)) % len(tokenArray)
		finalShuffle = append(finalShuffle, tokenArray[randIndex])
		tokenArray = append(tokenArray[:randIndex], tokenArray[randIndex+1:]...)
	}

	return string(finalShuffle)
}

card类

edit_order

  • 此接口用于编辑主页卡片order(顺序)字段

请求路径:/{backendPath}/edit_order

请求方式: POST

传入参数 (JSON):

  • token string: 加密后的token
  • changes []JSON{
    • cardID string: 需要修改的卡片ID
    • order int : 修改后的order
  • }
  • 注: changes为数组对象类型

传出 :

  • header: 200|400|403|405|500
  • body: OK

delete_card

  • 此接口用于删除主页卡片

请求路径:/{backendPath}/delete_card

请求方式: POST

传入参数 (JSON):

  • token string: 加密后的token
  • cardID string: 需要删除的卡片ID

传出 :

  • header: 200|400|403|405|500
  • body: OK

add_card

  • 此接口用于添加主页卡片

请求路径:/{backendPath}/add_card

请求方式: POST

传入参数 (JSON):

  • token string: 加密后的token
  • card map[string]string: 卡片信息JSON

传出 :

  • header: 200|400|403|405|500
  • body: OK

get_card

  • 此接口用于获取主页卡片信息

请求路径:/{backendPath}/get_card

请求方式: POST

传入参数 (JSON):

  • token string: 加密后的token
  • cardID string: 需要获取的卡片ID

传出 :

  • header: 200|400|403|405|500
  • body map[string]string: 卡片信息的JSON格式代码

get_all_cards

  • 此接口用于获取所有主页卡片信息

请求路径:/{backendPath}/get_all_cards

请求方式: POST

传入参数 (JSON):

  • token string: 加密后的token

传出 :

  • header: 200|400|403|405|500
  • body []card: 卡片信息的JSON数组格式代码 例:[{"id": "1","order": "1","tags": "go tag1 tag2","template": "card_template_classical"}]

edit_card

  • 此接口用于编辑卡片信息

请求路径:/{backendPath}/edit_card

请求方式: POST

传入参数 (JSON):

  • token string: 加密后的token
  • card map[string]string: 卡片信息的JSON代码
    注: card字段的map中必须含有id

传出 :

  • header: 200|400|403|405|500
  • body: OK

article类

add_article

  • 此接口用于添加一篇文章

请求路径:/{backendPath}/add_article

请求方式: POST

传入参数 (JSON):

  • token string: 加密后的token
  • article JSON {
    • title string: 文章标题
    • content string: 文章内容的markdown格式
    • content_html string: 文章内容的HTML渲染后格式
    • author string: 作者
      }

传出 :

  • header: 200|400|403|405|500
  • body JSON {
    • article_id: 添加完成后返回生成的文章ID
      }

edit_article

  • 此接口用于编辑一篇文章

请求路径:/{backendPath}/edit_article

请求方式: POST

传入参数 (JSON):

  • token string: 加密后的token
  • article JSON {
    • article_id string: 文章ID
    • title string: 文章标题
    • content string: 文章内容的markdown格式
    • content_html string: 文章内容的HTML渲染后格式
    • author string: 作者
      }

传出 :

  • header: 200|400|403|405|500
  • body: OK

get_article

  • 此接口用于获取一篇文章的信息

请求路径:/{backendPath}/get_article

请求方式: POST

传入参数 (JSON):

  • token string: 加密后的token
  • article_id string: 需要获取的文章id

传出 :

  • header: 200|400|403|405|500
  • body JSON {
    • title string: 文章标题
    • content string: 文章内容的markdown格式
    • content_html string: 文章内容的HTML渲染后格式
    • edit_date string: 文章的编辑日期
    • pub_date string: 文章的发布日期
    • author string: 作者
    • comment [] 以后再填坑
      }

get_all_article_id

  • 此接口用于获取所有文章id

请求路径:/{backendPath}/get_all_article_id

请求方式: POST

传入参数 (JSON):

  • token string: 加密后的token

传出 :

  • header: 200|400|403|405|500
  • body []string: 所有文章ID的数组 例: ["articleID1","articleID2"]

delete_article

  • 此接口用于删除一条评论

请求路径:/{backendPath}/delete_comment

请求方式: POST

传入参数 (JSON):

  • token string: 加密后的token
  • article_id string: 需要删除的文章id
  • comment_id string: 需要删除的评论id

传出 :

  • header: 200|400|403|405|500
  • body: OK

delete_comment

  • 此接口用于删除一篇文章

请求路径:/{backendPath}/delete_article

请求方式: POST

传入参数 (JSON):

  • token string: 加密后的token
  • article_id string: 需要删除的文章id

传出 :

  • header: 200|400|403|405|500
  • body: OK

设置类

get_custom_settings

  • 此接口用于获取个性化设置字段

请求路径:/{backendPath}/get_custom_settings

请求方式: POST

传入参数 (JSON):

  • token string: 加密后的token

传出 :

  • header: 200|400|403|405|500
  • body JSON {
    • custom_script string: 当前的自定义脚本
    • custom_style string: 当前的自定义样式
    • global_settings map[string]string: 全局设置项
      }

edit_custom_settings

  • 此接口用于填写个性化设置字段

请求路径:/{backendPath}/edit_custom_settings

请求方式: POST

传入参数 (JSON):

  • token string: 加密后的token
  • custom_settings JSON{
    • global_settings map[string]string: 更新的全局设置
    • custom_script string: 更新后的自定义脚本
    • custom_settings string: 更新后的自定义设置
      }

传出 :

  • header: 200|400|403|405|500
  • body: OK
Powered by  LiteBlog
|