golang实现iOS DeviceCheck API交互的客户端插件库device-check-go的使用

Golang实现iOS DeviceCheck API交互的客户端插件库device-check-go的使用

简介

device-check-go是一个用于与iOS DeviceCheck API交互的Golang SDK,可以查询和修改设备位数据。

安装

go get github.com/rinchsan/device-check-go/v2

快速开始

初始化SDK

import "github.com/rinchsan/device-check-go/v2"

// 从私钥文件创建凭证,也可以使用原始字符串/字节创建
cred := devicecheck.NewCredentialFile("/path/to/private/key/file") 

// 创建配置:ISSUER、KEY_ID和环境(Development或Production)
cfg := devicecheck.NewConfig("ISSUER", "KEY_ID", devicecheck.Development)

// 创建客户端
client := devicecheck.New(cred, cfg)

使用DeviceCheck API

查询两个位

var result devicecheck.QueryTwoBitsResult
if err := client.QueryTwoBits("DEVICE_TOKEN", &result); err != nil {
    switch {
    // 注意:如果没有找到位状态,QueryTwoBits会返回ErrBitStateNotFound错误
    case errors.Is(err, devicecheck.ErrBitStateNotFound):
        // 处理ErrBitStateNotFound错误
    default:
        // 处理其他错误
    }
}

更新两个位

if err := client.UpdateTwoBits("DEVICE_TOKEN", true, true); err != nil {
    // 处理错误
}

验证设备令牌

if err := client.ValidateDeviceToken("DEVICE_TOKEN"); err != nil {
    // 处理错误
}

完整示例Demo

下面是一个完整的示例,展示了如何使用device-check-go库:

package main

import (
	"errors"
	"fmt"
	"log"

	"github.com/rinchsan/device-check-go/v2"
)

func main() {
	// 1. 初始化客户端
	cred := devicecheck.NewCredentialFile("path/to/AuthKey_XXXXXX.p8")
	cfg := devicecheck.NewConfig("YOUR_ISSUER_ID", "YOUR_KEY_ID", devicecheck.Development)
	client := devicecheck.New(cred, cfg)

	deviceToken := "DEVICE_TOKEN_FROM_IOS_APP"

	// 2. 验证设备令牌
	if err := client.ValidateDeviceToken(deviceToken); err != nil {
		log.Fatalf("设备令牌验证失败: %v", err)
	}
	fmt.Println("设备令牌验证成功")

	// 3. 查询设备位状态
	var result devicecheck.QueryTwoBitsResult
	if err := client.QueryTwoBits(deviceToken, &result); err != nil {
		if errors.Is(err, devicecheck.ErrBitStateNotFound) {
			fmt.Println("未找到设备位状态")
		} else {
			log.Fatalf("查询设备位失败: %v", err)
		}
	} else {
		fmt.Printf("设备位状态: bit0=%v, bit1=%v\n", result.Bit0, result.Bit1)
	}

	// 4. 更新设备位
	if err := client.UpdateTwoBits(deviceToken, true, false); err != nil {
		log.Fatalf("更新设备位失败: %v", err)
	}
	fmt.Println("设备位更新成功")
}

注意事项

  1. 在使用前需要从Apple开发者账号获取必要的凭证信息
  2. 根据实际环境选择Development或Production模式
  3. 设备令牌需要从iOS应用端获取

相关文档

  • iOS DeviceCheck API文档
  • HTTP命令文档(用于查询和修改设备位数据)

更多关于golang实现iOS DeviceCheck API交互的客户端插件库device-check-go的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang实现iOS DeviceCheck API交互的客户端插件库device-check-go的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用device-check-go实现iOS DeviceCheck API交互

DeviceCheck是苹果提供的一种服务,允许开发者验证iOS设备的真实性并存储少量设备级数据。下面我将介绍如何使用device-check-go库来实现与DeviceCheck API的交互。

安装device-check-go

首先安装device-check-go库:

go get github.com/dgrijalva/device-check-go

基本使用示例

1. 初始化客户端

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/dgrijalva/device-check-go"
)

func main() {
	// 从苹果开发者账户获取的密钥信息
	authKey := `-----BEGIN PRIVATE KEY-----
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgI5V7eYt5rqHQg0Os
...
-----END PRIVATE KEY-----`
	keyID := "ABC123DEFG" // 你的密钥ID
	teamID := "DEF456GHIJ" // 你的团队ID

	// 创建DeviceCheck客户端
	client, err := devicecheck.New(
		devicecheck.WithAuthKey([]byte(authKey)),
		devicecheck.WithKeyID(keyID),
		devicecheck.WithTeamID(teamID),
	)
	if err != nil {
		log.Fatalf("创建DeviceCheck客户端失败: %v", err)
	}
}

2. 查询设备状态

func queryDeviceStatus(client *devicecheck.Client) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	deviceToken := "设备令牌,来自iOS应用" // 实际应用中从请求中获取

	// 查询设备状态
	status, err := client.QueryTwoBits(ctx, deviceToken)
	if err != nil {
		log.Printf("查询设备状态失败: %v", err)
		return
	}

	fmt.Printf("设备状态: Bit0=%t, Bit1=%t\n", status.Bit0, status.Bit1)
}

3. 更新设备状态

func updateDeviceStatus(client *devicecheck.Client) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	deviceToken := "设备令牌,来自iOS应用"
	
	// 设置要更新的状态位
	update := devicecheck.BitsUpdate{
		Bit0: devicecheck.BitSetTrue,  // 设置为true
		Bit1: devicecheck.BitSetFalse, // 设置为false
	}

	// 更新设备状态
	err := client.UpdateTwoBits(ctx, deviceToken, update)
	if err != nil {
		log.Printf("更新设备状态失败: %v", err)
		return
	}

	fmt.Println("设备状态更新成功")
}

4. 验证设备令牌

func validateDeviceToken(client *devicecheck.Client) {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	deviceToken := "设备令牌,来自iOS应用"
	timestamp := time.Now().Unix() * 1000 // 毫秒级时间戳

	// 验证设备令牌
	err := client.ValidateDeviceToken(ctx, deviceToken, timestamp)
	if err != nil {
		log.Printf("设备令牌验证失败: %v", err)
		return
	}

	fmt.Println("设备令牌验证成功")
}

完整示例

下面是一个完整的HTTP服务示例,处理来自iOS应用的DeviceCheck请求:

package main

import (
	"context"
	"encoding/json"
	"log"
	"net/http"
	"time"

	"github.com/dgrijalva/device-check-go"
)

type DeviceCheckRequest struct {
	DeviceToken string `json:"device_token"`
}

var client *devicecheck.Client

func initDeviceCheck() {
	authKey := `-----BEGIN PRIVATE KEY-----
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgI5V7eYt5rqHQg0Os
...
-----END PRIVATE KEY-----`
	keyID := "ABC123DEFG"
	teamID := "DEF456GHIJ"

	var err error
	client, err = devicecheck.New(
		devicecheck.WithAuthKey([]byte(authKey)),
		devicecheck.WithKeyID(keyID),
		devicecheck.WithTeamID(teamID),
	)
	if err != nil {
		log.Fatalf("创建DeviceCheck客户端失败: %v", err)
	}
}

func handleDeviceCheck(w http.ResponseWriter, r *http.Request) {
	var req DeviceCheckRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "无效的请求", http.StatusBadRequest)
		return
	}

	ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
	defer cancel()

	// 验证设备令牌
	if err := client.ValidateDeviceToken(ctx, req.DeviceToken, time.Now().Unix()*1000); err != nil {
		http.Error(w, "设备验证失败", http.StatusUnauthorized)
		return
	}

	// 查询设备状态
	status, err := client.QueryTwoBits(ctx, req.DeviceToken)
	if err != nil {
		http.Error(w, "查询设备状态失败", http.StatusInternalServerError)
		return
	}

	// 根据业务逻辑处理状态位
	if status.Bit0 {
		// 执行Bit0为true时的逻辑
	}

	// 更新设备状态
	update := devicecheck.BitsUpdate{
		Bit0: devicecheck.BitSetTrue,
		Bit1: devicecheck.BitNoChange,
	}
	if err := client.UpdateTwoBits(ctx, req.DeviceToken, update); err != nil {
		log.Printf("更新设备状态失败: %v", err)
	}

	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(map[string]interface{}{
		"status":  "verified",
		"bit0":    status.Bit0,
		"bit1":    status.Bit1,
		"updated": true,
	})
}

func main() {
	initDeviceCheck()
	http.HandleFunc("/device-check", handleDeviceCheck)
	log.Println("服务启动,监听8080端口...")
	log.Fatal(http.ListenAndServe(":8080", nil))
}

注意事项

  1. 密钥管理:在实际应用中,不要将私钥硬编码在代码中,应该使用安全的配置管理系统或密钥管理服务。

  2. 错误处理:DeviceCheck API可能会返回各种错误,如无效令牌、配额限制等,应该妥善处理这些错误。

  3. 性能考虑:DeviceCheck API调用有一定的延迟,建议在后台异步处理,不要阻塞主请求流程。

  4. 配额限制:苹果对DeviceCheck API有调用频率限制,注意不要超过配额。

  5. 测试环境:苹果提供了沙箱环境用于测试,开发时应使用沙箱环境进行测试。

通过device-check-go库,你可以方便地在Go应用中集成iOS DeviceCheck功能,验证设备真实性并管理设备状态。

回到顶部