Daniel Watrous on Software Engineering

A Collection of Software Problems and Solutions

Posts tagged oauth

Software Engineering

Use oAuth to Register Users on My Site using Social Media Credentials

I’m interested in allowing a user to register on my site/app using their social account credentials (e.g. Google, Facebook, LinkedIn, etc.). It should also be possible to register using an email address. Since the site/app will be composed of a handful of microservices, I would want to provide my own identity service, which might includes profile information and roles. This should be possible with oAuth.

I found plenty of examples of how to use oAuth against someone’s social accounts. What I didn’t find were any examples of how to manage user registration and possibly ongoing authentication against a social account. I also didn’t see an examples of how to mix a social oAuth server with an internal oAuth server. The internal oAuth server would provide authentication for each microservice consumed by the site/app. It seemed awkward to keep validating access tokens against the social account oAuth server for each request to local microservices, so this design uses the social access token to get an access token against the internal oAuth server. Here’s how that looks:

social-oauth-register-third-party (You can play with this diagram here)

As you can see, the access token is used to get the initial data to create a user (register) in the internal oAuth server. After registration, the user can still authenticate using their social account, but the account wouldn’t be created a second time. Also notice that the social access token is used to generate the authorization code and eventually the access token for the internal oAuth server, instead of going back to the user for confirmation. In other words, a valid access token from the social oAuth server presumes the user has logged in to authorize access already. The oAuth access token from the internal oAuth server is used to authentication all calls to internal microservices.

References:

http://nordicapis.com/how-to-control-user-identity-within-microservices/
http://www.bubblecode.net/en/2016/01/22/understanding-oauth2/
http://stackoverflow.com/questions/29644916/microservice-authentication-strategy

Software Engineering

Design principles for REST APIs

I have recently had to work with a few REST APIs that exhibited some poor design choices that I had previously assumed would be obvious. Since they may not be obvious to everyone, I wanted to highlight them.

Idempotent operations

When an operation is idempotent that means that an end state will be identical regardless of how many times the operation is executed. If the end state is dependent on the number of times an operation is executed, then it is not idempotent.

Why is this important?

REST interfaces should assume unreliable networks (which isn’t hard). A consumer of a REST API may issue the same call multiple times if a call fails, or times out or for any other reason. An idempotent operation ensures that the end result of a system is identical in cases where an operation is called multiple times.

The most common violation of this in REST APIs is a call to create a record using a POST. I do agree that in some cases it is unavoidable, but there are many instances where a PUT would be a good replacement. PUT semantics simply make the server representation of a resource match what is sent in. When a POST is unavoidable, it may be possible to add some throttle or comparison function in the API that monitors for replays and either drops them or flags them as potential duplicates.

Authentication

Authentication is a critical element of any application. Fortunately there are some well established standards which also make your application more interoperable, such as oAuth. Unfortunately, many developers tend to roll their own authentication code, which can be a resource drain and present security risks.

What is this important?

Security is a big deal and has a huge potential impact on business for better or for worse. More and more businesses are getting hacked, which comes with a huge cost to both businesses and consumers.

Accepted standards are more likely to be secure. It is also more likely that there is an existing implementation that can be dropped in to your application.

Personal Information

Personally Identifiable Information (PII), such as username, email, user ID, address, phone, etc. should NEVER be included in a URI. Not only does this muddy the concept that a URI identifies a resource (since a userid in the URI would make it appear to be many resources, one for each userid), but it also compromises personal information. Any necessary personal information should be transmitted in the HEADERS or BODY of the request, not in the URI.

What is this important?

In REST, it’s important to make sure that a given URI identifies one resource, whether that resource is identified as a single item or a collection of items. It must also be reproducible. When personal information is included in a URI, the resource correlation is lost.

Proxy and cache servers often use the URI as the cache key to facilitate lookups. Most web servers also include full URIs in log files. For these reasons, any personal information that is included in the URI may end up persistently stored on any number of systems, including the local browser.

Response Codes

HTTP response codes are standard. Unfortunately many REST APIs make poor use of the standard. Some lump nearly all response states into just one or two response codes, like 500 and 404. Others deviate from the standard and create their own response codes. I’m not going to argue that the available response codes are sufficient for every case. What I will argue is that there is more value in terms of interoperability and adoption when a REST API conforms to existing response codes.

What is this important?

REST APIs are designed to accommodate integration with other systems and applications. Developers of those systems and applications are more likely to be familiar with the standards. It may even be that they are using a library that only accommodates standard response codes (possibly omitting 418 I’m a teapot). Sticking with standard response codes makes integration more straight forward.