푸시 알림을 위한 서버 설정

Google Play에서는 발생하는 이벤트에 대한 응답으로 알림을 생성함 기업에 영향을 미칠 수 있습니다 EMM 솔루션 제공업체는 이에 대해 적절한 조치를 취할 수 있도록 하는 경보 또는 기타 메커니즘을 액세스할 수 있습니다

이 가이드에서는 필요한 서버 인프라를 구성하는 방법을 설명합니다. EMM 푸시 알림만 수신하고 처리합니다. 풀 알림은 이 가이드에 설명된 설정이 필요하지 않습니다.

본 가이드에서 설명하는 서버 설정과 더불어 또한 적절한 권한을 부여하고 다른 구성도 수행해야 합니다. 할 수 있습니다. 자세한 내용은 EMM 푸시 알림 사용 설정하기 참조하세요.

예시를 포함하여 Google Cloud Pub/Sub에 대한 자세한 내용은 다음을 참조하세요. Cloud Pub/Sub 문서

사용자의 컴퓨터에서 푸시 알림이 전송되도록 시스템을 또는 알림 전송을 기다리는 서버에 연결할 수 있습니다.

푸시 엔드포인트 구성 정보

푸시 엔드포인트를 구성하려면 유효한 SSL 인증서가 있는 서버가 필요합니다. 포함 이 예시에서는 SSL 인증서를 만들어 인증 기관에 (CA)인 다음 NGINX 서버를 구성합니다. 마지막으로 테스트 코드를 컴파일하고 실행하여 설정이 올바른지 확인합니다.

이 예에서는 NGINX 서버 구독자 앱에 연결하기 위한 리버스 프록시 모드 (PushSubscriber.java) 포트 8093에서 실행(Ubuntu 14.04 사용) 기업에서는 샘플 설정이 변경 없이 모든 Debian 기반 환경에서 작동해야 합니다. 있습니다. 다른 배포판 (예: RedHat에 기반한 분포)도 유사합니다. 구성 파일의 위치는 다를 수 있습니다.

알림을 수신하려면 먼저 다음 기준을 충족해야 합니다.

  • 도메인을 소유하고 Google API 콘솔.

  • 포트 443 (SSL)에서 서비스를 실행할 수 있어야 합니다.

  • CA 서명 SSL 인증서가 있어야 합니다. 자체 서명된 인증서는 작동하지 않습니다.

  • 실행 중인 웹 서버는 웹훅

Google App Engine에서 실행될 필요는 없지만 엔드포인트가 꼭 실행되어야 하는 것은 아닙니다.

SSL 인증서 만들기 및 업로드

1. 보안 소켓 레이어 (SSL) 인증서를 만듭니다.

    myusername@myhost:/tmp$ sudo openssl req -x509 -nodes -days 365 \
      -newkey rsa:2048 -keyout cert.key -out cert.crt

그러면 다음과 같은 응답이 생성됩니다. 샘플 값 바꾸기 (예: push.solarmora.com, myusername@myhost) 이름, 회사, 주소 등을 다음 코드에 넣습니다. 이 하위 도메인의 A 레코드가 서버를 가리키고 있어야 합니다.

    Generating a 2048 bit RSA private key
    ...........................................................................
    .....+++
    writing new private key to 'cert.key'
    -----
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [AU]:GB
    State or Province Name (full name) [Some-State]:England
    Locality Name (eg, city) []:London
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:Solarmora, Inc.
    Organizational Unit Name (eg, section) []:Creative Publications
    Common Name (e.g. server FQDN or YOUR name) []:push.solarmora.com
    Email Address []:admin@solarmora.com

2. 인증서 파일이 생성되었는지 확인합니다.

$ myusername@myhost:/tmp$ ls cert*
cert.crt  cert.key

3. 이 인증서에 서명하려면 인증서 서명 요청 (CSR)을 사용하여 서명자에 업로드합니다.

myusername@myhost:/tmp$ sudo openssl x509 -x509toreq -in cert.crt \
  -out cert.csr -signkey cert.key
Getting request Private Key
Generating certificate request
myusername@myhost:/tmp$ ls cert.*
cert.crt  cert.csr  cert.key

4. CSR 파일의 내용이 다음과 같은지 확인합니다.

    Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=GB, ST=England, L=London, O=Solarmora, Inc.,
        OU=Creative Publications,
        CN=push.solarmora.com/emailAddress=admin@solarmora.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:cc:0f:54:26:3d:d9:17:eb:8f:6c:f7:27:5e:77:
                    64:65:00:db:fe:2a:1f:fa:ea:de:21:7a:c5:5d:87:
                    ...
                    ...
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
         1d:ea:12:b8:c2:6a:d6:f4:6e:92:2f:b9:12:5e:e3:91:15:a0:
         06:b5:81:ce:c5:cf:b7:d2:a7:dd:f2:78:ca:28:8e:21:cd:6d:
         ...
         ...
    -----BEGIN CERTIFICATE REQUEST-----
    MIIC6zCCAdMCAQAwgaUxCzAJBgNVBAYTAkdCMRAwDgYDVQQIDAdFbmdsYW5kMQ8w
    DQYDVQQHDAZMb25kb24xGDAWBgNVBAoMD0FDTUUgQ29ycCwgSW5jLjEYMBYGA1UE
    CwwPQ3JlYXRpdmUgQW52aWxzMRswGQYDVQQDDBJwdXNoLmFjbWUtY29ycC5jb20x
    IjAgBgkqhkiG9w0BCQEWE2FkbWluQGFjbWUtY29ycC5jb20wggEiMA0GCSqGSIb3
    ...
    ...
    -----END CERTIFICATE REQUEST-----

5. 인증서의 일부를 BEGIN 사이에 업로드하세요. 및 END 행 (포함)을 CA에 추가합니다. 정확한 과정은 다음 단계가 포함됩니다.

  1. CSR 파일을 CA 사이트에 업로드하거나 파일의 콘텐츠를 CA 사이트에 붙여넣습니다. 그러면 CA가 이 데이터의 유효성을 검사하고 처리합니다.
  2. CA에서 생성한 서명된 인증서를 다운로드합니다.

6. CA의 출력에는 다음과 같은 여러 파일이 포함되어야 합니다. 서명된 인증 자체에 대해 인증을 받았는지 확인하는 CA의 인증서를 서명합니다. 다운로드한 인증서의 모든 *.crt 인증서 파일을 연결합니다. 단일 번들 파일로 묶습니다(예: bundle.push.solarmora.com.crt).

$ cat *.crt > bundle.push.solarmora.com.crt

프록시 서버 구성

이 섹션에서는 NGINX 오픈소스 웹 서버를 구성하고 그 반대로 합니다. 프록시 서버를 사용하여 엔드포인트에 서비스를 제공하고 모든 수신 요청을 있습니다. NGINX가 예시로 사용되지만 다른 HTTP 프록시를 대신 사용하세요.

1. 서버에 NGINX를 설치합니다.

    $ sudo apt-get update
    $ sudo apt-get install nginx
    $ nginx -v
    $ nginx version: nginx/1.4.6 (Ubuntu)

2. 추가 서버 구성 파일이 sites-enabled 디렉터리가 NGINX에서 처리됩니다. /etc/nginx/nginx.conf을(를) 수정하세요. 다음을 포함해야 합니다.

    $ include /etc/nginx/conf.d/*.conf;
    $ include /etc/nginx/sites-enabled/*;

3. 인증서 파일을 다음 사용자가 읽을 수 있는 안전한 위치에 복사합니다. www-data 사용자이지만 다른 사용자는 읽을 수 없는 것이 좋습니다. 웹 서버가 다른 사용자):

    $ sudo mkdir -p /var/openssl/push.solarmora.com
    $ sudo mv /tmp/cert.key 
/var/openssl/push.solarmora.com/push.solarmora.com.key $ sudo mv /tmp/bundle.push.solarmora.com.crt
/var/openssl/push.solarmora.com/bundle.push.solarmora.com.crt

4. 새 server 구성을 만듭니다. push.solarmora.com 수정 /etc/nginx/sites-enabled에서 실제 서버의 정규화된 도메인 이름을 파일 이름으로 사용합니다.

server {
   listen 443;
   server_name push.solarmora.com;

   ssl on;
   ssl_certificate
     /var/openssl/push.solarmora.com/bundle.push.solarmora.com.crt;
   ssl_certificate_key
     /var/openssl/push.solarmora.com/push.solarmora.com.key;

   # it is usually very convenient to have separate files for your
   # access and error log to analyze for possible problems
   access_log /var/log/nginx/nginx.push.solarmora.com.log;
   error_log /var/log/nginx/nginx.push.solarmora.com.log;

   location / {
            # assuming the subscriber will run on the same machine
            # on port 8093
            proxy_pass http://localhost:8093;
   }
}

5. NGINX를 다시 시작하여 변경사항을 구현합니다.

    myusername@myhost:/etc/nginx$ sudo service nginx restart
    * Restarting nginx nginx
    ...done.

6. 이제 서버가 구성되었습니다. curl를 사용하여 서버를 쿼리해 보세요.

    [myusername@myhost:~]$ curl push.solarmora.com
    <html>
    <head><title>502 Bad Gateway</title></head>
    <body bgcolor="white">
    <center><h1>502 Bad Gateway</h1></center>
    <hr><center>nginx/1.4.6 (Ubuntu)</center>
    </body>
    </html>

다운스트림 서버가 구성되지 않은 경우 예상되는 응답입니다. (구성 파일의 localhost:8093)

예시 컴파일 및 실행

이 섹션의 예를 실행하려면 활성 Google API 콘솔이 필요합니다. 살펴보겠습니다 테스트용으로 특별히 하나를 만드는 것이 좋으며 프로덕션 프로젝트와 별도로 유지합니다 테스트 프로젝트를 만든 후에는 서비스 계정을 만들어야 합니다. 서비스 계정 이메일 주소를 기록하고 연결된 .p12 파일을 서버에 둡니다.

소스 코드 트리 설정

1. play-work.git 저장소를 복제합니다.

    myusername@myhost:~/code$ git clone
    https://github.com/google/play-work.git
    Cloning into 'play-work'...
    Username for 'https://github.com': username
    Password for 'https://username@github.com':
    remote: Counting objects: 110, done.
    remote: Compressing objects: 100% (60/60), done.
    remote: Total 110 (delta 24), reused 95 (delta 9), pack-reused 0
    Receiving objects: 100% (110/110), 23.88 KiB | 0 bytes/s, done.
    Resolving deltas: 100% (24/24), done.
    Checking connectivity... done.
드림 2. Debian 기반 시스템에서는 MavenGoogle 프로토콜 버퍼 컴파일러:
    $ sudo apt-get install maven protobuf-compiler

3. Maven과 Google 프로토콜 버퍼 컴파일러가 모두 설치되었습니다.

    myusername@myhost:~$ mvn -v
    Apache Maven 3.0.5
    Maven home: /usr/share/maven
    Java version: 1.7.0_75, vendor: Oracle Corporation
    Java home: /usr/lib/jvm/java-7-openjdk-amd64/jre
    Default locale: en_US, platform encoding: UTF-8
    OS name: "linux", version: "3.16.0-30-generic", arch: "amd64", family: "unix"
    myusername@myhost:~$ protoc --version
    libprotoc 2.5.0

4. Maven 구성 파일 pom.xml는 프로토콜 버퍼 컴파일러가 /usr/bin/protoc 디렉터리에 설치되어 있다고 가정합니다.

    myusername@myhost:~$ which protoc
    /usr/bin/protoc
드림 그렇지 않은 경우 pom.xml 또는 심볼릭 링크 protoc를 수정하면 됩니다.
    $ sudo ln -s which protoc /usr/bin/protoc
드림 5. 예시를 컴파일합니다. mvn clean compile assembly:single를 실행하여 코드를 빌드할 수 있는지 확인합니다. 그러면 이름이 emm-notifications-[version-number]-jar-with-dependencies.jar, 각 항목의 의미는 다음과 같습니다. [version number]는 예시의 현재 버전입니다(예: 1.0-SNAPSHOT).
    myusername@myhost:~/code/play-work/examples/emm-notifications$ ls target/*
    target/emm-notifications-1.0-SNAPSHOT-jar-with-dependencies.jar
드림 여섯째, 컴파일된 TestPublisher 코드를 실행할 수 있는지 확인합니다. 코드가 실패할 것으로 예상됩니다.

    myusername@myhost:~/code/play-work/examples/emm-notifications$ java -cp \
      target/emm-notifications-1.0-SNAPSHOT-jar-with-dependencies.jar \
      com.google.android.work.emmnotifications.TestPublisher
    Exception in thread "main" java.lang.IllegalArgumentException:
    You must specify non-default ServiceAccountEmail in
    settings.properties
        at com.google.api.client.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:119)
        at com.google.api.client.util.Preconditions.checkArgument(Preconditions.java:69)
        at com.google.android.work.emmnotifications.Settings.verifyVariable(Settings.java:129)
        at com.google.android.work.emmnotifications.Settings.getSettings(Settings.java:103)
        at com.google.android.work.emmnotifications.TestPublisher.main(TestPublisher.java:39)

7. settings.properties 파일에서 일부 값을 재정의해야 합니다. 이렇게 하려면 파일 사본을 만들고 사본의 속성을 다음과 같이 수정합니다.

    # This should be your own service account's email address
    ServiceAccountEmail=368628613713-t4hfexampledn5lhpdcu1qqfgio01626@developer.gserviceaccount.com
    ServiceAccountP12KeyFile=/opt/secret/secret.p12
    # This will be the name of the service account
    ProjectName=enterprise-cloud-pub-sub
    SubscriptionName=projects/enterprise-cloud-pub-sub/subscriptions/default
    TopicName=projects/enterprise-cloud-pub-sub/topics/default
    # The push endpoint in your API Console project
    PushEndpoint=https://push.solarmora.com

8. TestPublisher 코드를 다시 실행하여 더 이상 비정상 종료되지 않도록 합니다. ( 단일 오류를 나타낼 수 있습니다.)

게시자 테스트 코드 실행

알림을 게시하기 위한 샘플 코드를 실행해야 구독자가 몇 개의 메시지를 읽을 수 있습니다.

다음 예에서 코드는 주제가 my_settings.properties에 지정되어 있지만 찾지 못해 주제를 만듭니다. 그런 다음 주제에 메시지를 게시합니다. 이 예시에서는 Google Play EMM API에서 보낸 메시지를 에뮬레이션할 수 있는 테스트 도구입니다.

    myusername@myhost:~/code/play-work/examples/emm-notifications$ DEVELOPER_CONSOLE_SETTINGS=./my_settings.properties java -cp \
      target/emm-notifications-1.0-SNAPSHOT-jar-with-dependencies.jar com.google.android.work.emmnotifications.TestPublisher
    Feb 27, 2015 1:39:59 PM com.google.android.work.emmnotifications.RetryHttpInitializerWrapper$1 handleResponse
    INFO: RetryHandler: {
      "error": {
        "code": 404,
        "message": "Resource not found (resource=default).",
        "errors": [
          {
            "message": "Resource not found (resource=default).",
            "domain": "global",
            "reason": "notFound"
          }
        ],
        "status": "NOT_FOUND"
      }
    }

    Feb 27, 2015 1:39:59 PM com.google.android.work.emmnotifications.TestPublisher main
    INFO: Topic projects/enterprise-cloud-pub-sub/topics/default doesn't exists, creating it
    Feb 27, 2015 1:40:02 PM com.google.android.work.emmnotifications.TestPublisher main
    INFO: Topic projects/enterprise-cloud-pub-sub/topics/default created
    Feb 27, 2015 1:40:02 PM com.google.android.work.emmnotifications.TestPublisher main
    INFO: Publishing a request: {messages=[{data=CjEKFQoIMTIzMjEzMjESCXJpZ2h0IG5vdxIWY29tLmdvb2dsZS5hbmRyb2lkLmdtcxgA}]}

구독자 테스트 코드 실행

구독자 테스트 코드는 TestPublisher 코드

1. 코드가 최신 상태이고 컴파일되었는지 확인한 다음 구독자 테스트 코드:

    myusername@myhost:~/code/play-work/examples/emm-notifications$ DEVELOPER_CONSOLE_SETTINGS=./my_settings.properties 
java -cp target/emm-notifications-1.0-SNAPSHOT-jar-with-dependencies.jar
com.google.android.work.emmnotifications.PushSubscriber Feb 27, 2015 1:46:37 PM com.google.android.work.emmnotifications.PushSubscriber main INFO: Will be using topic name: projects/enterprise-cloud-pub-sub/topics/default, subscription name:
projects/enterprise-cloud-pub-sub/subscriptions/default Feb 27, 2015 1:46:38 PM com.google.android.work.emmnotifications.PushSubscriber main INFO: Trying to get subscription named projects/enterprise-cloud-pub-sub/subscriptions/default Feb 27, 2015 1:46:38 PM com.google.android.work.emmnotifications.RetryHttpInitializerWrapper$1 handleResponse INFO: RetryHandler: { "error": { "code": 404, "message": "Resource not found (resource=default).", "errors": [ { "message": "Resource not found (resource=default).", "domain": "global", "reason": "notFound" } ], "status": "NOT_FOUND" } } Feb 27, 2015 1:46:38 PM com.google.android.work.emmnotifications.PushSubscriber main INFO: Subscription doesn't exist, will try to create projects/enterprise-cloud-pub-sub/subscriptions/default Feb 27, 2015 1:46:43 PM com.google.android.work.emmnotifications.PushSubscriber main INFO: Created: { "ackDeadlineSeconds" : 600, "name" : "projects/enterprise-cloud-pub-sub/subscriptions/default", "pushConfig" : { "pushEndpoint" : "https://push.solarmora.com" }, "topic" : "projects/enterprise-cloud-pub-sub/topics/default" }
드림 구독자가 실행 중이며 수신되는 메시지를 수락할 준비가 되었습니다. 메시지를 보낼 수 있습니다

2. 게시자를 다시 실행하면 새 메시지가 로그에 다음 줄을 추가합니다.

    Feb 27, 2015 1:47:24 PM com.google.android.work.emmnotifications.PushSubscriber$1 handle
    INFO: Raw request: {"message":{"data":"CjEKFQoIMTIzMjEzMjESCXJpZ2h0IG5vdxIWY29tLmdvb2dsZS5hbmRyb2lkLmdtcxgA",
"attributes":{},"message_id":"71571141246"},"subscription":"/subscriptions/enterprise-cloud-pub-sub/default"} Feb 27, 2015 1:47:24 PM com.google.android.work.emmnotifications.PushSubscriber$1 handle INFO: Pubsub message received: { "attributes" : { }, "data" : "CjEKFQoIMTIzMjEzMjESCXJpZ2h0IG5vdxIWY29tLmdvb2dsZS5hbmRyb2lkLmdtcxgA", "message_id" : "71571141246" } Feb 27, 2015 1:47:24 PM com.google.android.work.emmnotifications.PushSubscriber$1 handle INFO: Message received: product_approval_event { common_event_information { enterprise_id: "12321321" event_notification_sent_timestamp: "right now" } product_id: "com.google.android.gms" approved: false }
드림 메일이 제대로 수신 및 처리되었습니다.