GDK Glassware에서 웹 서비스에 대해 사용자를 인증해야 하는 경우 GDK는 사용자가 Glassware를 설치할 때 사용자 인증 정보를 입력할 수 있는 API를 제공합니다.
이 API를 사용하면 Glass 사용자에게 일관된 사용자 환경을 제공하고 자체 맞춤 인증 스키마를 구현하는 오버헤드를 방지할 수 있습니다.
Google API 서비스 계정 만들기
인증이 올바르게 설정되면 웹 앱의 백엔드는 Mirror API를 사용하여 사용자가 서비스로 인증한 후 사용자의 계정 정보를 Glass에 푸시합니다.
이 API에 액세스하려면 Google API 프로젝트를 만든 다음 '웹 애플리케이션'이 아닌 '서비스 계정'의 클라이언트 ID를 만듭니다. 서비스 계정을 사용하면 사용자가 사용자 인증 정보를 Glass에 푸시할 수 있는 권한을 애플리케이션에 별도로 부여할 필요가 없으며 OAuth 권한 페이지와 자체 인증 페이지가 모두 다시 표시되지 않습니다.
이 계정을 만들려면 다음 단계를 따르세요.
- Google Developers Console로 이동합니다.
- 프로젝트 만들기 버튼을 클릭하고 요청된 정보를 입력합니다.
- 프로젝트가 생성되면 나중에 필요하므로 프로젝트 번호를 기록합니다.
- API 및 인증에서 API를 클릭하고 새 프로젝트에 Google Mirror API를 사용 설정합니다.
- API 및 인증에서 사용자 인증 정보를 클릭한 다음 새 클라이언트 ID 만들기를 클릭합니다. 서비스 계정 체크박스를 선택하여 프로젝트의 새 OAuth 2.0 클라이언트 ID를 만듭니다.
- 비공개 키가 컴퓨터에 다운로드되고 있음을 알리는 팝업 창에서 비공개 키의 비밀번호를 확인할 수 있습니다. 이 창을 닫으면 이 비공개 키를 다운로드하거나 비밀번호를 다시 볼 수 없습니다. 분실한 경우 새 키를 만들어야 합니다.
- 나중에 API를 호출할 때 필요한 서비스 계정의 이메일 주소를 기록해 둡니다.
Glassware에 대한 메타데이터 제공
Glass 소프트웨어를 제출할 준비가 되면 다음 정보를 제공해야 합니다. 이렇게 하면 Google에서 Glass 소프트웨어를 구현할 때 올바르게 인증되도록 설정할 수 있습니다.
- 인증 URL: 사용자가 MyGlass에서 Glass 소프트웨어를 켤 때 리디렉션되는 사용자
- 계정 유형 (Glass 기기에서 Android
AccountManager
API를 호출할 때 사용하는 문자열) AndroidManifest.xml
의 애플리케이션 패키지 이름- 위에서 만든 프로젝트의 숫자 Google API 프로젝트 ID
- MyGlass에 업로드할 APK 테스트의 경우 MyGlass에서 Glassware를 사용 설정할 때 초기 다운로드를 처리하기 위해 이 APK를 한 번만 제공하면 됩니다. 그 후에는 기기에서 APK를 덮어써서 로컬에서 반복하고 디버그할 수 있습니다. 이 APK는 다음 기준을 충족해야 합니다.
- 압축 정렬되어야 합니다.
- 이후에 패키지 이름이나 비공개 서명 키를 변경하면 안 됩니다. 이러한 변경사항 중 하나가 변경되면 Android 패키지 관리자가 업그레이드를 허용하지 않습니다.
- 50MB 미만이어야 합니다.
- 최신 버전의 GDK를 사용하여 컴파일해야 합니다.
인증 흐름 구현
다음 다이어그램은 GDK Glassware의 기본 인증 흐름을 보여줍니다.
인증 흐름을 구현하려면 다음 단계를 따르세요.
사용자가 MyGlass에서 Glass 소프트웨어를 켜면 인증 URL로 리디렉션됩니다. 이러한 요청에는 나중에 사용해야 하는
userToken
라는 쿼리 매개변수가 포함됩니다.사용자가 인증 페이지에 사용자 인증 정보를 입력합니다.
서버가 사용자의 사용자 인증 정보를 확인합니다. 사용자 인증 정보가 유효하면
mirror.accounts.insert
메서드에 Mirror API를 호출합니다. 이 메서드를 사용하려면 미러 서비스 객체를 빌드할 때https://www.googleapis.com/auth/glass.thirdpartyauth
범위를 지정해야 합니다. 원시 HTTP 또는 Java를 사용하여 이 API를 호출하는 예는 계정 생성 예에 나와 있습니다.아래에 제공하는 매개변수와 요청 본문은 기기에서 직접 계정을 만드는 경우 Android의
AccountManager
에 제공하는 것과 동일한 정보를 나타냅니다.속성 이름 값 설명 features[]
문자열 목록 기능 목록입니다( AccountManager.hasFeatures
참고).password
문자열 계정 비밀번호( AccountManager.getPassword
참고). 이 필드에 사용자의 실제 비밀번호를 저장하지 마시고 대신 새로고침 토큰과 같은 장기 비공개 데이터를 저장하는 데 사용하는 것이 좋습니다.userData[]
객체 목록 계정과 연결된 하나 이상의 사용자 데이터 쌍입니다( AccountManager.getUserData
참고).userData[].key
문자열 특정 사용자 데이터 키-값 쌍과 연결된 키입니다. userData[].value
문자열 특정 사용자 데이터 키-값 쌍과 연결된 값입니다. authTokens[]
객체 목록 계정과 연결된 하나 이상의 인증 토큰입니다( AccountManager.getAuthToken
참조).authTokens[].type
문자열 인증 토큰의 유형입니다. authTokens[].authToken
문자열 인증 토큰 mirror.account.insert
요청을 수신하면 Mirror API는 계정을 사용자의 Glass 기기로 푸시합니다. 이제 사용자는AccountManager
클래스를 사용하여 이 기기에 액세스할 수 있습니다.
권장되는 인증 흐름
다음 가이드라인에 따라 사용자 친화적인 인증 흐름을 구현하세요.
- 모바일 기기에 맞게 플로우를 최적화하세요.
- 흐름에 범위가 있고 사용자가 흐름을 취소하는 경우 잘 설계된 오류 메시지를 표시합니다.
- 요청한 범위가 Glassware에서 실제로 사용되고 있는지 확인합니다.
- 사용자 계정을 연결할 수 있는 경우 연결해야 합니다.
- 가능하면 사용자 데이터를 클라우드에 백업해야 합니다.
Glassware 인증의 일관성을 유지하려면 다음 인증 흐름 중 하나를 사용하세요.
계정 없이 미러링 또는 하이브리드
- MyGlass에서 사용 설정하면 인증 URL이 팝업으로 열립니다.
- 이렇게 하면 사용자는 수락할 범위로 바로 이동합니다.
- 사용자가 범위를 수락하거나 취소하면 팝업을 닫습니다.
계정으로 미러링
- MyGlass에서 전환하고 나면 인증 URL이 팝업에서 열립니다.
- 사용자가 이미 서비스에 로그인했다면 사용자를 직접 범위로 보냅니다.
- 사용자가 로그인하지 않은 경우 로그인 필드를 표시하고 사용자가 서비스에 로그인하도록 허용한 후 범위로 전송합니다.
- 사용자에게 계정이 없는 경우 계정 생성 링크를 제공합니다. 사용자는 설치 흐름 프로세스의 일부로 계정을 만들 수 있는 방법이 있어야 합니다.
- 사용자가 범위를 수락합니다.
- Glass 소프트웨어에 구성 가능한 설정이 있는 경우 적절한 기본값이 선택된 설정 페이지로 사용자를 보냅니다.
- Glassware에 구성 가능한 설정이 없는 경우 사용자를 확인 페이지로 이동합니다. 추가 구성이 필요하지 않으면 팝업을 닫습니다.
계정과 함께 하이브리드
- MyGlass에서 사용 설정하면 인증 URL이 팝업으로 열립니다.
- 사용자가 이미 서비스에 로그인한 경우 사용자를 직접 범위로 전송합니다.
- 사용자가 로그인하지 않은 경우 로그인 필드를 표시하고 사용자가 로그인하도록 허용한 후 범위로 전송합니다.
- 사용자에게 계정이 없는 경우 계정 생성 링크를 제공합니다.
- 사용자가 범위를 수락합니다.
- Mirror API에 요청을 전송하여 GDK 계정을 삽입합니다.
- 적절한 기본값이 선택된 설정 페이지로 사용자를 전송합니다.
- 사용자에게 확인 페이지를 보냅니다. 추가 구성이 필요하지 않으면 팝업을 닫습니다.
계정 및 맞춤 범위로 미러링 또는 하이브리드
- MyGlass에서 사용 설정하면 인증 URL이 팝업으로 열립니다.
- 사용자가 이미 서비스에 로그인되어 있는 경우 사용자를 내부 범위로 전송
- 사용자가 로그인하지 않은 경우 로그인 필드를 표시하고 사용자가 로그인할 수 있도록 허용한 다음 내부 범위로 전송합니다.
- 사용자에게 계정이 없는 경우 계정 생성 링크를 제공합니다.
- 사용자가 맞춤 범위를 수락하면 사용자를 Google의 범위로 안내합니다.
- Mirror API에 요청을 전송하여 GDK 계정을 삽입합니다.
- 적절한 기본값이 선택된 설정 페이지로 사용자를 전송합니다.
- 사용자에게 확인 페이지를 보냅니다. 추가 구성이 필요하지 않으면 팝업을 닫습니다.
Android/iPhone 앱으로 미러 또는 하이브리드 모드 사용
- MyGlass에서 사용 설정하면 인증 URL이 팝업으로 열립니다.
- 이렇게 하면 사용자는 수락할 범위로 바로 이동합니다.
- 사용자가 범위를 수락한 후:
- 사용자가 호환 앱을 보유하고 인증된 경우 팝업 창을 닫습니다.
- 그렇지 않은 경우 사용자를 Google Play 스토어 또는 iOS 스토어에서 앱을 다운로드하도록 안내하는 전면 광고로 연결합니다.
- 앱을 설치하고 인증한 후 팝업 창을 닫습니다.
GDK 및 계정 없음
이 흐름에 필요한 작업은 MyGlass에서 Glassware를 사용 설정하는 것뿐입니다.
계정이 있는 GDK
- MyGlass에서 사용 설정하면 인증 URL이 팝업으로 열립니다.
- 사용자가 이미 서비스에 로그인한 경우 사용자를 확인 화면으로 이동합니다.
- 사용자가 로그인되어 있지 않으면 로그인 필드를 표시하고 사용자가 로그인할 수 있도록 허용한 다음 확인 화면으로 전송합니다.
- 사용자에게 계정이 없는 경우 계정을 만들 수 있는 링크를 제공합니다.
- 사용자가 범위를 수락합니다.
- Mirror API에 요청을 전송하여 GDK 계정을 삽입합니다.
- 확인 화면을 표시하고 잠시 표시한 후 화면을 닫습니다.
계정 생성 예
가능하면 Mirror API의 클라이언트 라이브러리를 사용합니다. 이렇게 하면 mirror.accounts.insert
를 호출하여 계정을 더 쉽게 만들 수 있습니다.
원시 HTTP 예시
아래 예에서는 요청의 URL과 예상되는 JSON 본문의 예시만 보여줍니다. 서비스 계정을 대신하여 원시 HTTP 요청을 보내는 것은 훨씬 더 복잡합니다(자세한 내용은 서버 간 애플리케이션에 OAuth 2.0 사용 참고). 따라서 가능하면 Google API 클라이언트 라이브러리 중 하나를 사용하여 이 작업을 더 쉽게 하는 것이 좋습니다.
요청 메서드 및 URL:
POST https://www.googleapis.com/mirror/v1/accounts/{userToken}/com.example.myapp/username%40email.com
요청 본문:
{
"features": ["a", "b", "c"],
"userData": [
{ "key": "realName", "value": "Rusty Shackleford" },
{ "key": "foo", "value": "bar" }
],
"authTokens": [
{ "type": "your_token_type", "authToken": "zT419Ma3X2pBr0L..." }
]
}
요청 URL의 {userToken}
를 인증 흐름 구현의 1단계에서 인증 URL에 전달된 토큰으로 바꿉니다.
Java 예
이 예에서는 Java 클라이언트 라이브러리를 사용하여 mirror.accounts.insert
를 호출하는 방법을 보여줍니다.
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.mirror.Mirror;
import com.google.api.services.mirror.model.Account;
import com.google.api.services.mirror.model.AuthToken;
import com.google.common.collect.Lists;
...
/** Email of the Service Account */
private static final String SERVICE_ACCOUNT_EMAIL =
"<some-id>@developer.gserviceaccount.com";
/** Path to the Service Account's Private Key file */
private static final String SERVICE_ACCOUNT_PKCS12_FILE_PATH =
"/path/to/<public_key_fingerprint>-privatekey.p12";
/** The account type, usually based on your company or app's package. */
private static final String ACCOUNT_TYPE = "com.example.myapp";
/** The Mirror API scopes needed to access the API. */
private static final String MIRROR_ACCOUNT_SCOPES =
"https://www.googleapis.com/auth/glass.thirdpartyauth";
/**
* Build and returns a Mirror service object authorized with the service accounts.
*
* @return Mirror service object that is ready to make requests.
*/
public static Mirror getMirrorService() throws GeneralSecurityException,
IOException, URISyntaxException {
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(MIRROR_ACCOUNT_SCOPES)
.setServiceAccountPrivateKeyFromP12File(
new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
.build();
Mirror service = new Mirror.Builder(httpTransport, jsonFactory, null)
.setHttpRequestInitializer(credential).build();
return service;
}
/**
* Creates an account and causes it to be synced up with the user's Glass.
* This example only supports one auth token; modify it if you need to add
* more than one, or to add features, user data, or the password field.
*
* @param mirror the service returned by getMirrorService()
* @param userToken the user token sent to your auth callback URL
* @param accountName the account name for this particular user
* @param authTokenType the type of the auth token (chosen by you)
* @param authToken the auth token
*/
public static void createAccount(Mirror mirror, String userToken, String accountName,
String authTokenType, String authToken) {
try {
Account account = new Account();
List<AuthToken> authTokens = Lists.newArrayList(
new AuthToken().setType(authTokenType).setAuthToken(authToken));
account.setAuthTokens(authTokens);
mirror.accounts().insert(
userToken, ACCOUNT_TYPE, accountName, account).execute();
} catch (IOException e) {
e.printStackTrace();
}
}
Glass에서 계정 검색
Glass에서 Account
객체를 검색하고 사용하는 것은 표준 Android AccountManager
를 사용하는 것과 유사합니다.
AndroidManifest.xml
파일에서 다음 매니페스트 권한을 선언합니다.<uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" />
Glassware의 계정을 검색합니다.
AccountManager accountManager = AccountManager.get(mContext); // Use your Glassware's account type. Account[] accounts = accountManager.getAccountsByType("com.example"); // Pick an account from the list of returned accounts.
Account
에서 인증 토큰을 가져옵니다.// Your auth token type. final String AUTH_TOKEN_TYPE = "oauth2:https://www.example.com/auth/login"; accountManager.getAuthToken(account, AUTH_TOKEN_TYPE, null, activity, new AccountManagerCallback<Bundle>() { public void run(AccountManagerFuture<Bundle> future) { try { String token = future.getResult().getString(AccountManager.KEY_AUTHTOKEN); // Use the token. } catch (Exception e) { // Handle exception. } } }, null);