原创

V3手动鉴权失败之Go篇

导语

该系列其他篇章:

V3手动鉴权失败之Nodejs篇

V3手动鉴权失败之Python篇

V3手动鉴权失败之Java篇

V3手动鉴权失败之PHP篇

V3手动鉴权失败之C#篇

腾讯云 API 全新升级 3.0 ,该版本进行了性能优化且全地域部署、支持就近和按地域接入、访问时延下降显著,接口描述更加详细、错误码描述更加全面、SDK增加接口级注释,让您更加方便快捷的使用腾讯云产品。人脸识别文字识别语音识别等众多产品均已接入云API 3.0。

腾讯云API为了更好的让用户接入,已经封装好了多种语言的SDK,只需用户传入SecrectId、SectectKey以及接口入参,即可完成接口鉴权和请求发送,具体包括Python SDKJava SDKPHP SDKGo SDKNodeJS SDK.NET SDK

案例背景

在某些情况,用户需要实现手动接口鉴权,虽然官网文档已有详细的接口鉴权流程,但是由于:

1.V3手动鉴权步骤较为复杂;

2.官网某些demo代码无法直接下载运行,仍需简单调整;

3.官网文档的demo代码覆盖面有限,没有包括全量上述六类后端语言;

基于此,很多用户只能自己尝试手动鉴权,但都返回“鉴权失败”,从而无法调通接口。

原因分析

从宏观上看,“鉴权失败”要关注两个阶段:

1. 整体的接口鉴权是否正确;

2. 模拟的鉴权请求的发送是否正确;

从历史问题回顾,有客户曾经出现接口鉴权时而成功,时而失败的情况,排查了整体的鉴权过程,完全正确,但是也的确复现了客户的问题。后来发现,用户在鉴权完成后,发送具体的请求时,传入的时间戳timestamp没有实时更新导致了报错。

解决方案

为了帮助客户更简单、更快捷地完成接口手动鉴权,并成功发送鉴权请求,将通过一系列文章专门讲解各个后端语言的手动鉴权&发送请求的可执行demo代码,助力客户快速接入。

本期将以调用人脸识别的DetectFace接口为例,详叙Go语言demo。

前期准备

Go语言环境:直接在Go官网根据操作系统类型下载并安装指定安装包即可。

SecrectId和SecretKey:接口鉴权的密钥。可以把SecretId理解成“账号”,把SecretKey理解成“密码”。在自己的腾讯云官网控制台获取:访问管理 -> 访问密钥 -> API密钥管理。

手动鉴权相关文档:请求结构公共参数V3接口鉴权

具体代码

运行go语言代码,即可完成v3鉴权,并发送http请求,收到具体的response响应。运行指令为:

go run go_v3.go

具体的go_v3.go代码如下,只需要简单复制,然后输入自己的SecretId和SecretKey两个字段即可:

package main

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"
	"time"
)

const SecretId = "xxx";//填入自己的secretId
const SecretKey = "xxx";//填入自己的secretKey

//算法
const Algo                  = "sha256"
const Url      				= "https://iai.tencentcloudapi.com"
//规范请求串
const HTTPRequestMethod     = "POST"
const CanonicalURI          = "/"
const CanonicalQueryString  = ""
const CanonicalHeaders      = "content-type:application/json; charset=utf-8\nhost:iai.tencentcloudapi.com\n"
const SignedHeaders         = "content-type;host"//参与签名的头部信息

//签名字符串
const Algorithm             = "TC3-HMAC-SHA256"
const Service               = "iai"
const Stop                  = "tc3_request"


func main()  {
	var face face
	d := face.Authentication("DetectFace",`{"Url":"http://www.people.com.cn/mediafile/pic/20150624/51/10411837753251226111.jpg"}`, "2018-03-01")
	println(d)
}

type face struct {

}

//鉴权提交
// action 访问方法
// param   json参数
// version 版本
func (f *face) Authentication(action string, param string, version string) string {
	//loc, _ := time.LoadLocation("")
	//fmt.Println(loc, err)
	//时间戳
	timeNow		:= time.Now()
	//本地时区秒数
	timeStampInt	:= timeNow.Unix()
	timeStamp	:= strconv.FormatInt(timeStampInt, 10)
	//UTC时区年月日
	nowDate		:= time.Unix(timeStampInt,0).UTC().Format("2006-01-02")
	//加密参数
	hashedRequestPayload := f.HashEncryption(param)
	//初次加密 规范请求串
	canonicalRequest       :=   HTTPRequestMethod + "\n" +
		CanonicalURI + "\n" +
		CanonicalQueryString + "\n" +
		CanonicalHeaders + "\n" +
		SignedHeaders + "\n" +
		hashedRequestPayload;

	fmt.Println(canonicalRequest)
	//第二次加密 签名字符串
	credentialScope        :=   nowDate + "/" + Service + "/" + Stop;
	hashedCanonicalRequest :=   f.HashEncryption(canonicalRequest);
	stringToSign           :=   Algorithm + "\n" +
								timeStamp + "\n" +
								credentialScope + "\n" +
								hashedCanonicalRequest

	fmt.Println(stringToSign)

	//计算签名
	secretDate             :=   f.HashHmacSha256Encryption(nowDate,  "TC3" + SecretKey, true)
	secretService          :=   f.HashHmacSha256Encryption(Service,   secretDate, true)
	secretSigning          :=   f.HashHmacSha256Encryption(Stop,  secretService, true)

	//签名
	signature              :=   f.HashHmacSha256Encryption(stringToSign,  secretSigning, false)
	authorization          :=   Algorithm + " " +
								"Credential=" + SecretId + "/" + credentialScope + ", " +
								"SignedHeaders=" + SignedHeaders + ", " +
								"Signature=" + signature
	fmt.Println(authorization)
	//申明header头部
	var header = map[string]string{
		"Content-Type" : "application/json; charset=utf-8",
		"Authorization" : authorization,
		"Host" : "iai.tencentcloudapi.com",
		"X-TC-Action" : action,
		"X-TC-Version" : version,
		"X-TC-Timestamp" : timeStamp,
	}
	return f.http_post_request(header, param)
}

//256 加密算法 转小写
func (f *face) HashEncryption(sign string) string{
	sha256Byte := sha256.Sum256([]byte(sign))
	tf16 := fmt.Sprintf("%x", sha256Byte)
	return tf16
}


//Hash_Hmac 加密算法
//sign 加密字符串
//key  加密key
//flag true 原始数据  false 小写16进制数据
func (f *face) HashHmacSha256Encryption(sign string, key string, flag bool) string {
	hash := hmac.New(sha256.New,[]byte(key)) // 创建对应的sha256哈希加密算法
	hash.Write([]byte(sign)) // 写入加密数据
	if flag {
		return string(hash.Sum(nil))
	}
	return fmt.Sprintf("%x",hash.Sum(nil))
}

func (f *face) http_post_request(header map[string]string, param string) string {
	client		:= &http.Client{}
	req_new := bytes.NewBuffer([]byte(param))
	req, err 	:= http.NewRequest("POST", Url, req_new)
	//设置header头部
	for k,v := range header{
		req.Header.Set(k, v)
	}
	//发送请求
	resp, err := client.Do(req)
	//延迟执行断开
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("post request error : ", err)
		return "error"
	}
	return string(body)
}

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • V3手动鉴权失败之Nodejs篇

    腾讯云 API 全新升级 3.0 ,该版本进行了性能优化且全地域部署、支持就近和按地域接入、访问时延下降显著,接口描述更加详细、错误码描述更加全面、SDK增加接...

    周朋伟
  • V3手动鉴权失败之Java篇

    腾讯云 API 全新升级 3.0 ,该版本进行了性能优化且全地域部署、支持就近和按地域接入、访问时延下降显著,接口描述更加详细、错误码描述更加全面、SDK增加接...

    周朋伟
  • V3手动鉴权失败之Python篇

    腾讯云 API 全新升级 3.0 ,该版本进行了性能优化且全地域部署、支持就近和按地域接入、访问时延下降显著,接口描述更加详细、错误码描述更加全面、SDK增加接...

    周朋伟
  • V3手动鉴权失败之C#篇

    腾讯云 API 全新升级 3.0 ,该版本进行了性能优化且全地域部署、支持就近和按地域接入、访问时延下降显著,接口描述更加详细、错误码描述更加全面、SDK增加接...

    周朋伟
  • V3手动鉴权失败之PHP篇

    腾讯云 API 全新升级 3.0 ,该版本进行了性能优化且全地域部署、支持就近和按地域接入、访问时延下降显著,接口描述更加详细、错误码描述更加全面、SDK增加接...

    周朋伟
  • 【AI接入迷你赛】腾讯云产品鉴权签名 v3

    腾讯云 API 会对每个请求进行身份验证,用户需要使用安全凭证,经过特定的步骤对请求进行签名 Signature,每个请求都需要在公共请求参数中指定该签名结果并...

    用户4299935
  • Go+gRPC-Gateway(V2) 微服务实战,小程序登录鉴权服务(六):客户端基础库 TS 实战

    小程序登录鉴权服务,客户端底层 SDK,登录鉴权、业务请求、鉴权重试模块 Typescript 实战。

    为少
  • etcd 备份与恢复

    etcd 是一款开源的分布式一致性键值存储,由 CoreOS 公司进行维护,详细的介绍请参考官方文档。

    田飞雨
  • 重启导致etcd数据不一致的bug分析

    近日,腾讯云TKE团队的工程师在做混沌测试的过程中,定位并解决了一个存在3年之久的etcd3数据一致性bug。

    于广游garyyu

扫码关注云+社区

领取腾讯云代金券