---
title: '分享鏈接身份鑒權'
description: 'ITInfoGPT 分享鏈接身份鑒權'
icon: 'share'
draft: false
toc: true
weight: 860
---

## 介紹

在 ITInfoGPT V4.6.4 中,我們修改了分享鏈接的數據讀取方式,為每個用戶生成一個 localId,用于標識用戶,從云端拉取對話記錄。但是這種方式僅能保障用戶在同一設備同一瀏覽器中使用,如果切換設備或者清空瀏覽器緩存則會丟失這些記錄。這種方式存在一定的風險,因此我們僅允許用戶拉取近`30天`的`20條`記錄。

分享鏈接身份鑒權設計的目的在于,將 ITInfoGPT 的對話框快速、安全的接入到你現有的系統中,僅需 2 個接口即可實現。

## 使用說明

免登錄鏈接配置中,你可以選擇填寫`身份驗證`欄。這是一個`POST`請求的根地址。在填寫該地址后,分享鏈接的初始化、開始對話以及對話結束都會向該地址的特定接口發送一條請求。下面以`host`來表示`憑身份驗證根地址`。服務器接口僅需返回是否校驗成功即可,不需要返回其他數據,格式如下:

### 接口統一響應格式

```json
{
    "success": true,
    "message": "錯誤提示",
    "msg": "同message, 錯誤提示",
    "data": {
        "uid": "用戶唯一憑證"
    }
}
```

`ITInfoGPT` 將會判斷`success`是否為`true`決定是允許用戶繼續操作。`message`與`msg`是等同的,你可以選擇返回其中一個,當`success`不為`true`時,將會提示這個錯誤。

`uid`是用戶的唯一憑證,將會用于拉取對話記錄以及保存對話記錄??蓞⒖枷路綄嵺`案例。

### 觸發流程

![](/imgs/sharelinkProcess.png)

## 配置教程
### 1. 配置身份校驗地址

![](/imgs/share-setlink.png)

配置校驗地址后,在每次分享鏈接使用時,都會向對應的地址發起校驗和上報請求。

{{% alert icon="" %}}
這里僅需配置根地址,無需具體到完整請求路徑。
{{% /alert %}}

### 2. 分享鏈接中增加額外 query

在分享鏈接的地址中,增加一個額外的參數: authToken。例如:

原始的鏈接:`https://share.ITInfoGPT.in/chat/share?shareId=648aaf5ae121349a16d62192`  

完整鏈接: `https://share.ITInfoGPT.in/chat/share?shareId=648aaf5ae121349a16d62192&authToken=userid12345`

這個`authToken`通常是你系統生成的用戶唯一憑證(Token之類的)。ITInfoGPT 會在鑒權接口的`body`中攜帶 token={{authToken}} 的參數。

### 3. 編寫聊天初始化校驗接口

{{< tabs tabTotal="3" >}}
{{< tab tabName="請求示例" >}}
{{< markdownify >}}

```bash
curl --location --request POST '{{host}}/shareAuth/init' \
--header 'Content-Type: application/json' \
--data-raw '{
    "token": "{{authToken}}"
}'
```

{{< /markdownify >}}
{{< /tab >}}

{{< tab tabName="鑒權成功" >}}
{{< markdownify >}}

```json
{
    "success": true,
    "data": {
        "uid": "用戶唯一憑證"
    }
}
```

系統會拉取該分享鏈接下,uid 為 username123 的對話記錄。

{{< /markdownify >}}
{{< /tab >}}

{{< tab tabName="鑒權失敗" >}}
{{< markdownify >}}

```json
{
    "success": false,
    "message": "身份錯誤",
}
```

{{< /markdownify >}}
{{< /tab >}}
{{< /tabs >}}



### 4. 編寫對話前校驗接口

{{< tabs tabTotal="3" >}}
{{< tab tabName="請求示例" >}}
{{< markdownify >}}

```bash
curl --location --request POST '{{host}}/shareAuth/start' \
--header 'Content-Type: application/json' \
--data-raw '{
    "token": "{{authToken}}",
    "question": "用戶問題",
}'
```

{{< /markdownify >}}
{{< /tab >}}

{{< tab tabName="鑒權成功" >}}
{{< markdownify >}}

```json
{
    "success": true,
    "data": {
        "uid": "用戶唯一憑證"
    }
}
```

{{< /markdownify >}}
{{< /tab >}}

{{< tab tabName="鑒權失敗" >}}
{{< markdownify >}}

```json
{
    "success": false,
    "message": "身份驗證失敗",
}
```

```json
{
    "success": false,
    "message": "存在違規詞",
}
```

{{< /markdownify >}}
{{< /tab >}}
{{< /tabs >}}

### 5. 編寫對話結果上報接口(可選)

該接口無規定返回值。

響應值與[chat 接口格式相同](/docs/development/openapi/chat/#響應),僅多了一個`token`。

可以重點關注`responseData`里的`price`值,`price`與實際價格的倍率為`100000`,即 100000=1元。

```bash
curl --location --request POST '{{host}}/shareAuth/finish' \
--header 'Content-Type: application/json' \
--data-raw '{
    "token": "{{authToken}}",
    "responseData": [
        {
            "moduleName": "KB Search",
            "price": 1.2000000000000002,
            "model": "Embedding-2",
            "tokens": 6,
            "similarity": 0.61,
            "limit": 3
        },
        {
            "moduleName": "AI Chat",
            "price": 454.5,
            "model": "FastAI-4k",
            "tokens": 303,
            "question": "導演是誰",
            "answer": "電影《鈴芽之旅》的導演是新海誠。",
            "maxToken": 2050,
            "quoteList": [
                {
                    "dataset_id": "646627f4f7b896cfd8910e38",
                    "id": "8099",
                    "q": "本作的主人公是誰?",
                    "a": "本作的主人公是名叫鈴芽的少女。",
                    "source": "手動修改"
                },
                {
                    "dataset_id": "646627f4f7b896cfd8910e38",
                    "id": "8686",
                    "q": "電影《鈴芽之旅》男主角是誰?",
                    "a": "電影《鈴芽之旅》男主角是宗像草太,由松村北斗配音。",
                    "source": ""
                },
                {
                    "dataset_id": "646627f4f7b896cfd8910e38",
                    "id": "19339",
                    "q": "電影《鈴芽之旅》的導演是誰?22",
                    "a": "電影《鈴芽之旅》的導演是新海誠。",
                    "source": "手動修改"
                }
            ],
            "completeMessages": [
                {
                    "obj": "System",
                    "value": "下面是知識庫內容:\n1. [本作的主人公是誰?\n本作的主人公是名叫鈴芽的少女。]\n2. [電影《鈴芽之旅》男主角是誰?\n電影《鈴芽之旅》男主角是宗像草太,由松村北斗配音。]\n3. [電影《鈴芽之旅》的導演是誰?22\n電影《鈴芽之旅》的導演是新海誠。]\n"
                },
                {
                    "obj": "System",
                    "value": "1.請記住,你的身份是百度的下一代知識增強語言模型,能夠完全根據知識庫提供的內容回答問題。\n\n2. 你忘記了關于電影《鈴芽之旅》以外的內容。"
                },
                {
                    "obj": "System",
                    "value": "你僅回答關于電影《玲芽之旅》的問題,其余問題直接回復: 我不清楚。"
                },
                {
                    "obj": "Human",
                    "value": "導演是誰"
                },
                {
                    "obj": "AI",
                    "value": "電影《鈴芽之旅》的導演是新海誠。"
                }
            ]
        }
    ]
}'
```



## 實踐案例

我們以[Laf作為服務器為例](https://laf.dev/),簡單展示這 3 個接口的使用方式。

### 1. 創建3個Laf接口

![](/imgs/share-auth1.png)



{{< tabs tabTotal="3" >}}
{{< tab tabName="/shareAuth/init" >}}
{{< markdownify >}}

這個接口中,我們設置了`token`必須等于`ITInfoGPT`才能通過校驗。(實際生產中不建議固定寫死)

```ts
import cloud from '@lafjs/cloud'

export default async function (ctx: FunctionContext) {
  const { token } = ctx.body
  // 此處省略 token 解碼過程
  if (token === 'ITInfoGPT') {
    return { success: true,  data: { uid: "user1" } }
  }

  return { success: false,message:"身份錯誤" }
}

```

{{< /markdownify >}}
{{< /tab >}}

{{< tab tabName="/shareAuth/start" >}}
{{< markdownify >}}

這個接口中,我們設置了`token`必須等于`ITInfoGPT`才能通過校驗。并且如果問題中包含了`你`字,則會報錯,用于模擬敏感校驗。

```ts
import cloud from '@lafjs/cloud'

export default async function (ctx: FunctionContext) {
  const { token, question } = ctx.body

  // 此處省略 token 解碼過程
  if (token !== 'ITInfoGPT') {
    return { success: false, message: "身份錯誤" }
  }

  if(question.includes("你")){
    return { success: false, message: "內容不合規" }
  }

  return { success: true, data: { uid: "user1" } }
}

```

{{< /markdownify >}}
{{< /tab >}}

{{< tab tabName="/shareAuth/finish" >}}
{{< markdownify >}}

結果上報接口可自行進行邏輯處理。

```ts
import cloud from '@lafjs/cloud'

export default async function (ctx: FunctionContext) {
  const { token, responseData } = ctx.body
 
  const total = responseData.reduce((sum,item) => sum + item.price,0)
  const amount = total / 100000

  // 省略數據庫操作

  return { }
}
```

{{< /markdownify >}}
{{< /tab >}}
{{< /tabs >}}


### 2. 配置校驗地址

我們隨便復制3個地址中一個接口: `https://d8dns0.laf.dev/shareAuth/finish`, 去除`/shareAuth/finish`后填入`身份校驗`:`https://d8dns0.laf.dev`

![](/imgs/share-auth2.jpg)

### 3. 修改分享鏈接參數

源分享鏈接:`https://share.ITInfoGPT.in/chat/share?shareId=64be36376a438af0311e599c`

修改后:`https://share.ITInfoGPT.in/chat/share?shareId=64be36376a438af0311e599c&authToken=ITInfoGPT`

### 4. 測試效果

1. 打開源鏈接或者`authToken`不等于`ITInfoGPT`的鏈接會提示身份錯誤。
2. 發送內容中包含你字,會提示內容不合規。


## 使用場景

這個鑒權方式通常是幫助你直接嵌入`分享鏈接`到你的應用中,在你的應用打開分享鏈接前,應做`authToken`的拼接后再打開。

除了對接已有系統的用戶外,你還可以對接`余額`功能,通過`結果上報`接口扣除用戶余額,通過`對話前校驗`接口檢查用戶的余額。