jamp
jamp

Reputation: 2275

Google API OAuth 2.0 for Devices Java library

I need to implement the OAuth 2.0 flow for Devices described here:

https://developers.google.com/identity/protocols/OAuth2ForDevices

I couldn't find any implementation of this in the Google APIs Client Library for Java.

There is, for instance, the support for the installed applications flow (https://developers.google.com/identity/protocols/OAuth2InstalledApp) as shown in this example:

https://developers.google.com/api-client-library/java/google-api-java-client/oauth2#installed_applications

but nothing for devices with no browser...

Should I implement the API from scratch or there is something I'm missing?

Thanks!

Upvotes: 3

Views: 938

Answers (1)

faraway
faraway

Reputation: 932

I have faced the same problem. I needed to figure out the structure of api client library. Anyway, here is a sample code for oauth 2.0 for devices.

It prints out user code and verification url. Go to the verification url and enter user code. After you authroized the app it gets access and refresh token.

public static class OAuthForDevice{


    private static final String TOKEN_STORE_USER_ID = "butterflytv";

    public static String CLIENT_ID = "Your client id";
    public static String CLIENT_SECRET = "your client secredt";

    public static class Device {
        @Key
        public String device_code;
        @Key
        public String user_code;
        @Key
        public String verification_url;
        @Key
        public int expires_in;
        @Key
        public int interval;
    }

    public static class DeviceToken {
        @Key
        public String access_token;
        @Key
        public String token_type;
        @Key
        public String refresh_token;
        @Key
        public int expires_in;
    }

    public static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();

    /**
     * Define a global instance of the JSON factory.
     */
    public static final JsonFactory JSON_FACTORY = new JacksonFactory();


    public static void main(String[] args)  {
        getCredential();
    }

    public static Credential getCredential() {
        Credential credential = null;
        try {
            FileDataStoreFactory fileDataStoreFactory = new FileDataStoreFactory(new File(System.getProperty("user.home")));
            DataStore<StoredCredential> datastore = fileDataStoreFactory.getDataStore("youtube_token");

            credential = loadCredential(TOKEN_STORE_USER_ID, datastore);
            if (credential == null) {

                GenericUrl genericUrl = new GenericUrl("https://accounts.google.com/o/oauth2/device/code");         


                Map<String, String> mapData = new HashMap<String, String>();
                mapData.put("client_id", CLIENT_ID);
                mapData.put("scope", "https://www.googleapis.com/auth/youtube.upload");
                UrlEncodedContent content = new UrlEncodedContent(mapData);
                HttpRequestFactory requestFactory = HTTP_TRANSPORT.createRequestFactory(new HttpRequestInitializer() {
                    @Override
                    public void initialize(HttpRequest request) {
                        request.setParser(new JsonObjectParser(JSON_FACTORY));
                    }
                });
                HttpRequest postRequest = requestFactory.buildPostRequest(genericUrl, content);

                Device device = postRequest.execute().parseAs(Device.class);
                System.out.println("user code :" + device.user_code);
                System.out.println("device code :" + device.device_code);
                System.out.println("expires in:" + device.expires_in);
                System.out.println("interval :" + device.interval);
                System.out.println("verification_url :" + device.verification_url);


                mapData = new HashMap<String, String>();
                mapData.put("client_id", CLIENT_ID);
                mapData.put("client_secret", CLIENT_SECRET);
                mapData.put("code", device.device_code);
                mapData.put("grant_type", "http://oauth.net/grant_type/device/1.0");

                content = new UrlEncodedContent(mapData);
                postRequest = requestFactory.buildPostRequest(new GenericUrl("https://accounts.google.com/o/oauth2/token"), content);

                DeviceToken deviceToken;
                do {
                    deviceToken = postRequest.execute().parseAs(DeviceToken.class);

                    if (deviceToken.access_token != null) {
                        System.out.println("device access token: " + deviceToken.access_token);
                        System.out.println("device token_type: " + deviceToken.token_type);
                        System.out.println("device refresh_token: " + deviceToken.refresh_token);
                        System.out.println("device expires_in: " + deviceToken.expires_in);
                        break;
                    }
                    System.out.println("waiting for " + device.interval + " seconds");
                    Thread.sleep(device.interval * 1000);

                } while (true);


                StoredCredential dataCredential = new StoredCredential();
                dataCredential.setAccessToken(deviceToken.access_token);
                dataCredential.setRefreshToken(deviceToken.refresh_token);
                dataCredential.setExpirationTimeMilliseconds((long)deviceToken.expires_in*1000);

                datastore.set(TOKEN_STORE_USER_ID, dataCredential);

                credential = loadCredential(TOKEN_STORE_USER_ID, datastore);
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }

        return credential;
    }

    public static Credential loadCredential(String userId, DataStore<StoredCredential> credentialDataStore) throws IOException {
        Credential credential = newCredential(userId, credentialDataStore);
        if (credentialDataStore != null) {
            StoredCredential stored = credentialDataStore.get(userId);
            if (stored == null) {
                return null;
            }
            credential.setAccessToken(stored.getAccessToken());
            credential.setRefreshToken(stored.getRefreshToken());
            credential.setExpirationTimeMilliseconds(stored.getExpirationTimeMilliseconds());
        } 
        return credential;
    }

    private static Credential newCredential(String userId, DataStore<StoredCredential> credentialDataStore) {

        Credential.Builder builder = new Credential.Builder(BearerToken
                .authorizationHeaderAccessMethod()).setTransport(HTTP_TRANSPORT)
                .setJsonFactory(JSON_FACTORY)
                .setTokenServerEncodedUrl("https://accounts.google.com/o/oauth2/token")
                .setClientAuthentication(new ClientParametersAuthentication(CLIENT_ID, CLIENT_SECRET))
                .setRequestInitializer(null)
                .setClock(Clock.SYSTEM);

        builder.addRefreshListener(
                new DataStoreCredentialRefreshListener(userId, credentialDataStore));

        return builder.build();
    }

}

Upvotes: 3

Related Questions