구글에서 제공하는 페이지(https://developers.google.com/cloud-print/docs/privet)를 참조해서 시험삼아 가상의 클라우드 프린터용 Privet API 서비스를 구현하고 크롬 브라우저를 이용 등록해보았다. 몇몇 사항에 대해 자세히 설명이 되어 있지 않아서 여러번 시행 착오가 있었다. 다행스럽게 등록에 성공, 여기에 자세한 내용을 기술하고 작업한 소스코드를 공유한다.
사전에 준비할 것이 있는데, 프린터용으로 사용할 OAuth 2.0 client id가 없으면 구글페이지(https://developers.google.com/identity/protocols/OpenIDConnect#registeringyourapp)를 참조해서 만든다. 만약 https://console.developers.google.com 사이트 이용법을 잘 알고 있다면 해당 사이트에서 발급받으면 된다.
등록 시나리오
등록하는 전 과정은 아래처럼 겉보기에도 여러 단계를 거치는데, 각각의 단계마다 숨겨진 작업들이 있고 이러한 작업들이 정확히 이루어져야 한다.
- 크롬 브라우저를 띄우고, 설정(고급) > 구글 클라우드 프린트 > 클라우드 프린트 기기 관리 페이지를 연다. (구글계정으로 로그인 되어 있어야 한다.)
- 프린터 프로그램 구동, 프린터는 mDNS규약에 따라 자신의 정보를 로컬망에 뿌린다.
- Privet REST API /privet/info 호출
- 크롬 브라우저 화면에 프린터가 보여지고 '등록'버튼이 나타난다.
- 크롬 브라우저 화면에 표시된 등록 버튼을 클릭
- Privet REST API /privet/register?action=start 호출
- Privet REST API /privet/register?action=getClaimToken 호출
- Privet REST API /privet/register?action=complete 호출
- Privet REST API /privet/info를 호출 (최종 확인작업)
단계 1~2, mDNS
Record Type |
QNAME |
Data |
PTR |
_privet._tcp.local |
printer's name._privet._tcp.local |
TXT |
printer's name._privet._tcp.local |
txtvers=1 ... |
SRV |
printer's name._privet._tcp.local |
웹API port, hostname |
A |
hostname |
IP address (IPv4) |
AAAA |
hostname |
IP address (IPv6) |
단계 3~4, /info
크롬 브라우저는 mDNS로 얻어진 정보를 가지고 Privet API중 'privet/info'를 호출한다. 구글측 페이지에 따르면 API를 제공하는 쪽에서 'X-Privet-Token' 헤더 정보를 확인하도록 되어 있지만 이번 구현에는 생략했다.
프린터는 JSON형식으로 프린터의 정보를 호출한 쪽(크롬브라우저)에 제공하는데, 이 때 중요한 것은 'api' 필드의 내용이다. 이 필드는 배열로 정의되는데 배열에 반드시 '/privet/register'항목이 포함되야 한다. 그렇지 않으면 '등록'버튼은 표시되지 않는다. 그리고 'id' 필드는 빈 문자열로 정의해도 된다.
단계 6, /privet/register?action=start
'등록'버튼이 눌려짐과 동시에 크롬브라우저는 등록이 시작되었음을 프린터에게 알려준다. 매개변수 'user'에 브라우저에서 구글계정으로 로그인한 사용자 아이디가 담겨 전달된다. 자세한 정보는 이 페이지 앞부분에 적혀진 구글 페이지를 참조하면 된다. 특별한 경우가 아니라면 구글 페이지에 정의된대로 응답한다.
단계 7, /privet/register?action=getClaimToken
가장 중요한 단계이다. 단계 6의 응답을 받은 크롬브라우저는 자동으로 이 API를 호출한다. 그러면 프린터는 구글 클라우드 API '/cloudprint/register'를 호출하고 받은 응답을 가지고 크롬 브라우저로 응답한다. '/cloudprint/register' API를 호출할 때, 프린터는 아래의 값들을 제출한다.
- proxy : 프린터측에서 정한 임의의 문자열을 넣는다. (자세한 내용을 확인 못함)
- printer : 프린터 이름 (privet/info에서 제공한 이름과 동일)
- capabilities : 프린터 사양 등인데 정확한 정보가 아니어도 된다. (구글 페이지 참조)
- use_cdd: true
요청에 아무 오류가 없다면 등록과 관련된 많은 정보가 담긴 응답을 받게 된다. 테스트때 받았던 응답중 하나를 예로 옮긴다.
{
"success": true,
"request": {
"time": "0",
"params": {
"proxy": [
"ZZZ"
],
"capabilities": [
"{\"version\": \"1.0\"}"
],
"printer": [
"ZCUBEPRN"
],
"printerid": [
"1ddd6ccc5-3eee-bccc-7871-0001999abcce"
],
"use_cdd": [
"true"
]
}
},
"printers": [
{
"isTosAccepted": false,
"capabilities": {
"version": "1.0"
},
"displayName": "ZCUBEPRN",
"description": "",
"capsHash": "",
"updateTime": "...",
"type": "GOOGLE",
"notificationChannel": "XMPP_CHANNEL",
"tags": [
"__cp_printer_passes_..."
],
"gcpVersion": "1.0",
"proxy": "ZZZ",
"createTime": "...",
"defaultDisplayName": "",
"name": "ZCUBEPRN",
"id": "333d6cc66-3ee1-bcee-7871-0001999abcce",
"status": "",
"accessTime": "..."
}
],
"complete_invite_url": "https://goo.gl/printe...",
"invite_url": "https://www.google.com/cloudprint/claimprinter.html",
"oauth_scope": "https://www.googleapis.com/auth/cloudprint",
"invite_page_url": "https://www.google.com/cloudprint/regtokenpage?...",
"registration_token": "....",
"token_duration": "....",
"automated_invite_url": "https://www.google.com/cloudprint/conf...",
"polling_url": "https://www.google.com/cloudprint/getauthcode?printerid..."
}
등록과정시 반드시 챙겨둘 항목
- printers[0].id : 프린터 아이디 (등록때마다 값이 달라진다.)
- polling_url : 단계 8에서 사용될 URL (getauthcode URL로 직접 만들어도 된다.)
그리고 크롬브라우저로 보낼 정보들을 확인해서 응답한다.
- registration_token ===> token
- invite_url ===> claim_url
단계 8, /privet/register?action=complete
크롬 브라우저는 단계7의 응답을 받으면 자동으로 이 API를 호출한다. 프린터는 단계7에서 챙겨두었던 'polling_url'을 사용해서 구글 API를 호출한다. 이 URL은 printer id와 프린터용으로 사용할 oauth 2.0 client id를 가지고 직접 구성할 수도 있다.
'polling_url'은 대개 'https://...getauthcode?printerid=....&oauth_client_id='까지 구성되어 있다. 여기에 발급받은 client id를 덧붙여 호출하면 된다.오류가 없다면 아래와 같은 메시지를 받게 되며, 크롬 브라우저로 'device_id'에 프린터 아이디를 설정 해서 응답한다.
{
"success": true,
"xmpp_jid": "....@cloudprint.googleusercontent.com",
"confirmation_page_url": "https://www.google.com/cloudprint/regc ...",
"request": {
"time": "0",
"params": {
"printerid": [
"...."
],
"oauth_client_id": [
".....apps.googleusercontent.com"
]
}
},
"user_email": "user@gmail.com",
"authorization_code": "...."
}
단계 9, 최종 확인작업
이 단계의 작업 또한 정확히 이루어져야 등록이 성공한다. 크롬 브라우저는 최종 확인작업을 위해 프린터의 '/privet/info'를 다시 호출하는데, 이 때 응답정보에는 아래의 사항이 지켜져야 한다.
- 'id' 값은 앞단계에서 전달한 'device_id' 값과 같아야 한다.
- 'api' 배열에 '/privet/regist' 항목이 없어야 한다.
마치며
'Maker Movement' 카테고리의 다른 글
DDNS(Google Domains), 집에 있는 라즈베리파이 설정 (0) | 2018.12.15 |
---|---|
자바유료화 대책 (0) | 2018.09.25 |
구글 클라우드 프린트(3) - 프린터인식 (0) | 2017.12.23 |
구글 클라우드 프린트(2) - mDNS 구현 (0) | 2017.11.30 |
구글 클라우드 프린트(1) - 들어가기 (0) | 2017.11.19 |