0

I have seen this solved in popular platforms like Android & iOS using client SDKs. My question is

  • I have a RESTful server
  • I have a mobile client

How to

  1. Create a signup which uses a federated OAuth (Google, FB, Microsoft etc) and use that to further authenticate the subsequent API calls.

This is what I am thinking

  1. Client application calls the OAuth dialog of the login provider, and receives (after user consent), access token and user ID.
  2. This is stored on the client and also passed to the server.
  3. Server can validate (retreive) user info using the accessToken.
  4. Sever can return IDtoken/Refreshtokens which client can use in subsequent API calls.

My question here is

  1. Is this the right approach.
  2. Can clients store the accesstoken (best practice?)
  3. Can client pass the accessToken to backend (best practice?)

Is there an example, how this can be implemented for Google Auth (for a client and Webserver) without using SDKs.

Codevalley
  • 4,593
  • 7
  • 42
  • 56

3 Answers3

0

The standard option is to implement the AppAuth pattern in your mobile app, meaning it signs in and uses tokens from your Authorization Server (AS). The mobile app then sends access tokens to your APIs.

Once this is done, signing in via Google, Facebook etc requires only config changes in the AS. Adding a new login / identity provider requires no code changes in either your UIs or APIs.

Here are Android and iOS samples of mine that use this approach and which you can run and maybe borrow some ideas from.

They use AWS Cognito as the AS - and I could configure Cognito to use Google or Facebook logins if I wanted to. Also I am in full control of scopes and claims added to access tokens - which my APIs can use to authorize requests.

ANSWERS

  1. Almost right - your client app redirects to the AS and not Google / Facebook directly

  2. Yes - mobile clients can store a refresh token in OS secure storage private to the app so that users do not need to login on every app restart. My samples do that.

  3. Yes - mobile clients use access tokens as API message credentials

LIBRARIES

I agree with you here - avoid Google / Facebook libraries in your app. However it is recommended to use the respected AppAuth libraries - once integrated your app is compliant with any AS and will support all of its authentication flows.

Out of interest the AppAuth pattern even potentially enables future advanced scenarios such as App2App, since the AS can federate to an AS from another company (though I doubt that is relevant to you right now).

LEARNING CURVE

Finally it's worth mentioning that it is tricky to implement AppAuth - there are annoyances - but once done the architecture is in a good place.

Gary Archer
  • 22,534
  • 2
  • 12
  • 24
0

Firstly, Any application that calls Google APIs needs to enable those APIs in the API Console.

Now, Any application that uses OAuth 2.0 to access Google APIs must have authorization credentials that identify the application to Google's OAuth 2.0 server.

For the credentials go to the Credentials Page and then fill the form according to your Application.

Note: Google recommends that you design your app's auth endpoints so that your application does not expose authorization codes to other resources on the page.

After getting your credentials, download the client_secret.json file from the API Console and securely store the file in a location that only your application can access.

For HTTP/REST, there is no need to install any libraries to call oAuth 2.0

Google's OAuth 2.0 endpoint is at https://accounts.google.com/o/oauth2/v2/auth. This endpoint is accessible only over HTTPS. Plain HTTP connections are refused.

As a client, the only thing you need to do for Basic authentication is to include an Authorization header in an HTTP request, composed of the username and password, separated by a colon and then Base64 encoded. E.g., in Ruby (1.9) using RestClient:

require 'restclient'
require 'base64'
auth = "Basic " + Base64::strict_encode64("#{username}:#{password}")
response = RestClient.get("https://myhost/resource",:authorization=>auth)

The token value is opaque to a client, but can be decoded by a Resource Server so it can check that the Client and User have permission to access the requested resource.

Authorization: Bearer <TOKEN_VALUE>

Send user to Google's OAuth 2.0 server. Example URL:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly&
 access_type=offline&
 include_granted_scopes=true&
 state=state_parameter_passthrough_value&
 redirect_uri=http%3A%2F%2Foauth2.example.com%2Fcallback&
 response_type=code&
 client_id=client_id

Request access token. Example:

POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https://oauth2.example.com/code&
grant_type=authorization_code

Use API. Example:

GET /drive/v2/files HTTP/1.1
Authorization: Bearer <access_token>
Host: www.googleapis.com/
Sreeram Nair
  • 2,369
  • 12
  • 27
0

Is this the right approach.

Yes, pretty much. You're describing standard bearer token authorization. Access & ID tokens expire after a short time frame, and you have to use a long-lived refresh token to get new ones. The access token allows you to gain access, the refresh token is only useful for bootstrapping tokens.

Can clients store the accesstoken (best practice?)

Yes. You must store an OAuth refresh token. You may store the ID and access tokens (as opposed to keeping them in memory.)

On the web, you should not use Local Storage. Instead, use an httpOnly cookie.

On mobile, use platform features like Android's AccountManager or iOS' Keychain Services.

Can client pass the accessToken to backend (best practice?)

Yes, that's its purpose.

Is there an example, how this can be implemented for Google Auth (for a client and Webserver) without using SDKs.

I do not recommend this for several reasons. Firstly, your implementation will be less secure than Google's, who has a team devoted to ensuring their SDK is the most secure it can be. Secondly, you're not ready to try this implementation, yet. Start with the SDK, get it working, and then come back to this.

Using a solution like Auth0 will be the easiest way to start.

Jameson
  • 6,400
  • 6
  • 32
  • 53