接口规范说明

30 篇文章 0 订阅

接口输出能力

A:提供restful-api风格的http接口

B:提供grpc接口

HEAD部分:Content-Type: application/json

POST body部分:{"xxx": "xxxxxxx"}

认证鉴权:调用接口有如下两种认证方式  ,认证鉴权。

Token认证:通过Token认证通用请求。

AuthorizationBearer  

·  APPkey/AppSecret认证:通过APPkey/AppSecret 签名方式调用请求。适用于应用接入方认证,参照 附录api签名指南部分

AuthorizationZEUS-HMAC-SHA256

认证相关hearder头规范如下:

·  Authorization:  

目前支持Bearer和自定义ZEUS-HMAC-SHA256

·   X-Auth-Subject: 扩展认证主体标识

格式:,  逗号分隔

类型:目前支持两种种类型:

user:用户

app :应用如果是client id为终端ID,如果是用户,ID为staffid,如果是app则是appID

响应规范

响应Content-Type

application/json

即返回结果格式使用 JSON

响应约束

response.header 中的 HTTP status Code 为 2xx 时,表示正常响应;直接返回数据

成功 :

HTTP/1.1 200 OK

Content-Type: application/json; charset="UTF-8"

Content-Length: XXXX

{

"id": 0,

"userName": "john",

"email": "123@",

}

失败 :
 

HTTP/1.1 500 INTERNAL SERVER ERROR

Content-Type: application/json; charset="UTF-8"

Content-Length: XXXX

{

"code": 3,

"message": "xxx错误",

"details": [],

}

GRPC 接口规范

附录

HTTP常用响应码·

响应 码

描述

200

OK – 操作顺利完成

201

Created –- 客户端请求成功创建了一个新资源时,可发送此响应码

204

No Content – 服务器端拒绝对PUT、POST或DELETE请求返回任何状态信息或表示,可发送此响应码

301

Moved Permanently – 客户端触发的动作引起资源URI变化时发送此响应码,或者客户端请求一个资源的旧url时也发送此响 应码

400

Bad Request – 客户端请求参数不合法

401

Unauthorized – 客户端试图操作一个受保护资源,却又没有提供正确的认证证书,可发送此响应码

403

Forbidden – 客户端请求正确,认证也正确,但由于请求资源只允许在指定时间段内,或者只允许指定IP的用户访问,可发送 此响应码

404

Not Found – 客户端请求的资源不存在

405

Method Not Allowed – 客户端试图使用一个本资源不支持的HTTP方法时,可发送此响应码

409

Conflict – 客户端试图执行一个“会导致一个或多个资源处于不一致状态”的操作时,可发送此响应码

410

Gone – 服务器知道被请求资源曾经指向一个资源,但该资源现在不存在了,可发送此响应码

413

Request Entity Too Large – 客户端发送的表示太大以至于服务器无法处理时,可发送此响应码

414

Request-URI Too Long – 客户端请求URL长度超过服务端处理能力时,可发送此响应码

415

Unsupported Media Type – 客户端在发送表示时采用了一个服务端无法理解的媒体类型,可发送此响应码

500

Internal Server Error – 服务器端发生未知故障

503

Service Unavailable – 服务器正常,但由于下层服务不正常(如系统资源不足或正在遭受大量恶意请求)以至于不能全部处 理,可发送此响应码

错误码分配表

错误码段

模块名称

0~9999

平台框架使用 参照下面表格中定义的错误码

10000 ~ 99999

其它模块使用 有业务自己定义

……

……

下面列举了状态码code及http 对应关系,该状态码已覆盖大部分场景

错误码

code

对应http状 态码

错误描述

0

200

1

499

CANCELLED:操作被取消

2

500

UNKNOWN-未知的错误。   通常是服务器错误

3

400

INVALID_ARGUMENT-客户端指定了无效的参数。   检查错误消息和错误详细信息以获取更多信息。

4

504

DEADLINE_EXCEEDED已超过请求期限。如果重复发生,请考虑降低请求的复杂性。

5

404

NOT_FOUND找不到指定的资源

6

409

ALREADY_EXISTS客户端尝试创建的资源已存在。

7

403

PERMISSION_DENIED客户端没有足够的权限。这可能是因为OAuth令牌没有正确的范围,客户端没有权限,或者客 户端项目尚未启用API。

8

429

RESOURCE_EXHAUSTED资源配额达到速率限制。如磁盘已满

9

400

FAILED_PRECONDITION失败具有前提条件

请求不能在当前系统状态下执行,例如删除非空目录。

10

409

ABORTED并发冲突,例如读-修改-写冲突

11

400

OUT_OF_RANGE客户端指定了无效的范围。

12

501

UNIMPLEMENTED服务器未实现该API方法。

13

500

INTERNAL内部服务错误。   通常是服务器错误。

14

503

UNAVAILABLE暂停服务。通常是服务器已经关闭。

15

500

DATA_LOSS不可恢复的数据丢失或数据损坏。   客户端应该向用户报告错误

16

401

UNAUTHENTICATED由于遗失,无效或过期的OAuth令牌而导致请求未通过身份验证。

Api签名指南

通过APPKEY/AppSecret签名以及请求发送的流程概述如下:

a.  创建待签名字符串。

b.  使用APPKEY/AppSecret待签字符串计算签名。

c.  将生成的签名信息作为请求消息头添加到HTTP请求HEADER:Authorization中

以下做详细介绍。

步骤1:创建待签名字符串

参数说明

参数

必须

说明

appkey

用户中心系统分配

timestamp

毫秒时间戳

nonce

一个随机值,建议10位

version

算法版本号:默认1.0.0

待签名字符串:

StringToSign=appKey:{appKey}&nonce:{nonce}×tamp={timestamp}

举例说明:appKey:snc&nonce:1234567890×tamp:1566974140

步骤2:使用APPKey/AppSecret待签字符串计算签名

signature = HMAC256(AppSecret,StringToSign))

假设:StringToSign=

appKey:snc&nonce:1234567890×tamp:1566974140 AppSecret=8095e6-85e6-11e9-bf62-6c92bf0e53 则signature=

步骤3:将生成的签名信息作为请求消息头添加到HTTP请求HEADER:Authorization中

在计算签名后,将它添加到Authorization的HTTP消息头。Authorization消息头未包含在已签名消息头中,主要用于身份验证。

伪代码如下:

Authorization header

Authorization:

为固定值ZEUS-HMAC-SHA256,为 appId nonce timestamp signature 中间是逗号隔开, 和空格隔开

Authorization:ZEUS-HMAC-SHA256 appKey={AppKey},nonce={nonce},timestamp={timestamp},version={version},signature=

{signature}

举例:

Authorization:ZEUS-HMAC-SHA256

appKey=snc,nonce=1234567890,timestamp=1566974140,version=1.0.0,signature=

得到签名消息头后,将其增加到原始HTTP请求内容中

包含签名信息的完整请求如下:

GET /api/v1/staff/123 HTTP/1.1

Host: xxx

Content-Type: application/json

Authorization:ZEUS-HMAC-SHA256 appKey=snc,nonce=1234567890,timestamp=1566974140,version=1.0.0,signature=

X-Auth-Subject:client,xxxxx

认证相关自定义错误码:

CAPTCHA_ERROR errCodeType = 10000 //

LOCK_ACCOUNT_ERR = 10001 //

LOCKED_ACCOUNT_ERR = 10002 //

AUTH_FACTOR_ERR = 10003 //

PASSWORD_EXPIRED_ERR = 10004 //

PASSWORD_EXPIRED_TIME = 10005 //

PASSWORD_POLICIY_ERR = 10006 //

FACTOR_NOT_FOUND_ERR = 10007 //

UNAUTH_ERROR = 10008 //

CAPTCHA_CHECK_ERROR = 10009 //

以创建应用接口为例:

HTTP报文示例:

POST /app/v1/app HTTP/1.1

Host: 10.251.72.200:32165

Accept: application/grpc-web-text

X-User-Agent: grpc-web-javascript/0.1

Authorization: ZEUS-HMAC-SHA256 appKey=b09285a0a7bc4dd3aca3c84dd4f1e927,nonce=4266672601,timestamp=1599552024,

version=1.0.0,signature=72e7febb10177249a1d7fb23aa96329437a5e60c8ff107e7aab94f00def710ec

X-Grpc-Web: 1

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135

Safari/537.36

x-request-id: 8def5010-4d9e-433e-a5aa-55f4d453d51e

Content-Type: application/json

X-Auth-Subject: app,b09285a0a7bc4dd3aca3c84dd4f1e927

{"asset_id":{"oid":2671556498458444238,"id":2671556498458509774},"meta":{"name":"test12663","description":"this is test123","staff_id":{"asset_id":{"oid":2671556498458444238,"id":2671556498458509774},"id":

2672430249123283553}}}

CURL示例:

​
curl --location --request POST 'https://10.251.72.200:32165/app/v1/app' \

--header 'Accept: application/grpc-web-text' \

--header 'X-User-Agent: grpc-web-javascript/0.1' \

--header 'Authorization: ZEUS-HMAC-SHA256 appKey=b09285a0a7bc4dd3aca3c84dd4f1e927,nonce=4266672601,

timestamp=1599552024,version=1.0.0,signature=72e7febb10177249a1d7fb23aa96329437a5e60c8ff107e7aab94f00def710ec' \

--header 'X-Grpc-Web: 1' \

--header 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.

0.4147.135 Safari/537.36' \

--header 'x-request-id: 8def5010-4d9e-433e-a5aa-55f4d453d51e' \

--header 'Content-Type: application/json' \

--header 'X-Auth-Subject: app,b09285a0a7bc4dd3aca3c84dd4f1e927' \

--data-raw '{"asset_id":{"oid":2671556498458444238,"id":2671556498458509774},"meta":{"name":"test12663","

description":"this is test123","staff_id":{"asset_id":{"oid":2671556498458444238,"id":2671556498458509774},"id":

2672430249123283553}}}'

HTTP请求

package main

import (

"fmt"

"strings"

"net/http"

"io/ioutil"

)

func main() {

url := "https://10.251.72.200:32165/app/v1/app"

method := "POST"

payload := strings.NewReader("{\"asset_id\":{\"oid\":2671556498458444238,\"id\":2671556498458509774},\"meta\": {\"name\":\"test12663\",\"description\":\"this is test123\",\"staff_id\":{\"asset_id\":{\"oid\":

2671556498458444238,\"id\":2671556498458509774},\"id\":2672430249123283553}}}")

client := &http.Client {

}

req, err := http.NewRequest(method, url, payload)

if err != nil {

fmt.Println(err)

}

req.Header.Add("Accept", "application/grpc-web-text")

req.Header.Add("X-User-Agent", "grpc-web-javascript/0.1")

req.Header.Add("Authorization", "ZEUS-HMAC-SHA256 appKey=b09285a0a7bc4dd3aca3c84dd4f1e927,nonce=4266672601,

timestamp=1599552024,version=1.0.0,signature=72e7febb10177249a1d7fb23aa96329437a5e60c8ff107e7aab94f00def710ec")

req.Header.Add("X-Grpc-Web", "1")

req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)

Chrome/84.0.4147.135 Safari/537.36")

req.Header.Add("x-request-id", "8def5010-4d9e-433e-a5aa-55f4d453d51e")

req.Header.Add("Content-Type", "application/json")

req.Header.Add("X-Auth-Subject", "app,b09285a0a7bc4dd3aca3c84dd4f1e927")

res, err := client.Do(req)

defer res.Body.Close()

body, err := ioutil.ReadAll(res.Body)

fmt.Println(string(body))

}

GRPC示例:

package main

import (

"crypto/hmac"

"crypto/rand"

"crypto/sha256"

"encoding/hex"

"fmt"

api "git-biz.qianxin-inc.cn/zeus-platform/zeus-da-api.git/generated-go/app_v1"

apiClient "git-biz.qianxin-inc.cn/zeus-platform/zeus-da-api.git/generated-go/app_v1/client"

"golang.org/x/net/context"

"google.golang.org/grpc/metadata"

"strconv"

"time"

"git-biz.qianxin-inc.cn/zeus-platform/zeus-da-api.git/generated-go/zeus"

"git-biz.qianxin-inc.cn/zeus-platform/zeus-da-api.git/generated-go/zeus/app"

)

var oid int64 = 2671556498458444238

var assetId int64 = 2671556498458509774

var appId int64 = 2682883730313347430

var staffId int64 = 2672430249123283553

var appKey string = "b09285a0a7bc4dd3aca3c84dd4f1e927"

var appSecret string = "b817187828965ed56d8d72bd90d1ab0c5e2479e3"

const (

VERSION = "1.0.0"

SIGNALG = "ZEUS-HMAC-SHA256"

)

func main() {

GrpcCreateApp()

}

func GrpcCreateApp() {

client, err := apiClient.NewAppV1FatClient()

if err != nil {

fmt.Println(err)

return

}

req := &api.CreateApp_Request{

AssetId: &zeus.AssetId{Oid: oid, Id: assetId},

Meta: &app.Meta{

Name:        "test1d0",

Description: "this is test10",

StaffId:     &zeus.StaffId{AssetId: &zeus.AssetId{Oid: oid, Id: assetId}, Id: staffId},

},

}

authClient := NewAuthClient(appKey, appSecret)

ctx := authClient.GetCtx()

res, err := client.CreateApp(ctx, req)

fmt.Println(res, err)

return

}

type AuthClient struct {

signAlg   string //  ZEUS-HMAC-SHA256

appKey    string //

appSecret string // appKey

nonce     int64  //

timestamp int64  //

version   string // 1.0.0

}

func NewAuthClient(appKey, appSecret string) *AuthClient {

random, _ := rand.Prime(rand.Reader, 32)

timestamp := time.Now().Unix()

return &AuthClient{

signAlg:   SIGNALG,

appKey:    appKey,

appSecret: appSecret,

nonce:     random.Int64(),

timestamp: timestamp,

version:   VERSION,

}

}

func (c *AuthClient) GetHeader() map[string]string {

return c.assemble()

}

func (c *AuthClient) GetCtx() context.Context {

assemble := c.assemble()

md := metadata.Pairs(

"Authorization", assemble["Authorization"],

"X-Auth-Subject", assemble["x-Auth-Subject"],

)

return metadata.NewOutgoingContext(context.Background(), md)

}

func (c *AuthClient) assemble() map[string]string {

authorization := fmt.Sprintf("%s ", c.signAlg)

authorization += fmt.Sprintf("%s=%s,", "appKey", c.appKey)

authorization += fmt.Sprintf("%s=%s,", "nonce", strconv.FormatInt(c.nonce, 10))

authorization += fmt.Sprintf("%s=%s,", "timestamp", strconv.FormatInt(c.timestamp, 10))

authorization += fmt.Sprintf("%s=%s,", "version", c.version)

authorization += fmt.Sprintf("%s=%s", "signature", c.getSign())

xAuthSubject := fmt.Sprintf("%s,%s", "app", appKey)

return map[string]string{

"Authorization":  authorization,

"X-Auth-Subject": xAuthSubject,

}

}

func (c *AuthClient) getSign() string {

signStr := fmt.Sprintf("%s:%s&", "appKey", c.appKey)

signStr += fmt.Sprintf("%s:%s&", "nonce", strconv.FormatInt(c.nonce, 10))

signStr += fmt.Sprintf("%s:%s", "timestamp", strconv.FormatInt(c.timestamp, 10))

return c.getHmac256(signStr)

}

func (c *AuthClient) getHmac256(signStr string) string {

h := hmac.New(sha256.New, []byte(c.appSecret))

h.Write([]byte(signStr))

return hex.EncodeToString(h.Sum(nil))

}

​

  • 18
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 接口规范文档说明书是一份详细描述软件系统中的接口规范的文档。它主要用于软件开发过程中,为开发人员提供接口的使用规范和约束,保证系统的稳定性和兼容性。 首先,接口规范文档说明书可以在Word文档中进行下载和阅读。Word是一种常见的办公软件,广泛应用于文档编辑、排版和打印等工作。通过下载接口规范文档说明书的Word版本,我们可以方便地阅读和理解其中的内容。 接口规范文档说明书通常包含以下内容:接口概述、接口设计原则、接口命名规范接口数据结构定义、接口参数说明接口返回值说明接口安全要求等。这些内容的详细描述可以帮助开发人员了解接口的功能和使用方式,增加系统的可维护性和可扩展性。 在接口规范文档说明书中,我们可以了解到接口的输入、输出参数的数据类型、取值范围以及异常处理等细节。这有助于开发人员在使用接口时,能够准确地传入参数、正确地解析返回值,并能够针对不同的异常情况进行处理。 总结而言,接口规范文档说明书是一份非常重要的文档,它提供了开发人员在软件开发过程中使用接口规范和约束。通过下载和阅读接口规范文档说明书的Word版本,我们能够更好地理解和掌握接口的使用方式,提高软件系统的质量和可维护性。 ### 回答2: 接口规范文档说明书是描述软件系统中各个接口的详细信息和使用规则的文档。这个文档对于开发人员、测试人员以及其他相关人员来说都非常重要,它可以帮助大家理解和使用系统中的各个接口。 通过这个文档,开发人员可以了解接口的设计思路、输入输出参数以及调用方式等。这对于他们开发和集成系统中的各个模块非常有帮助。同时,测试人员可以根据接口规范文档编写测试用例,对接口进行全面的测试,确保系统的质量和稳定性。 接口规范文档的格式通常是Word文档,大家可以通过下载这个文档来查阅和阅读。在文档中,会包含接口名称、接口描述、参数说明、调用示例以及错误码等内容。这些内容能够帮助大家更好地了解和使用接口。 为了保证文档的准确性和及时性,编写接口规范文档时需要严谨和细致。文档应该根据实际情况进行更新和维护,及时反映系统中接口的变动。此外,文档的编写应该尽量清晰明了,避免出现歧义和混淆。 总而言之,接口规范文档说明书是帮助大家理解和使用系统中各个接口的重要参考文档。通过下载这个Word文档,大家可以更好地了解接口的设计和使用规则,提高开发和测试效率,保证系统的质量和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纵然间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值