当前位置: 首页 > news >正文

Go中使用国家新闻出版署实名认证

随着网络游戏防沉迷系统的接入,实名认证验证也是一个必不可少的部分,网上有第三方的实名认证但基本上都收费,国家新闻出版署提供了免费的接口,不过需要自己去提交申请,获取应用标识 (APPID)应用密钥 (Secret Key)业务权限标识(BizId),并将请求服务器的IP设为白名单后,就可以调用https:// api.wlc.nppa.gov.cn/idcard/authentication/check接口来获取实名认真了。

这个接口中请求体body使用了AES-128/GCM + BASE64算法加密,签名使用了sha256。直接上完整的代码

import ("bytes""crypto/aes""crypto/cipher""crypto/rand""crypto/sha256""encoding/base64""encoding/hex""encoding/json""fmt""io""io/ioutil""net/http""sort""strconv""time"
)// 国家新闻出版署配置信息
type nppaInfo struct {AppId     string // 应用标识SecretKey string // 应用密钥BizId     string // 业务权限标识
}var nppa nppaInfo// 输入国家新闻出版署配置信息
func NppaInit(appId, secretKey, bizId string) {nppa = nppaInfo{AppId:     appId,SecretKey: secretKey,BizId:     bizId,}
}// 实名验证
// ai 	- 游戏内部成员标识,固定32位字符,一般使用 md5(用户ID)
// name - 实名信息中的姓名
// id 	- 实名信息中身份证号码
// 返回
// 		- result 是否验证成功
// 		- errcode 状态码
// 		- errmsg 状态描述
func NppaCheck(ai, name, id string) (result bool, errcode int, errmsg string ) {client := &http.Client{}// body 参数param := map[string]string{"ai":    ai,"name":  name,"idNum": id,}// AES-128/GCM + BASE64算法加密jsonParam, _ := json.Marshal(param)cipher, _ := gcmEncrypt(string(jsonParam))body, _ := json.Marshal(map[string]string{"data": cipher,})// post请求地址req, _ := http.NewRequest("POST", "https://api.wlc.nppa.gov.cn/idcard/authentication/check", bytes.NewReader(body))// header头验证信息headers := map[string]string{"appId":      nppa.AppId,"bizId":      nppa.BizId,"timestamps": strconv.FormatInt(time.Now().UnixNano()/1e6, 10),}// 签名headers["sign"] = sign(headers, string(body))headers["Content-Type"] = "application/json;charset=utf-8"for k, v := range headers {req.Header.Set(k, v)}// 请求resp, err := client.Do(req)if err != nil {return false, -1, "Http请求错误"}defer resp.Body.Close()if resp.StatusCode != 200 {return false, resp.StatusCode, "Http请求返回码错误"}str, err := ioutil.ReadAll(resp.Body)if err != nil {return false, -2, "Http请求返回数据为空"}var msg map[string]interface{}err = json.Unmarshal(str, &msg)if err != nil {return false, -3, "Http请求返回数据格式错误"}ec, ok := msg["errcode"]if !ok {return false, -3, "Http请求返回数据格式错误"}errcode = int(ec.(float64))if errcode != 0 {errmsg, _:= msg["errmsg"]return false, errcode, errmsg.(string)}data, ok := msg["data"]if !ok {return false, -3, "Http请求返回数据格式错误"}r, ok := data.(map[string]interface{})["result"]if !ok {return false, -3, "Http请求返回数据格式错误"}status, ok := r.(map[string]interface{})["status"]if !ok {return false, -3, "Http请求返回数据格式错误"}errcode = int(status.(float64))if errcode == 0{return true, 0, "认证成功"} else if errcode == 1 {return false, errcode, "认证中"}else {return false, errcode, "认证失败"}
}func gcmEncrypt(originalText string) (string, error) {// 需要解码key, _ := hex.DecodeString(nppa.SecretKey)block, err := aes.NewCipher(key)if err != nil {return "", err}aesGcm, err := cipher.NewGCM(block)if err != nil {return "", err}// 向量nonce := make([]byte, aesGcm.NonceSize())if _, err := io.ReadFull(rand.Reader, nonce); err != nil {return "", err}cipherText := aesGcm.Seal(nonce, nonce, []byte(originalText), nil)// encode as base64 stringencoded := base64.StdEncoding.EncodeToString(cipherText)return encoded, nil
}func sign(headers map[string]string, body string) string {var data stringvar keys []string// key排序for k := range headers {keys = append(keys, k)}sort.Strings(keys)// 拼接for _, k := range keys {data = data + k + headers[k]}data = nppa.SecretKey + data + body// 对字符串进行sha256哈希h := sha256.New()h.Write([]byte(data))sum := h.Sum(nil)return hex.EncodeToString(sum)
}

调用

func main() {// 初始化NppaInit("test-appId","2836e95fcd10e04b0069bb1ee659955b","test-bizId")// 使用userId := "123456"name := "岑吾"id := "xxxxxxxxxxxxxxxxxx"h := md5.New()h.Write([]byte(userId))ok,code,msg := NppaCheck(hex.EncodeToString(h.Sum(nil)), name, id)fmt.Println(ok,code,msg)
}

详细返回参数可见网络游戏防沉迷实名认证系统

http://www.dtcms.com/a/266987.html

相关文章:

  • [C++] # 深入理解C++继承:从原理到实现
  • 通过网页调用身份证阅读器http websocket方法-华视电子————仙盟创梦IDE
  • 结构型智能科技的关键可行性——信息型智能向结构型智能的转换(提纲)
  • CSS知识复习2
  • 3-1 PID算法改进(积分部分)
  • Softhub软件下载站实战开发(十二):软件管理编辑页面实现
  • 科学的第五范式:人工智能如何重塑发现之疆
  • 力扣打卡第二十一天 中后遍历+中前遍历 构造二叉树
  • 【Qt】QxORM无法删除和更改主键值为0的行,否则报错:invalid primary key
  • Docker学习笔记:Docker网络
  • DotNetBrowser 2.27.14 版本发布啦!
  • Python 制作 pyd(Windows 平台的动态链接库)
  • 力扣:70. 爬楼梯
  • [Terence Tao访谈] 无限 | 关注模型 | 矢量场 | 策略性“作弊” | Lean
  • 【Prometheus 】通过 Pushgateway 上报指标数据
  • 408第三季part1 - 操作系统 - 输入输出管理
  • pyproject.toml 有什么作用呢?
  • Java对象哈希值深度解析
  • vue/微信小程序/h5 实现react的boundary
  • 汽车功能安全概念阶段开发【相关项定义HARA】2
  • 【Mysql系列】Mysql 多级隔离级别揭秘
  • 使用Python绘制图片拆分工具
  • 风平浪静、无事发生
  • 论文解读:《DeepGray:基于灰度图像和深度学习的恶意软件分类方法》
  • OneCode 智能化UI布局与定位:注解驱动的视觉编排艺术
  • 图灵完备之路(数电学习三分钟)----数据选择器与总线
  • 使用alist+RaiDrive+webdav将百度夸克网盘变为本地电脑磁盘方法教程
  • 《人生顶层设计》读书笔记7
  • J20250704 算法题5道
  • css-多条记录,自动换行与自动并行布局及gap兼容