iOS 11에 추가된 DeviceCheck 정보

16365 단어 SwiftWWDC2017ios11iOS
이 기사는 이미 공개된WWDC2017 - Privacy and Your Apps애플 Developer 문서를 바탕으로 제작됐다.베타 버전으로 기사가 났을 때는 앞으로 규격 변경 등에 따라 다를 수 있기 때문이다.사전에 양해해 주십시오.
만약 보도에 또 오류가 있다면 지적해 주십시오.
iOS 11에서 DeviceCheck이라는 프레임워크와 서버 측면의 API가 추가되었습니다.이를 통해 각 장치가 연결하고자 하는 정보를 간단하게 설정하고 얻을 수 있다.

DeviceCheck이란



인용자 WWDC2017 Privacy and Your Apps
  • 이전에 이 장치에서 무료 체험을 해 본 적이 있습니까?
  • 청구 계정은 아니지만 이전에 해당 장치에서 지불한 적이 있습니까?
  • 불법 사용자가 이 장치를 사용한 적이 있습니까?
  • ...장치 단위의 제한 상태와 사용 상태를 확인할 때 활발하다.
    디바이스 식별하면 이전에도 UDID, MAC 주소, Push 알림의 영패 등 각종 고유 식별자를 사용할 때가 있었지만, 애플이 대책을 강구해 사용할 수 없었다.
    UUID를 생성하여 키체인에 저장하는 방법이나 IDFV(Identifier for Vendor)를 사용하여 식별할 수 있지만 응용프로그램 삭제, 초기화(복원)로 인해 식별자가 사라집니다.
    DeviceCheck은 2비트(최대 4개 표시)와 타임 스탬프를 애플 서버에 기록합니다.이렇게 되면 App의 삭제, 디바이스의 복구 및 재설정으로 인해 레코드가 사라지지 않습니다.

    대략적인 절차


    어플리케이션을 처음 설치하는 경우

    인용자 WWDC2017 Privacy and Your Apps
    어플리케이션 제거 또는 재설치 시

    인용자 WWDC2017 Privacy and Your Apps
    먼저 클라이언트 호출generateToken에서 임시 영패를 받습니다.
    그런 다음 이 토큰을 API 서버에 던집니다.서버 측은 기밀 키를 이용해 JWT(JSON WebToken)를 생성합니다.고객으로부터 받은 토큰과 거래 ID, 타임 스탬프를 JSON 인코딩하여 애플의 API에 던져 장치와 관련된 정보를 얻거나 설정합니다.
    정보를 얻으면 서버 측에서 동작을 허용할지 여부를 판정합니다.

    서버 측 설치 예


    설치 시 애플에서 기밀 열쇠를 미리 받아야 한다.키는 Celtificates, Identifiers & Profiles의 Keys에서 만들 수 있습니다.
    키를 만들려면 CSR이 필요합니다.여기 참고해주세요. 제작해주세요.
    기밀 키를 다시 다운로드할 수 없습니다.열쇠를 잃어버리거나 유출했을 가능성이 있다면 리보크를 다시 만들어주세요.
    이외에도 JWT를 생성할 때
  • 개인 키 ID(Keys에서 볼 수 있음)
  • 개발 계정의 TeamID
  • 필요이쪽도 미리 조사해 주세요.
    준비 후 애플 문서 참조 서버 측면을 설치합니다.여기서는 PHP7을 사용합니다.
    composer
    composer require zenstruck/jwt ramsey/uuid
    
    requestToken.php
    <?php
    require_once "vendor/autoload.php";
    use Zenstruck\JWT\Token;
    use Zenstruck\JWT\Signer\OpenSSL\ECDSA\ES256;
    use \Ramsey\Uuid\Uuid;
    
    //  _POSTからdeviceTokenを受け取り
    $deviceToken = (isset($_POST["deviceToken"]) ? $_POST["deviceToken"] : null);
    
    function generateJWT($teamId, $keyId, $privateKeyFilePath) {
        $payload = [
            "iss" => $teamId,
            "iat" => time()
        ];
    
        $header = [
            "kid" => $keyId
        ];
    
        $token = new Token($payload, $header);
        return (string)$token->sign(new ES256(), $privateKeyFilePath);
    }
    
    function postRequest($url, $jwt, $bodyArray) {
        $body = json_encode($bodyArray);
    
        $header = [
            "Authorization: Bearer ". $jwt,
            "Content-Type: application/x-www-form-urlencoded",
            "Content-Length: ".strlen($body)
        ];
    
        $context = [
            "http" => [
                "method"  => "POST",
                "header"  => implode("\r\n", $header),
                "content" => $body
            ]
        ];
    
        return file_get_contents($url, false, stream_context_create($context));
    }
    
    $teamId = "TEAMID";
    $keyId = "KEYID";
    $privateKeyFilePath = "PRIVATE KEY FILE PATH";
    $jwt = generateJWT($teamId, $keyId, $privateKeyFilePath);
    
    //  情報の取得
    $body = [
        "device_token" => $deviceToken,
        "transaction_id" => Uuid::uuid4()->toString(),
        "timestamp" => ceil(microtime(true)*1000) // time()だとだめでした
    ];
    postRequest("https://api.development.devicecheck.apple.com/v1/query_two_bits", $jwt, $body);
    //  まだ情報を設定していない場合は、"Failed to find bit state"と返されます。
    //  設定している場合はこんな形で帰ってきます。
    //  {"bit0":true,"bit1":false,"last_update_time":"2017-06"}
    
    
    //  情報の設定
    $body = [
        "device_token" => $deviceToken,
        "transaction_id" => Uuid::uuid4()->toString(),
        "timestamp" => ceil(microtime(true)*1000),
        "bit0" => true,
        "bit1" => false
    ];
    
    postRequest("https://api.development.devicecheck.apple.com/v1/update_two_bits", $jwt, $body);
    
    서버 측의 설치 예는 다음과 같다.상황에 따라 값을 얻는 판정 처리와 업데이트를 진행하십시오.

    클라이언트 설치 예


    DeviceCheck 프레임워크를 가져오고 사용합니다.
    여기서는 Alamofire 투척 영패를 사용합니다.
    참고로 디버깅하는 곳이 시뮬레이터라면 구축할 수 없으니 실제 컴퓨터를 향해 가세요.
    ViewController.swift
    import UIKit
    import DeviceCheck
    import Alamofire
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            self.requestToken()
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
        fileprivate func requestToken() {
            DCDevice.current.generateToken {
                (data, error) in
                guard let data = data else {
                    return
                }
    
                let token = data.base64EncodedString()
                //  トークンをサーバーに投げる
                let url = "https://hogehogehoge.com/v1/request_token"
                let params = ["deviceToken": token]
                Alamofire.request(url, method: .post, parameters: params).responseString {
                    (request) in
                    //  ここで処理
                    print(request.value)
                }
            }
        }
    }
    

    주의 사항

  • 장비가 매매 및 양도된 경우
  • DeviceCheck은 장치의 초기화 이외의 식별을 할 수 있기 때문에 장치 소유자가 변하거나 관련 계정이 변할 때 정보를 업데이트하는 처리가 필요하다.DeviceCheck API에서 정보를 얻으면 최종 업데이트 날짜를 얻을 수 있기 때문에 이것에 따라 처리할 수 있습니다.
    그나저나 마지막 경신일은 YYY-MM으로 돌아왔습니다.날짜와 시간이 생략됐네요...

    감상


    DeviceCheck API를 사용하여 장치 및 정보를 간단하게 연결할 수 있습니다.정보량이 적지만 일반적으로 사용하면 문제가 없고 가장 중요한 것은 설비가 초기화되어도 정보가 연결되어 있다는 것이다.

    참고 자료


    [iOS11] 판정을 처음 시작하는 데 사용되는 DeviceCheck 프레임워크는 #WDC17입니다.
    Accessing and Modifying the Per-Device Data
    iOS 푸시 알림 발송 시 토큰 인증이 가능하기 때문에 조사해봤습니다.

    좋은 웹페이지 즐겨찾기