Skip to main content
Samsung Developer Program

OAuth user authentication on a watch

This section describes how to use OAuth user authentication on a watch.

Google and Facebook support OAuth user authentication for devices that do not have access to a browser or have limited input capabilities (such as TVs, game consoles, and printers). Using mobile browsers, watches can provide Google OAuth or Facebook OAuth user logins to Google or Facebook accounts to get users' Google or Facebook profiles. Watch apps can then authenticate users through their profiles.

Before using Google or Facebook OAuth, see the following guides for information about basic OAuth for limited-input devices:

OAuth development environment requirements

OAuth process

The following figure illustrates the OAuth process to authenticate the user:

gearoauth_diagram.png

  1. Click Confirm to start the process.
  2. The watch requests your user code and verification URL from the Google or Facebook server.
  3. The server returns the user code and URL to the watch.
  4. The watch starts the process to get an access token from the server. The request is repeated every 5 seconds until it is successful.
  5. The watch uses the verification URL to launch the mobile device browser and display the user code.
  6. Check your user code on the watch screen.
  7. In the mobile device browser, enter the user code to grant permission for user authentication.
  8. The watch app uses the mobile device browser to request user authentication by the Google or Facebook server.
  9. After user authentication, the watch gets the access token from the server.
  10. The watch requests the Google or Facebook user profile from the server.
  11. The server returns the profile.
  12. The watch app uses the profile to authenticate the user.

Code examples for Google OAuth

The following examples show how to communicate with the Google server:
 

Request the user code

Use the XMLHttpRequest APIs to request the user code.

var userCodeResponse = function(data) {
    Object.defineProperties(this, {
    device_code : { value: String(data.device_code), writeable: false, enumerable: true},
    user_code : { value: String(data.user_code), writeable: false, enumerable: true},
    verification_url : { value: String(data.verification_url), writeable: false, enumerable: true},
    expires_in : {value: data.expires_in, writeable: false, enumerable: true},
    interval : {value: data.interval, writeable: false, enumerable: true}
    });
}

var userCode=null;

function requestUserCode() {

    var postfields = "client_id=" + CLIENT_ID + "&scope=email profile";

    try {
        var xmlRequest = new XMLHttpRequest();
        if (xmlRequest) {
            xmlRequest.open("POST", "https://accounts.google.com/o/oauth2/device/code", true);
            xmlRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");

            xmlRequest.onreadystatechange = function() {
                if (xmlRequest.readyState == 4) {
                    console.log(xmlRequest.responseText);
                    if(xmlRequest.status == 200) {
                        userCode = new userCodeResponse(JSON.parse(xmlRequest.responseText));
                    } else {
                        console.log("status:" + xmlRequest.status);
                        var errorMsg = JSON.parse(xmlRequest.responseText);
                        if ( errorMsg && errorMsg.error ) {
                            console.log(errorMsg.error_description);
                        } else {
                            console.log("Request Access Token fail..." );
                        }
                    }

                }
            };

            xmlRequest.send(postfields);
        }
    } catch(err) {
            console.log("exception [" + err.name + "] msg[" + err.message + "]");
    }
}


Launch the browser with the verification URL

Use the App Control APIs to launch the browser with the verification URL in the user code you received. If your app control launch is successful, your device sends a polling request to Google's authorization server every interval, as shown in the user code you received.

function consentLogin(userCode) {
    var txt_content = document.getElementById("text-content");
    txt_content.innerHTML = userCode.user_code;

    deviceCode = userCode.device_code;
    intervalTime = userCode.interval*1000;

    var appid = "tizen.wearablemanager",
    extra_data = [new tizen.ApplicationControlData("type", ["launch-remote-browser"])];

    var appControl = new tizen.ApplicationControl(
            "http://tizen.org/appcontrol/operation/default",
            userCode.verification_url, null, null, extra_data
        );

    try {
        tizen.application.launchAppControl(appControl, appid,
                function () {
                    console.log("success");
                    console.log("enter user code to mobile");
                    intervalObj = setInterval(pollAccessToken, intervalTime); //send a polling request  
                }, function(e) {console.log("failed : " + e.message);});
    } catch(e) {
        console.log("Error Exception, error name : " + e.name + ", error message : " + e.message);
    }
} 


Poll Google's authorization server

Use the XMLHttpRequest APIs to request permission.

function pollAccessToken()
{
    console.log("poll...");
    requestAccessToken();
    if (tokenObj && intervalObj) {
        clearInterval(intervalObj);
        requestProfile(tokenObj.access_token, tokenObj.expires_in); //request profile
    }
}

function requestAccessToken()
{
    var postfields = "client_id=" + CLIENT_ID + "&client_secret=" + CLIENT_SECRET + "&code=" + deviceCode + "&grant_type=http://oauth.net/grant_type/device/1.0";

    try {
        var xmlRequest = new XMLHttpRequest();
        if (xmlRequest) {
            
            xmlRequest.open("POST", "https://www.googleapis.com/oauth2/v4/token", true);
            xmlRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
            xmlRequest.timeout = intervalTime;

            xmlRequest.onreadystatechange = function() {
                if (xmlRequest.readyState == 4) {
                    console.log(xmlRequest.responseText);
                if(xmlRequest.status == 200) {
                var token = JSON.parse(xmlRequest.responseText);
                    if (token && token.access_token) {
                        tokenObj = token;
                    }
                } else {
                    var errorMsg = JSON.parse(xmlRequest.responseText);
                        if ( errorMsg && errorMsg.error ) {
                            console.log(errorMsg.error_description);
                        } else {
                            console.log("Request Access Token fail..." );
                        }
                    }
                }
            };

            xmlRequest.ontimeout = function(e) {
                console.log("timeout:" + e);
            }

            xmlRequest.send(postfields);
        }

    } catch(err) {
        console.log("exception [" + err.name + "] msg[" + err.message + "]");
    }
}


Request the profile with access token

Use the XMLHttpRequest APIs to request the profile.

function requestProfile(access_token, expires_in)
{
    try {
        var reqURI = "https://www.googleapis.com/plus/v1/people/me?access_token=" + access_token;
        var xmlRequest = new XMLHttpRequest();
        if (xmlRequest) {
            xmlRequest.open("GET", reqURI);
    
            xmlRequest.onreadystatechange = function() {
                if (xmlRequest.readyState == 4) {
                    console.log(xmlRequest.responseText);
                    if(xmlRequest.status == 200) {
                        console.log("OAuth Complete.");
                        var profile = JSON.parse(xmlRequest.responseText);
                        console.log("profile's display name is " + profile.displayName)
                    } else {
                       var errorMsg = JSON.parse(xmlRequest.responseText);
                       if ( errorMsg && errorMsg.error ) {
                           console.log(errorMsg.error_description);
                       }
                    }
                }
            };        
        }

        xmlRequest.send();
    } catch(err) {
        console.log("exception [" + err.name + "] msg[" + err.message + "]");
    }    
}

Code examples for Facebook

The following examples show how to communicate with the Facebook server.

Request the user code

Use the XMLHttpRequest APIs to request the user code.

var userCode = null;

function requestUserCode() {

    var postfields = "access_token=" + APP_ID + "|" + CLIENT_TOKEN  + "&scope=public_profile";

    var xmlRequest = new XMLHttpRequest();
    if (xmlRequest) {
        console.log("request");
        xmlRequest.open("POST", "https://graph.facebook.com/v2.7/device/login", true);
        xmlRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");

        xmlRequest.onreadystatechange = function() {
            if (xmlRequest.readyState == 4) {
                console.log(xmlRequest.responseText);
                if(xmlRequest.status == 200) {
                   userCode = JSON.parse(xmlRequest.responseText);
                } else {
                    console.log("status:" + xmlRequest.status);
                    var errorMsg = JSON.parse(xmlRequest.responseText);
                    if ( errorMsg && errorMsg.error ) {
                        console.log(errorMsg.error.message);
                    } else {
                        console.log("Request Access Token fail..." );
                    }
                }
            }
        };

        try {
            xmlRequest.send(postfields);
        } catch(err) {
            console.log("exception [" + err.name + "] msg[" + err.message + "]");
        }
    }
}

 

Launch the browser with the verification URL

Use the App Control APIs to launch the browser with the verification URL in the user code you received.

function consentLogin(userCode) {
    var txt_content = document.getElementById("text-content");
    txt_content.innerHTML = userCode.user_code;
    console.log("url...:" + userCode.verification_uri);
    
    deviceCode = userCode.code;
    intervalTime = userCode.interval*1000;
    
    var appid = "tizen.wearablemanager",
    extra_data = [new tizen.ApplicationControlData("type", ["launch-remote-browser"])];
    
    var appControl = new tizen.ApplicationControl(
            "http://tizen.org/appcontrol/operation/default",
            userCode.verification_uri, null, null, extra_data
        );

    try {
        tizen.application.launchAppControl(appControl, appid,
            function () {
                console.log("success");

                intervalObj = setInterval(pollAccessToken, intervalTime);
            }, function(e) {toastPopup("failed : " + e.message);});
    } catch(e) {
        toastPopup("Error Exception, error name : " + e.name + ", error message : " + e.message);
    }
}

Request the access token

Use the XMLHttpRequest APIs to request the access token.

function pollAccessToken()
{
    console.log("poll...");
    requestAccessToken();
    if (tokenObj) {
        clearInterval(intervalObj);
        requestProfile(tokenObj.access_token, tokenObj.expires_in);
    }
}

function requestAccessToken()
{
    try {
        var postfields = "access_token=" + APP_ID + "|" + CLIENT_TOKEN + "&code=" + deviceCode;
        console.log(postfields);
        var xmlRequest = new XMLHttpRequest();
        if (xmlRequest) {

            xmlRequest.open("POST", "https://graph.facebook.com/v2.7/device/login_status", true);
            xmlRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
            xmlRequest.timeout = intervalTime;

            xmlRequest.onreadystatechange = function() {
                if (xmlRequest.readyState == 4) {
                    console.log(xmlRequest.responseText);
                    if(xmlRequest.status == 200) {
                       var token = JSON.parse(xmlRequest.responseText);
                       if (token && token.access_token) {
                           tokenObj = token;
                       } else {
                           console.log("Request Access Token fail..." );
                       }
                    } else {
                        var errorMsg = JSON.parse(xmlRequest.responseText);
                        if ( errorMsg && errorMsg.error ) {
                            console.log(errorMsg.error.message);
                        } else {
                            console.log("Request Access Token fail..." );
                        }
                    }
                }
            };

            xmlRequest.ontimeout = function(e) {
                console.log("timeout");
            }

            xmlRequest.send(postfields);
        }

    } catch(err) {
        console.log("exception [" + err.name + "] msg[" + err.message + "]");
    }
}

 

Request the profile with access token

Use the XMLHttpRequest APIs to request the profile.

function requestProfile(access_token, expires_in)
{
    var reqURI = "https://graph.facebook.com/v2.7/me?fields=name,email&access_token=" + access_token;
    console.log("reqURI:" + reqURI);
    var xmlRequest = new XMLHttpRequest();
    if (xmlRequest) {
        xmlRequest.open("GET", reqURI);

        xmlRequest.onreadystatechange = function() {
            if (xmlRequest.readyState == 4) {
                console.log(xmlRequest.responseText);
                if(xmlRequest.status == 200) {
                    var profile = JSON.parse(xmlRequest.responseText);

                    var txt_content = document.getElementById("text-content");
                    txt_content.innerHTML = profile.name; 

                } else {
                    console.log(xmlRequest.responseText);
                    console.log("Request Profile fail..." );
                }
            } else {
                console.log("readyState:" + xmlRequest.readyState);
            }
        };
        
        try {
            xmlRequest.send();
        } catch(err) {
            console.log("exception [" + err.name + "] msg[" + err.message + "]");
        }
    }
}