Skip to content
jvelilla edited this page Aug 23, 2013 · 13 revisions

Cypress OAuth Client Library

This document assume that you know OAuth, in other case there are a lot of tutorials. Look at the end of this tutorial to read about the specific OAuth version.

Under apis folder you will find a lot of APIs out of box (OAuth1.0a and OAuth2.0) for a lot of well known service providers like LinkedIn, Google, Box. The examples using the previous libraries are found here.

Eiffel library OAuth1.0a and OAuth2.0, consumer library based on Scribe Java Library

Features

  • Supports OAuth1.0a and 2.0
  • OAuth1.0 and 2.0 API ready to use
  • Simple to create new OAuth API bindings.

Setup

Require EiffelStudio 7.3, depends on eel and json

OAuth Workflow

{to be completed}

Initialization

Before to start you will need to create a service for a particular OAuth API consumer (for example Twiter, Linkedin, etc).

api_service : OAUTH_SERVICE_I
api_builder: API_BUILDER
	
create api_builder
api_service := api_builder.with_api (create {OAUTH_10_LINKEDIN_API})
			.with_api_key (api_key)											     
			.with_api_secret (api_secret)
			.build

As you can see we use an instance of API_BUILDER to create a service, in this case Linkedin as the API provider. By default an out of band callback is defined, but you can set a callback Url using with_callback_url, before to call build.

Read the fluent API to use the Builder

Request Token

Get the request token

request_token : detachable OAUTH_TOKEN

request_token := api_service.request_token

Authorization Request

We need to authorize our app, before we can start make OAuth calls. Calling authorization_url will redirect us to a url

   authorization_url := api_service.authorization_url (request_token)

Then we will get a verfier code (if we send an Out of band request) or we will be redirected to an URL with the verfier code and the request token on it.

Access Token Request

Now we need an access token, so we call access_token_get (or post) with the previous request_token and the verfier code that you got in the previous steps.

access_token := api_service.access_token_get (request_token, create 
                                     {OAUTH_VERIFIER}.make (io.last_string))

After this, we will use the access_token to sing the requests.

Resource Request

To make a resource request call, first we need to sign the request, with the previous access_token

 create request.make ("GET", protected_resource_url)
 api_service.sign_request (access_token, request)
 if attached {OAUTH_RESPONSE} request.execute as l_response then
	if attached l_response.body as l_body then
 end

Examples

How to add a new OAuth1.0a service provider?

Inherit from OAUTH_10_TEMPLATE_API and complete the values for: authorize_url, request_token_endpoint_url, and access_token_endpoint_url. Let see an example for Linkedin1.0a, read the documentation and retrieve the needed information.

class
	OAUTH_10_LINKEDIN_API

inherit

	OAUTH_10_TEMPLATE_API

feature {NONE} -- Implementation

	authorize_url: STRING ="https://api.linkedin.com/uas/oauth/authenticate?oauth_token="

	request_token_endpoint_url: STRING = "https://api.linkedin.com/uas/oauth/requestToken"

	access_token_endpoint_url: STRING = "https://api.linkedin.com/uas/oauth/accessToken"

end

2-Legged’ OAuth10a

class	OAUTH_10_YELPv2_API

inherit

	OAUTH_10_TEMPLATE_API

feature {NONE} -- Implementation

	authorize_url: STRING =""

	request_token_endpoint_url: STRING = ""

	access_token_endpoint_url: STRING = ""

end

How to add a new OAuth2.0 service provider.

Let see an example with Google API, inherit from OAUTH_20_API and complete the missing parts, and that's all.

class
	OAUTH_20_GOOGLE_API

inherit

	OAUTH_20_API
		redefine
			access_token_extractor,
			access_token_verb
		end

feature -- Access

	access_token_extractor: ACCESS_TOKEN_EXTRACTOR
		do
			create {JSON_TOKEN_EXTRACTOR} Result
		end

	access_token_verb: READABLE_STRING_GENERAL
		do
			Result := "POST"
		end

	access_token_endpoint: READABLE_STRING_GENERAL
			-- Url that receives the access token request
		do
			create {STRING_32} Result.make_from_string ("https://accounts.google.com/o/oauth2/token")
		end

	authorization_url (config: OAUTH_CONFIG): detachable READABLE_STRING_GENERAL
			-- Url where you should redirect your users to authneticate
		local
			l_result: STRING_32
		do
			if attached config.scope as l_scope then
				create {STRING_32} l_result.make_from_string (TEMPLATE_AUTHORIZE_URL + SCOPED_AUTHORIZE_URL)
				l_result.replace_substring_all ("$CLIENT_ID", config.api_key.as_string_8)
				if attached config.callback as l_callback then
					l_result.replace_substring_all ("$REDIRECT_URI", (create {OAUTH_ENCODER}).encoded_string (l_callback.as_string_32))
				end
				if attached config.callback as l_callback then
					l_result.replace_substring_all ("$SCOPE", (create {OAUTH_ENCODER}).encoded_string (l_scope.as_string_32))
					Result := l_result
				end
			else
				create {STRING_32} l_result.make_from_string (TEMPLATE_AUTHORIZE_URL + SCOPED_AUTHORIZE_URL)
				l_result.replace_substring_all ("$CLIENT_ID", config.api_key.as_string_8)
				if attached config.callback as l_callback then
					l_result.replace_substring_all ("$REDIRECT_URI", (create {OAUTH_ENCODER}).encoded_string (l_callback.as_string_32))
				end
			end
		end

feature -- Implementation

	Template_authorize_url: STRING = "https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI";

	Scoped_authorize_url: STRING = "&scope=$SCOPE";

end

Quality: unstable, draft, in-progress

OAuth1.0 http://tools.ietf.org/html/rfc5849 http://oauth.net/core/1.0a/

OAuth2.0 http://oauth.net/2/