Soletta Project is a framework for making IoT devices. With Soletta Project's libraries developers can easily write software for devices that control actuators/sensors and communicate using standard technologies. It enables adding smartness even on the smallest edge devices.
Step 1: Obtaining a request token:POST /oauth/request_token with oauth_callback set to device IP address and some node-internal path (ie: http://device-ip/namespace/oauth_callback). Receive the temporary oauth_token and oauth_token_secret. Likely this is started by user accessing the device web server using his desktop/mobile web browser, at say http://device-ip/namespace/oauth_start. The HTTP request handler on the device web server is asynchronous and will delay the response while it finishes the POST request. After the POST is finished, the device web server answers the desktop/mobile web browser request with a 302 - Redirect to https://api.twitter.com/oauth/authorize?oauth_token=....
Step 2: Redirecting the user to OAuth Service Login: as per step 1, the user should use his desktop/mobile web browser to login to the service and authorize the device application (client) to use on his behalf. Once the user finishes this process at the OAuth service provider web server, it will be redirected to the oauth_callback specified before, that points to the http://device-ip/namespace/oauth_callback as per step 1. The device web server will parse the result, upon success it will convert the temporary token into a long-lived access token using the received oauth_verifier. On failure the user will be 302 - Redirect to a device web page to show the error (finish_uri node option).
Step 3: Converting the request token to an access token: as per step 2, if a valid token is received, it must be converted into a long-lived access token via POST /oauth/access_token with oauth_verifier. The response is an access token and a secret. On both success or failure the user is 302 - Redirect to finish_uri with an URI fragment indicating the current status (success or error). On success, the token string is sent on node's TOKEN output port. On failure the error is sent on node's ERROR output port.
Step 1: Redirecting the user to OAuth Service Login: The user access the device web server using his desktop/mobile web browser, at say http://device-ip/namespace/oauth_start. The device web server will issue a 302 - Redirect to OAuth Service Login page such as https://www.facebook.com/dialog/oauth?client_id=XXX&response_type=token&redirect_uri=http://device-ip/namespace/oauth_callback. The user should use his desktop/mobile web browser to login to the service and authorize the device application (client) to use on his behalf. Once the user finishes this process at the OAuth service provider web server, it will be redirected to the redirect_uri specified before, that points to the http://device-ip/namespace/oauth_callback. The device web server will parse the result, upon success it use the received access_token. On failure the user will be 302 - Redirect to a device web page to show the error (finish_uri node option).
Step 2: (Optional) Facebook token validation: since the token above is returned as URI fragment, it's visible and may be modified. Then Facebook recommends one to validate it using its token inspection (https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow#checktoken). This is done by using an external server (ie: your product server) with a secret and private access_token. That server should do a GET graph.facebook.com/debug_token?input_token=.... If the token is valid, then it's sent on node's TOKEN output port, otherwise error is sent on node's ERROR output port.
Suggested Node Type
V1:
Options:
client_id (string, required): the client identifier.
namespace (string, required): namespace to use to allow multiple services, such as /oauth/twitter and /oauth/facebook.
temporary_endpoint_uri (string, required): where to get the temporary request token.
authorization_endpoint_uri (string, required): where to redirect user to login and then callback our app.
access_token_url (string, required): where to get the access token given the token verifier.
finish_uri (string, required): after the process is finished, then redirect to this URI providing status as URI fragment. This should show the user the result of the operation.
Output Ports:
TOKEN (string): the access token to use (it's actually a set of URL form-encoded parameters from oauth)
V2:
Options:
client_id (string, required): the client identifier.
namespace (string, required): namespace to use to allow multiple services, such as /oauth/twitter and /oauth/facebook.
authorization_endpoint_uri (string, required): where to redirect user to login and then callback to our app.
validation_endpoint_uri (string, optional): server to reach with access token in order to validate it against spoof.
finish_uri (string, required): after the process is finished, then redirect to this URI providing status as URI fragment. This should show the user the result of the operation.
scope (string, optional): the scope to request authorization for.
Output Ports:
TOKEN (string): the access token to use.
Sample FBP
fb_oauth(oauth/v2:client_id=xxx,namespace="/oauth/facebook",authorization_endpoint_uri="https://www.facebook.com/dialog/oauth",validation_endpoint_uri="https://my-server.com/oauth-verify-token/facebook",finish_uri="/facebook-oauth.html")
fb_oauth_token_persistence(persistence/string:name="fb.oauth.token",storage="efivars")
fb_updater(facebook/status-update)
needs_fb_oauth(http-server/boolean:path="needs-fb-oauth")
fb_oauth TOKEN -> IN fb_oauth_token_persistence
fb_oauth_token_persistence OUT -> OAUTH_TOKEN fb_updater
fb_oauth_token_persistence OUT -> IN (string/is-empty) OUT -> IN needs_fb_oauth
some_content_provider OUT -> MESSAGE fb_updater
Test is to ask user to visit http://device-ip, this should contain a static HTML provided by the product with its UI/theme that will query http://device-ip/needs-fb-oauth (node option), if it's true, then it will show a facebook login button. Click that button and it will go to http://device-ip/oauth/facebook/oauth_start (based on node option). User will be then redirected to Facebook's website. Once the OAuth process finishes, that website will redirect user to http://device-ip/oauth/facebook/oauth_callback that will process the results and emit the packet on output port TOKENor ERROR, then redirect to http://device-ip/facebook-oauth.html (node option), a static HTML that will get the URI fragment with a success/error and show to the user using the product UI/theme.
If the UI shows success, then user may trigger an action that creates a message to be posted to facebook.
The method for users to find out device-ip is beyond the scope of this task. Users may use avahi (zeroconf/mDNS), OIC or even assume a known IPv6 address using device's macaddress that can be encoded in QRCode to be scanned in the product enclosure.
Rationale
Provide OAuth node types, demonstrate its usage with a realistic sample using Twitter (v1.0) and Facebook (v2).
Sadly the two versions are different and major services use one of them, such as Twitter that uses v1.0 and Facebook that uses v2.
OAuth Work Flow
V1:
Using Twitter's API (https://dev.twitter.com/web/sign-in/implementing, replacing
/oauth/authenticate
with/oauth/authorize
as per https://dev.twitter.com/oauth/3-legged).POST /oauth/request_token
withoauth_callback
set to device IP address and some node-internal path (ie:http://device-ip/namespace/oauth_callback
). Receive the temporaryoauth_token
andoauth_token_secret
. Likely this is started by user accessing the device web server using his desktop/mobile web browser, at sayhttp://device-ip/namespace/oauth_start
. The HTTP request handler on the device web server is asynchronous and will delay the response while it finishes the POST request. After the POST is finished, the device web server answers the desktop/mobile web browser request with a302 - Redirect
tohttps://api.twitter.com/oauth/authorize?oauth_token=...
.oauth_callback
specified before, that points to thehttp://device-ip/namespace/oauth_callback
as per step 1. The device web server will parse the result, upon success it will convert the temporary token into a long-lived access token using the receivedoauth_verifier
. On failure the user will be302 - Redirect
to a device web page to show the error (finish_uri
node option).POST /oauth/access_token
withoauth_verifier
. The response is an access token and a secret. On both success or failure the user is302 - Redirect
tofinish_uri
with an URI fragment indicating the current status (success or error). On success, the token string is sent on node'sTOKEN
output port. On failure the error is sent on node'sERROR
output port.V2:
Using Facebook's API (https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow):
http://device-ip/namespace/oauth_start
. The device web server will issue a302 - Redirect
to OAuth Service Login page such ashttps://www.facebook.com/dialog/oauth?client_id=XXX&response_type=token&redirect_uri=http://device-ip/namespace/oauth_callback
. The user should use his desktop/mobile web browser to login to the service and authorize the device application (client) to use on his behalf. Once the user finishes this process at the OAuth service provider web server, it will be redirected to theredirect_uri
specified before, that points to thehttp://device-ip/namespace/oauth_callback
. The device web server will parse the result, upon success it use the receivedaccess_token
. On failure the user will be302 - Redirect
to a device web page to show the error (finish_uri
node option).access_token
. That server should do aGET graph.facebook.com/debug_token?input_token=...
. If the token is valid, then it's sent on node'sTOKEN
output port, otherwise error is sent on node'sERROR
output port.Suggested Node Type
V1:
client_id
(string, required): the client identifier.namespace
(string, required): namespace to use to allow multiple services, such as/oauth/twitter
and/oauth/facebook
.temporary_endpoint_uri
(string, required): where to get the temporary request token.authorization_endpoint_uri
(string, required): where to redirect user to login and then callback our app.access_token_url
(string, required): where to get the access token given the token verifier.finish_uri
(string, required): after the process is finished, then redirect to this URI providing status as URI fragment. This should show the user the result of the operation.TOKEN
(string): the access token to use (it's actually a set of URL form-encoded parameters from oauth)V2:
client_id
(string, required): the client identifier.namespace
(string, required): namespace to use to allow multiple services, such as/oauth/twitter
and/oauth/facebook
.authorization_endpoint_uri
(string, required): where to redirect user to login and then callback to our app.validation_endpoint_uri
(string, optional): server to reach with access token in order to validate it against spoof.finish_uri
(string, required): after the process is finished, then redirect to this URI providing status as URI fragment. This should show the user the result of the operation.scope
(string, optional): the scope to request authorization for.TOKEN
(string): the access token to use.Sample FBP
Test is to ask user to visit
http://device-ip
, this should contain a static HTML provided by the product with its UI/theme that will queryhttp://device-ip/needs-fb-oauth
(node option), if it's true, then it will show afacebook login
button. Click that button and it will go tohttp://device-ip/oauth/facebook/oauth_start
(based on node option). User will be then redirected to Facebook's website. Once the OAuth process finishes, that website will redirect user tohttp://device-ip/oauth/facebook/oauth_callback
that will process the results and emit the packet on output portTOKEN
orERROR
, then redirect tohttp://device-ip/facebook-oauth.html
(node option), a static HTML that will get the URI fragment with a success/error and show to the user using the product UI/theme.If the UI shows success, then user may trigger an action that creates a message to be posted to facebook.
The method for users to find out
device-ip
is beyond the scope of this task. Users may use avahi (zeroconf/mDNS), OIC or even assume a known IPv6 address using device's macaddress that can be encoded in QRCode to be scanned in the product enclosure.Resources: