Quantcast
Channel: Blog – Stormpath User Identity API
Viewing all 278 articles
Browse latest View live

Social Login: Facebook & Google in One API Call

$
0
0

Integrating to Facebook, Google, and other social providers can be a pain. Do you want to deal with Facebook and Google tokens and their idiosyncrasies every time you build a new app? Probably not.

We at Stormpath frequently get requests to automate social login and integration for our customers so that they don’t have to build it themselves. Well, we’ve done that— Hooray! This post is about some of the design challenges and solutions we worked through while implementing this feature for our customers.

Social Login with Stormpath – Quick Description

Stormpath’s first OAuth integration makes it easy to connect to Google and Facebook in one simple API call. It’s a simple and secure way to retrieve user profiles and convert them into to Stormpath accounts so that no matter the service you’re using, you have one simple user API.

Goals and Design Challenges

My primary goal was to make this easy for developers. At the same time, it needed to be robust enough so that Stormpath could use it as the foundation to integrate with future identity providers like Twitter and GitHub.

This came with some design challenges:

  • How Do We Model Social Account Data in Stormpath? We decided to let users configure external providers (like Google or Facebook) as a Stormpath Directory. In Stormpath, a Directory is a high-level ‘bucket’ of users and groups. Adding social integration at the Directory level means that all Facebook identities would exist in a Facebook directory— same for Google. This give a developer two big benefits:

    1. You can map your Facebook or Google Directory to multiple applications in the same domain, allowing your apps to share those users without any additional code and improving your user experience.
    2. You can define authorization policies for your social identities by assigning specific groups, roles, and permssions to them. Note— this particular feature is coming soon.
  • What Fields Should the Developer be Able to Update in a Social Account? Google and Facebook do not allow you to write changes back to one of their accounts. This poses a problem. How do you add your own app-specific data to the record? As a solution, Stormpath creates a “mirror” of a social identity and allows you to add your own data to the “mirror” record via customData.

  • Do We Allow Password Resets? Many applications with social integration rely solely on the external credentials hosted on the social network. This poses another problem. What if your registers with Google or Facebook but they later forget and try to log in directly with a username and password? This scenario is extremely common and often creates user confusion. They try all the passwords they remember and then eventually try a password reset, before finally contacting your help desk. At scale, this can clog your support staff.

To solve this problem, Stormpath allows you to create a new password for a social account in Stormpath. If you want, the user can specificy a password upon first registering and/or by initiating a password reset flow. Ultimately, the user can now choose how they want to log in regardless of how they registered.

  • How Do We Sync Data? You can pull in profile data from social integrations and host it in Stormpath, but how do we keep the account information up-to-date without eating through a bunch of API calls? We decided to perform “on demand sync” – every time a user accesses your application with their social credentials, their Stormpath account information will be automatically updated with the information retrieved by the social provider.

  • How Will the Application Know the Difference Between New and Existing Social Accounts? When retrieving an account from a social provider, you can tell whether the account is new to your application or if it already existed by checking the HTTP response status code. Stormpath will return a 201 Created status for newly obtained social accounts and a 200 OK when returning an existing/known account.

Making Google Access Tokens Painless

Getting an access token for a Google user in a web server application is not as easy as one might hope. Once the end-user has authorized your application, Google will send an “authorization code” as query parameter to the “redirect_uri” you specified in the developers console when you created your “Google project”. Finally, you’ll have to exchange the “authorization code” for an access token.

Of course, each of these calls require their own set of headers, parameters, etc. Fun times.

We wanted to reduce this burden for developers, so our Google integration conveniently automates the “exchange code” flow for you. This allows you to POST the authorization code and then receive a new (or updated) account, along with the access token, which can be used for further API calls.

Security

At Stormpath one of our main responsibilities is securing user data. When it comes to social integration, we ensure that Facebook and Google client secrets are encrypted using strong AES 256 (CBC) encryption, using secure-random Initialization Vectors. Every encryption key is tenant-specific, so you can guarantee that your encrypted secrets are only accessible by you.

Also, Facebook Login Security recommends that every server-to-server call is signed to reduce the risk of misuse of a user access token in the event it’s stolen. If your access token and you don’t require all your server calls to be signed, the thief can use your application as spam or read user’s private data.

Securing Facebook requests makes your application less vulnerable to attacks, and that’s why we recommend you to enable the Require proof on all calls setting for your Facebook application. Stormpath does this by default.

How does this work? Signing a call to Facebook just means adding the “appsecret_proof” parameter to every server request you make.

The content of the additional parameter is the hash value (SHA-256) of the user’s access with the Facebook application secret. Finally, the generated bytes are encoded using Hexadecimal characters.

1
2
3
4
5
appsecret_proof_value = Hex.encodeToString(hmac(SHA-256, access_token, app_secret)
https://graph.facebook.com/me
{
   access_token=...&appsecret_proof=${appsecret_proof_value}
}

How To Get Started With Stormpath Social Integration

To use Google or Facebook with Stormpath, follow these three steps:

  1. Create a Facebook or Google Directory in Stormpath to mirror social accounts. You can do this via the Stormpath Admin Console, or our REST API using a POST like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
POST https://api.stormpath.com/v1/directories?expand=provider
Content-Type: application/json;charset=UTF-8

{
  "name" : "my-google-directory",
  "description" : "A Google directory",
  "provider": {
    "providerId": "google"
    "clientId":"857385-m8vk0fn2r7jmjo.apps.googleusercontent.com",
    "clientSecret":"ehs7_-bA7OWQSQ4",
    "redirectUri":"https://myapplication.com/authenticate"
  }
}
  1. Assign the created directory to your application in Stormpath.
  2. Populate your directory with social accounts from Google or Facebook using the application’s accounts endpoint.

That is it! Your application can now access social accounts. And you didn’t have to touch any OAuth!

Future Stormpath releases will support additional social account providers. Please give us your feedback and let us know which ones we should release next!


Choosing your Node.js Authentication Strategy

$
0
0

Node is blowing up! I’ve been working and playing with Node since 2010 and in that time I’ve seen it go from a tiny community of people hacking side projects to a full-fledged and legit movement of modern developers building very real, very important, and very large applications. A whole ecosystem of solutions has sprung up to help Node developers, and that ecosystem is rapidly evolving. But it’s increasingly hard to figure out what solutions are best for you because of all the noise in a Google search or in npm.

Authentication and user management in particular is a difficult and shifting landscape. And yet, when building a real application in Node, it is one of the first components you need to figure out. This guide aims to give you a complete lay of the land for user management and authentication in node.

What is available in Node?

Node today has several different paths to build user management. In no particular order there are:

  • Passport.js / Everyauth
  • Your Own Database and a Hashing Algorithm
  • User Management as a Service

Passport.js / Everyauth

PassportJS and Everyauth are authentication middleware for node that leverage the Connect middleware conventions. That means if you are using a framework like Express, Restify, or Sails you can easily plug one of their authentication schemes (or strategies) directly into your application. Everyauth comes with their strategies embedded, where as with Passport you can pick and choose which strategies to use. Some of the common strategies that developers use with Passport are Facebook and Google, but it also include everything from a local username/password authentication, to a slew of OpenID and OAuth providers, and even a Stormpath strategy for Passport.

Even though Everyauth and Passport are built on top of the same middleware framework, they have their own sets of pros and cons. Passport is more flexible and modular, but Everyauth provides additional functionality that helps with routes and login/registration views. For a lot of Node developers Passport is also preferred because it does not use promises.

Since Passport and Everyauth are built on Connect, both will help you with session management, including:

  • Serialization of the authenticated user
  • Managing the session
  • Logging the user out

Additionally, they are designed for simple, easy authentication, but fall short (by design) of broader user management needs. You are still left to design, implement, and maintain all your other user infrastructure.

For example, if you are using passport-local (the strategy to authenticate username / password against your own database), Passport does not handle user signup and account verification. You will need to work with database modules to authenticate to a database, create the account, track verification status, create a verification token, send an email, and verify the account. This means a developer will need to worry about URL safety, removing expired tokens, and other security constraints (like hashing the password correctly in a database).

Your Own Database and a Hashing Algorithm

The do-it-yourself approach doesn’t rely on any middleware. You choose your own stack, a database to store users (likely PostgresSQL and MongoDB) and a hashing algorithm to generate password hashes (likely bcrypt and scrypt). Searching for bcrypt or scrypt in npm will result in quite a few modules of varying degrees of quality, each with their own sets of dependencies. Be particularly careful if you are a Windows developer – we recommend the native JS implementation of bcrypt.

After deciding on a stack, you will need to build out user management and authentication. Historically this approach has been extremely common, but is tedious, prone to error, and requires more maintenance than other approaches.

You will need to build/figure out:

  • Account Creation
    • Create a user schema to hold user data
    • Create accounts and store salt + hashed passwords using bcrypt / scrypt
    • Sending an email with token for account verification
  • Account Authentication
    • Authenticate the user (comparing hashes)
  • Account Management
    • Password reset work flow
      • Generating / invalidating tokens
    • Role-based access / permissions
  • Integrations with ID and Social Providers
  • Secure the system
    • Secure the Database from unauthorized access
    • Secure the OS from unauthorized access
  • Backups for data

One of the biggest challenges with rolling your own auth and user management, is the maintenance. Take password hashing as an example. Done right, you select a cost factor that makes your hashing algorithm purposely slow (roughly 300-700ms) to prevent brute force attacks. However, Moore’s Law is a bitch— compute price/performance doubles every year. So the right cost factor today, may be considered insecure tomorrow. If you’re building applications that will go into production, its your responsibility to update your hashing strategy at least once a year.

Despite the Node community’s aversion to “rolling your own” middleware, there are a few benefits to this approach. You get complete control of your infrastructure. If the tools available to you are not “good enough” for what you need to deliver to your customer, then you have the ability to invest engineering effort and time to innovate around user authentication and user management. Luckily, very few applications and developers have those kind of requirements, so the open source tools and API services available today help them move faster and deliver more.

User Management as a Service

Over time, software has moved from on premise, to the cloud, to distributed API services. At the same time, development teams have come to rely on open source software and API services as much as their own code. It is now possible to offload user management to a system that exposes user management functionality via REST APIs and open-source SDKs for application development. Stormpath falls into this category along with some user API startups. The Node community, in particular, has adopted this service oriented paradigm more than any other community to date.

Typically, API-driven services allow for more common functionality around user management, going beyond just authentication. The additional functionality varies by provider, but usually includes:

  • Account email verification
  • Password reset work flows
  • Role based access / permissions
  • Schema-less User Profiles
  • Two-factor authentication
  • Single sign on between applications
  • Social login integration (Facebook, Google, etc)
  • Integration to Node auth middleware like Passport

In addition to pure features, they also off-load much of the security and operations. They host all the infrastructure for you, scale to absorb your peak traffic, and handle on-going security of your user data.

Offloading to an API service generally delivers convenience and improved security, while reducing development and maintenance costs. Developers now get to focus on building unique parts of their application.

However, there are trade-offs with using API services. You are introducing a 3rd party dependency to your application. It needs to be highly available, fast, portable, provide security during transport, and be flexible enough to meet your user data model.

Availability and performance are extremely important because a critical system like user authentication and management can not be offline or slow. Caching in their SDKS and being based on modern cloud infrastructures is a good start, but it is important that the service is prepared for the worst case scenarios – like whole data centers going down. And if you build on top of a service for user management, make sure you can subscribe to notifications of any outages.

Data portability is also critical – can you move user data in and out in safe (and easy) ways. While its easy to write a script to port unencrypted data over JSON, the ease of porting passwords will heavily depend on how you have stored any pre-existing data. For example, bcrypt is very portable by design, as it follows Modular Crypt Format (MCF). It is possible for multiple systems and languages to understand how to construct the hash by looking at the hash value itself. If you’re building a prototype and don’t use a service like Stormpath, we recommend starting with an MCF hash like bcrypt – it will be much easier to upgrade in the future.

Transport security between your application and the API Service is important in this approach compared to the approaches above. The additional network communication needs to be secured. For example, Stormpath supports only HTTPS and uses a custom digest auth algorithm to guard against replay and man in the middle attacks. You can read more about our security here.

The data model used by authentication services can vary widely – Salesforce, for instance, looks very different from the Stormpath data model, which is based on directories and therefore generic and flexibly. It’s worth digging in to make sure that the data model you have planned for your application, is supported by the service. This is particularly true for mulit-tenant applications or SaaS.

Additionally, documentation of APIs varies widely – you should make sure your solution outlines what you need before you dive in.

Building User Management…

…is hard. Inside node there are different solutions, each with a set of pros and cons. I hope this post helps you get the lay of the land. If you have any questions, suggestions or experiences that you want to share, feel free to leave a comment or reach out to me on twitter @omgitstom. And if you’re interested in a User Management API service, check out Stormpath and our Official Node SDK.

Build a Killer Node.js Client for Your REST+JSON API

$
0
0

If you’re building a Node API client, the design of your client can make or break adoption.

Our CTO Les Hazlewood recently built the Stormpath Node SDK and put what he learned into this presentation on Building A Node.js Client for REST+JSON APIs. We get a ton of questions on how we design SDKs at Stormpath, so we put the video on Youtube.

In the video, Les covers:

  • Collection & Instance Resources
  • Public / Private API
  • Proxy Design
  • Component Architecture
  • Queries
  • Authentication – Digest Algorithm vs HTTP Basic
  • Pluggability

If you want to explore our Node client further, here’s the getting started code from the presentation:

1
2
3
4
$ git clone https://github.com/stormpath/stormpath-sdk-node.git
$ cd stormpath-sdk-node
$ npm install
$ grunt

We’ll also be posting full writeup blogs soon – Stay tuned!

Thanks to the BayNode Meetup for hosting this talk.

Cryptography 101

$
0
0

Cryptography is an important part of almost every web or mobile application and yet most developers feel that they don’t understand it or worse, are doing it wrong. Yes, the field of cryptography is dominated by uber-smart mathematicians, researchers, and PhDs galore but thanks to the hard work of those people, we have great tools that the average dev can benefit from.

Here at Stormpath, our goal is to make developer’s lives easier and help them build more secure applications faster. Sharing the basics of cryptography will hopefully help you in your development projects.

What is Cryptography

Cryptography is the practice of protecting information from undesired access by hiding it or converting it into nonsense. For developers, cryptography is a notoriously complex topic and difficult to implement.

The goal of this guide is to walk you through the basics of Cryptography. How some of these algorithms and techniques are implemented is often dependent on your chosen language and/or framework but this guide will hopefully help you know what to look for. If you’re a Java developer, check out Apache Shiro. It’s a popular security framework thats makes implementing crypto much easier than messing with the JCE. ::cough:: We’re the authors.

Terminology

First, a bit of terminology. In crypto-land, you can break most algorithms down to ciphers and hashes.

  • Ciphers are algorithms that can encrypt or decrypt data based on shared or public/private keys.
  • Hashes (a.k.a. Message Digests) are one way, irreversible conversion of an input source. Often used for passwords and checksums.

When to use a Cipher vs a Hash

Put simply, you should use a hash when you know you will not need the original data in plain text ever again. When would you ever take data that you don’t ever need it’s original value? Well, passwords are a good example.

Let’s say Sean’s password is ‘Suck!tTrebek’. Your application doesn’t actually need to know the raw value of the password. It just needs to be able to verify that any future authentication attempt by Sean gives you a matching value. Hashes are great for that because the hash, while gibberish, will always be the same for a particular input, thereby letting you verify a match. Because you just need the hash to perform comparisons, the big benefit to you is that you don’t need to store Sean’s raw (plaintext) password directly in your database, which would be a bad idea.

Another example is a checksum. A checksum is a simple way to know if data has been corrupted or tampered with during storage or transmission. You take the data, hash it, and then send data along with the hash (the checksum). On the receiving end, you’ll apply the same hashing algorithm to the received data and compare that value to the checksum. If they don’t match, your data has been changed. This is one of the strategies Stormpath uses to prevent man-in-the-middle attacks on API requests.

Ciphers on the other hand are your tool if you will need the original raw value (called ‘plaintext’ in cryptography, even if its binary data) eventually. Credit card numbers are a good example here. Sean gives you his credit card and later you’ll need the plain text value to process a transaction. In order to encrypt and decrypt any piece of data you’ll need deal with keys and make sure you’re keeping them safe.

Working with Ciphers

Want to encrypt and decrypt your sensitive data like a boss? Let’s talk ciphers.

Choosing a Cipher Algorithm

If you’re reading this… well, then you should probably stick to AES-256 Encryption as it is approved by the US Military for top-secret material.

Most languages and many security frameworks support multiple cipher algorithms but determining which is appropriate for you is a complex topic outside the scope of this guide. Consult your local cryptanalyst.

Ciphers typically come in a few varieties. Symmetric or Asymmetric Ciphers. Symmetric ciphers can be further categorized into Block or Stream ciphers. Let’s discuss the differences.

Symmetric vs Asymmetric Cipher

Symmetric encryption (aka secret key encryption) uses the same (or trivially similar) key to both encrypt and decrypt data. As long as the sender and receiver both know the key, then they can encrypt and decrypt all the messages that use that use that key. AES and Blowfish are both Symmetric (Block) Ciphers.

But there could be a problem. What happens if the key falls into the wrong hands. Oh No!

Asymmetric ciphers to the rescue. Asymmetric encryption (aka public key encryption) uses a pair of keys, one key to encrypt and the other to decrypt. One key, the public key, is published openly so that anyone one can send you a properly encrypted message. The other key, the private key, you keep secret to yourself so that only you can decrypt those messages. Asymmetric sounds perfect, right? It has limitations too, unfortunately. It’s slower, using up more computing resources than a symmetric cipher and it requires more coordination between parties for each direction of communication.

Consider defaulting to asymmetric encryption until your project requirements suggest otherwise. And always remember to properly secure you private keys.

Block vs Stream Cipher

Symmetric ciphers can be categorized into two sub-categories: Block Ciphers and Stream Ciphers. A Stream Cipher has a streaming key that is used to encrypt and decrypt data. A Block Cipher uses a ‘block’ of data (a ‘chunk’ of bytes = a byte array) as the key that is used to encrypt and decrypt. We recommend most people use Block Ciphers since byte array keys are easy to work with and store. AES and Blowfish are both Block Ciphers for example.

Stream ciphers have their benefits (like speed) but are harder to work with so we don’t generally recommend them unless you know what you’re doing.

There’s a common misconception that Block ciphers are for block data like files and data fields while Stream ciphers are for stream data like network streams. This is not the case. The word ‘stream’ reflects a stream of bits used for the key, not the raw data (again, _plaintext) being encrypted or decrypted.

Securing Keys… Yes

Speaking of securing your keys, you should! No, I’m serious. If someone ever gets a hold of your private keys, all your encrypted data might as well be in plaintext. Like most everything in Cryptography, there are very advanced strategies but most are outside the skill set and budget of most developers. If you can afford key management software, then it’s your best and safest bet. Otherwise, you can still reduce some risk with basic strategies.

  1. Keep your keys on another server and database than your encrypted data.
  2. Keep that server’s security patches 100% up-to-date all the time (Firmware, OS, DB, etc).
  3. Lock down its network access as much as you can. Invest in a good firewall.
  4. Limit who on your team has access to the server and enforce multi-factor authentication for them to access it.

Working with Hashes

Don’t actually care what the original input value was but still need to do other things like matching? Let’s hash it out… get it?

Choosing a Hash Algorithm

Here too, most languages and many security frameworks support a variety of algorithms including MD-2, MD-5 and SHA-1, SHA-256, SHA-384, SHA-512, BCrypt, PBKDF2, and Scrypt. Unless you have a requirement for a particular hashing algorithm, we recommend you stick to BCrypt for secure data like passwords. It is a widely used and reviewed algorithm.

If you’ve heard of Scrypt before, then you’re probably wondering “Shouldn’t I be using Scrypt? Isn’t it better?” Maybe. Cryptanalysts are nothing if not paranoid (to our benefit). The prominent view among experts is that Scrypt is very promising but still too new to be considered a guaranteed bet for most people. So we recommend you stick with Bcrypt for now until more concrete research confirms SCrypt as better.

Salting and Repeated Hashing

For secure data, hashing is often not enough. The same message hashed will always have the same output and can therefore be susceptible to dictionary and rainbow table attacks.

To protect against these attacks, you should use salts. A salt is (preferably) randomly generated data that is used as an input to a hashing algorithm to generate the hash. This way, the same input message with two different salts will have different hashes.

Again, think of a password. If your password is 12345, then the hashed output would be the same anyone else who uses the same password (and very easy to guess for an attacker), unless the password is salted as well and each person has a different salt. Oh, and please don’t use the same salt for every record, that’s not a good idea. Different secure random salts for each password hash is a good idea.

In addition to salting, repeated hashing is recommended. Repeated hashing increases the time it takes someone to try to guess a password. For a user in human time, a difference of milliseconds to half a second is probably negligible. But to an attacker running a script with billions of password candidates, the added time per password can change the time it takes to attack a password from hours to years or even centuries! You’ll need to play with the appropriate number of iterations (or ‘rounds’ in BCrypt speak) in order to find the appropriate balance of security and performance.

What work factor (or # of iterations) should I use?

The complexity of your hashing algorithm comes down to performance versus security. If you’re talking about passwords, then a good rule of thumb is 500 milliseconds to process the algorithm on your production hardware. Most people won’t notice a half second delay during an authentication but it will make an attack prohibitively expensive for many attackers.

Keeping your Hashes and Ciphers up to date

The limiting factors to someone cracking your hashed or encrypted data is compute power and time. If a password is properly hashed with strong salts and a high number of iterations (work factor), it might take an attacker years to break a single password— today. With passwords in particular, you could have a high enough complexity factor so that it takes 0.5 to 1 second to process a password. But Moore’s law presents a problem. Every year compute power doubles and compute costs drop significantly. Moreover, new technologies pop up all the time that give attackers new advantages, like elastic on-demand compute clouds or power GPUs. So, what was a pretty secure hashing strategy today, may not be tomorrow. For any production application, you should be evaluating your strategy at least once a year and perhaps ratcheting up things like the number of hash iterations or salt sizes.

About Stormpath

Stormpath is a user mananagement API for developers. We make it easy to register, login, and manage users without build a database, worrying about data encryption or spending time on maintenance. Stormpath plugs into identity stores like Facebook, Google, LDAP and Active Directory, and also hosts robust user profiles.

Build a Simple App with Node.js, Express, Passport and Stormpath

$
0
0

Node + Stormpath

Since the release of our new node.js Stormpath Library I’ve been itching to get my hands dirty and build something.

So — let’s build something together :)

NOTE: If you’d like to skip the tutorial below and jump straight into the code, I’ve put this app on Github for your viewing pleasure: https://github.com/stormpath/stormpath-express-sample

What We’re Building

I thought a great way to test out the new Stormpath node libraries would be to build a simple website that allows you to do a few things:

  • Create a new account (register) with email and password.
  • Log into your new account (login) with email and password.
  • Display a dashboard page once you’ve logged in, that is only accessible to users with an account.
  • Redirect unauthenticated users who try to access the dashboard back to the login page.
  • Allow a logged in user to log out of their account (logout).

Pretty simple — but that should at least allow us to play around with the new tooling!

In the end, things should look like this:

Node App Home Node App Register Node App Dashboard

Sound good? I thought so!

Intro to Stormpath

If you aren’t already familiar with Stormpath, it’s an API service that allows you to create, edit, and securely store your application’s user accounts and user account data. Stormpath makes it easy to do stuff like:

  • User registration and login.
  • Account verification via email.
  • Password reset via email.
  • Social login.
  • And a bunch of other cool stuff you probably don’t like coding!

So — why should you use Stormpath?

Well, quite simply, we make building user accounts a lot easier, more secure, and more scalable than what you’re probably used to.

Using Stormpath not only allows you to easily build your application out, but it also allows you to scale your site to support millions of users without changing your code, or even needing a database!

So, let’s dive in.

If you don’t already have a Stormpath account and application, you’ll need to create one now — you can do so here: https://api.stormpath.com/register

The rest of this article will assume you have a Stormpath account and API key pair.

The Tools

To build this simple app, we’ll be using

If you’re not familiar with express, you should check it out! express is an awesome web framework for node.js which makes building full-fledged web applications a lot simpler.

One of the most important pieces of express is the middleware layer (powered by connect). This middleware allows you to tap into HTTP requests before they reach your view code, allowing you to do cool stuff like authenticate users, among other things.

Next up is passport. Passport is a generic library for handling user authentication in node web apps. It allows you to abstract away some of the technical details related to handling web session and authentication. We’ll be using this in combination with the official passport-stormpath backend to log users in and out of our new web app.

Lastly, we’ll also be using the official Stormpath node library to register new users (essentially we’ll be sending Stormpath’s API service a POST request when a new user creates an account, this way the user will be stored securely on Stormpath’s servers).

Getting Started

So, now that we’ve covered what this web app will be doing, what it’ll look like, and what we’ll use to build it: let’s get this going!

The first thing you need to do is install node.js (if you don’t already have it installed).

Next, let’s install express.js by running:

1
$ npm install -g express-generator

The express-generator module allows you to easily generate a project skeleton to get started with (yey!).

Now that we have express, let’s create our basic project directory:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ express --css stylus stormpath-express-sample

   create : stormpath-express-sample
   create : stormpath-express-sample/package.json
   create : stormpath-express-sample/app.js
   create : stormpath-express-sample/public
   create : stormpath-express-sample/public/javascripts
   create : stormpath-express-sample/public/images
   create : stormpath-express-sample/public/stylesheets
   create : stormpath-express-sample/public/stylesheets/style.styl
   create : stormpath-express-sample/routes
   create : stormpath-express-sample/routes/index.js
   create : stormpath-express-sample/routes/users.js
   create : stormpath-express-sample/views
   create : stormpath-express-sample/views/index.jade
   create : stormpath-express-sample/views/layout.jade
   create : stormpath-express-sample/views/error.jade
   create : stormpath-express-sample/bin
   create : stormpath-express-sample/bin/www

   install dependencies:
     $ cd stormpath-express-sample && npm install

   run the app:
     $ DEBUG=my-application ./bin/www

Then, of course, you’ll want to go into your project directory and install all of the basic dependencies:

1
2
$ cd stormpath-express-sample
$ npm install

And that’s it for the basic configuration!

Configuration

Now that we have our skeleton application ready (thanks, express!), let’s change our project name in the package.json file.

Open up package.json and change the name field so it says "stormpath-express-sample" instead of "application-name". This will make any errors we have easier to debug later on.

Install Required Modules

The next thing we’ll want to do is install all of the required modules we’re going to be using.

You can install them all by running the following command:

1
$ npm install passport passport-stormpath express-session connect-flash stormpath --save

This command will install:

NOTE: The --save flag instructs node to install the packages, and then add them as dependencies to your project’s package.json file. This way, if you want to bootstrap this project at a later time, you can do so easily by just running npm install.

Set Environment Variables

Now that we’ve installed all the required modules, let’s configure our environment variables.

We’re going to be using environment variables to tell our web app what credentials / secrets to use when running our app.

You’ll want to create a .env file in the root of your project with the following contents:

1
2
3
4
export STORMPATH_API_KEY_ID=xxx
export STORMPATH_API_KEY_SECRET=xxx
export STORMPATH_APP_HREF=xxx
export EXPRESS_SECRET=some_random_string

Obviously, you’ll need to replace these values with the appropriate values! The Stormpath settings (API_KEY_ID, API_KEY_SECRET, and APP_HREF) will be used to tell the app how to communicate with Stormpath. The EXPRESS_SECRET variable is used to make session management secure (this should be a long string of random characters).

If you haven’t already created a Stormpath application, you’ll want to go into the Stormpath admin console and create a new Application called stormpath-express-sample. Once you’ve created this application, you should see an Application REST URL in the web interface — use this URL as the value for your STORMPATH_APP_HREF environment variable.

Once you’ve got the environment variables defined in your .env file, all you need to do is use them:

1
$ source .env

The source command will run the .env file, setting the environment variables in your current terminal session.

Configure Middleware

The next thing we need to do is open up the app.js file and import our dependencies. You’ll want to make the top of your app.js file look like the below:

1
2
3
4
5
6
7
8
9
10
11
12
var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

// These are the new imports we're adding:
var passport = require('passport');
var StormpathStrategy = require('passport-stormpath');
var session = require('express-session');
var flash = require('connect-flash');

Now that we have our dependencies imported, let’s configure them!

In app.js, you’ll want to add the following:

1
2
3
4
5
6
7
var app = express();

// Here is what we're adding:
var strategy = new StormpathStrategy();
passport.use(strategy);
passport.serializeUser(strategy.serializeUser);
passport.deserializeUser(strategy.deserializeUser);

Next, we need to configure some of our middleware in app.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));

// Stuff we're adding:
app.use(session({
  secret: process.env.EXPRESS_SECRET,
  key: 'sid',
  cookie: {secure: false},
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());

This just tells express to activate our middleware components.

I learned how to do all of the above by reading through the project documentation for the following libraries (it’s nothing special!):

Now we’re ready to move onto the good stuff: our routes.

Writing the Routes

Writing routes is where the real action happens.

We’re going to define several routes:

  • A / route which just displays a simple home page.
  • A /register route which renders a registration page. This route will need to accept both GET and POST requests.
  • A /login route which will allow existing users to log in. This route will need to accept both GET and POST requests as well.
  • A /logout route which will log users out of their account.
  • A /dashboard route which will display a dashboard page for logged in users.

To keep things orderly, let’s create two separate route files.

First, open up the routes/index.js file and replace its contents with the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var express = require('express');
var router = express.Router();


// Render the home page.
router.get('/', function(req, res) {
  res.render('index', {title: 'Home', user: req.user});
});


// Render the dashboard page.
router.get('/dashboard', function (req, res) {
  if (!req.user || req.user.status !== 'ENABLED') {
    return res.redirect('/login');
  }

  res.render('dashboard', {title: 'Dashboard', user: req.user});
});

module.exports = router;

This index.js route file holds all of the main website routes (anything not auth related).

Next, create a new file named routes/auth.js and add the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
var express = require('express');
var router = express.Router();
var passport = require('passport');
var stormpath = require('stormpath');


// Render the registration page.
router.get('/register', function(req, res) {
  res.render('register', {title: 'Register', error: req.flash('error')[0]});
});


// Register a new user to Stormpath.
router.post('/register', function(req, res) {

  var username = req.body.username;
  var password = req.body.password;

  // Grab user fields.
  if (!username || !password) {
    return res.render('register', {title: 'Register', error: 'Email and password required.'});
  }

  // Initialize our Stormpath client.
  var apiKey = new stormpath.ApiKey(
    process.env['STORMPATH_API_KEY_ID'],
    process.env['STORMPATH_API_KEY_SECRET']
  );
  var spClient = new stormpath.Client({ apiKey: apiKey });

  // Grab our app, then attempt to create this user's account.
  var app = spClient.getApplication(process.env['STORMPATH_APP_HREF'], function(err, app) {
    if (err) throw err;

    app.createAccount({
      givenName: 'John',
      surname: 'Smith',
      username: username,
      email: username,
      password: password,
    }, function (err, createdAccount) {
      if (err) {
        return res.render('register', {title: 'Register', error: err.userMessage});
      } else {
        passport.authenticate('stormpath')(req, res, function () {
          return res.redirect('/dashboard');
        });
      }
    });
  });

});


// Render the login page.
router.get('/login', function(req, res) {
  res.render('login', {title: 'Login', error: req.flash('error')[0]});
});


// Authenticate a user.
router.post(
  '/login',
  passport.authenticate(
    'stormpath',
    {
      successRedirect: '/dashboard',
      failureRedirect: '/login',
      failureFlash: 'Invalid email or password.',
    }
  )
);


// Logout the user, then redirect to the home page.
router.get('/logout', function(req, res) {
  req.logout();
  res.redirect('/');
});


module.exports = router;

This auth.js route file contains all the routes that handle user-specific stuff: registration, login, and logout.

Now that we’ve created our routes, we have to also plug them into the main app.js file so they’ll be used by express.

First, remove the existing routes near the top of your app.js file:

1
2
3
4
5
6
app.use(passport.session());
app.use(flash());

// Remove these two lines.
var routes = require('./routes/index');
var users = require('./routes/users');

Next, add in the following two lines to replace the ones you just removed:

1
2
var index_routes = require('./routes/index');
var auth_routes = require('./routes/auth');

After importing the routes, we’ll also need to bind them to express’ URL routing mechanism:

1
2
3
4
5
6
app.use(passport.session());
app.use(flash());

// Specify the routes here.
app.use('/', index_routes);
app.use('/', auth_routes);

Then, delete the existing routes that were there — the lines you’ll want to remove are the following:

1
2
3
// Remove these two lines:
app.use('/', routes);
app.use('/users', users);

And with the changes above made — we’ve just successfully finished writing our routes! In the next section, we’ll dive into understanding the routes, and explain why things work the way they do.

Understanding the Routes

Now that we’ve defined our routes, let’s see how they actually work!

The Home Page Route

Let’s start by looking at the home page route:

1
2
3
4
// Render the home page.
router.get('/', function(req, res) {
  res.render('index', {title: 'Home', user: req.user});
});

The home page route isn’t doing much other than rendering a template (which we have yet to create!), and passing in some variable values.

The important thing to note here is the title and user values. We’ll use the title variable in our template to generate a nice HTML title for the page. We’ll also use the user variable to tell us whether or not the person viewing the home page is a user or not.

If the person viewing the page IS a user, then instead of displaying a Login button on the website, we’ll just display a link to the Dashboard page.

The req.user variable is automatically populated for us by passport. It will either be undefined, or a JSON object of this user’s account.

The Dashboard Route

The dashboard route is also quite simple:

1
2
3
4
5
6
7
8
9
10
11
12
// Render the dashboard page.
router.get('/dashboard', function (req, res) {
  if (!req.user || req.user.status !== 'ENABLED') {
    return res.redirect('/login');
  }

  res.render('dashboard', {
    title: 'Dashboard',
    user: req.user,
    }
  );
});

The first thing we’ll do here is check to see if the person viewing this page is a user, and then, if their account is enabled or not (Stormpath allows you to have users that disabled).

If the person viewing our dashboard page isn’t a valid user, we’ll redirect the user to the login page.

If the person IS a valid user, we’ll render our dashboard page (simple — right?).

The Registration Route

Now we’ll dive into the authentication routes. We’ll start by looking at our registration route — which is responsible for signing up new users.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// Render the registration page.
router.get('/register', function(req, res) {
  res.render('register', {title: 'Register', error: req.flash('error')[0]});
});


// Register a new user to Stormpath.
router.post('/register', function(req, res) {

  var username = req.body.username;
  var password = req.body.password;

  // Grab user fields.
  if (!username || !password) {
    return res.render('register', {title: 'Register', error: 'Email and password required.'});
  }

  // Initialize our Stormpath client.
  var apiKey = new stormpath.ApiKey(
    process.env['STORMPATH_API_KEY_ID'],
    process.env['STORMPATH_API_KEY_SECRET']
  );
  var spClient = new stormpath.Client({ apiKey: apiKey });

  // Grab our app, then attempt to create this user's account.
  var app = spClient.getApplication(process.env['STORMPATH_APP_HREF'], function(err, app) {
    if (err) throw err;

    app.createAccount({
      givenName: 'John',
      surname: 'Smith',
      username: username,
      email: username,
      password: password,
    }, function (err, createdAccount) {
      if (err) {
        return res.render('register', {title: 'Register', error: err.userMessage});
      } else {
        passport.authenticate('stormpath')(req, res, function () {
          return res.redirect('/dashboard');
        });
      }
    });
  });

});

The first bit just renders the registration page for GET requests.

The second bit is where things get interesting.

Firstly, we’re checking for a username and password field from the HTTP form. This is what the user will be submitting to us when they create a new account. (The username field is actually an email address, but I’ll explain this in more detail later.)

Next, we’ll re-render the registration page (with an error message) if either the username or password fields are missing.

After that’s out of the way, we need to initialize the Stormpath client. This involves using our API key credentials to make a new client, and then fetching our Stormpath application (since we’ll need to create this new user account inside of our application namespace).

Once we’ve fetched our Stormpath application, we’ll then create a new user account using the createAccount method. Since Stormpath requires (at minimum):

  • givenName
  • surname
  • email
  • and password

fields — but we only want to store email / password — I’m just setting the givenName and surname values to 'John' and 'Smith'.

NOTE: If the user account creation fails, we’ll render the registration page and pass in an appropriate error message from Stormpath. This will automatically handle problems like users attempting to register with an email that already exists.

If everything goes smoothly, we’ll use the passport.js library to log this new user in (creating a session, transparently), then redirect the user to the dashboard page.

The Login Route

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Render the login page.
router.get('/login', function(req, res) {
  res.render('login', {title: 'Login', error: req.flash('error')[0]});
});


// Authenticate a user.
router.post(
  '/login',
  passport.authenticate(
    'stormpath',
    {
      successRedirect: '/dashboard',
      failureRedirect: '/login',
      failureFlash: 'Invalid email or password.',
    }
  )
);

The login routes (shown above) are responsible for logging existing users back into the site. The GET route only renders the login page, along with an optional error message to display if a user enters invalid credentials.

NOTE: The req.flash('error')[0] you see is provided by the connect-flash library. If a login fails, the passport.js library will embed a tiny little ‘error’ message in a cookie, which is what the req.flash('error')[0] call then retrieves.

The POST request is completely offloaded to the passport.js library. passport provides the authenticate method which will transparently check the username and password form fields against the Stormpath API, and take care of login automatically.

If the login is successful, passport will redirect the user to the dashboard page — otherwise, it’ll re-render the login page once more, along with a friendly error message.

The Logout Route

1
2
3
4
5
// Logout the user, then redirect to the home page.
router.get('/logout', function(req, res) {
  req.logout();
  res.redirect('/');
});

The logout route (above) will log the user out of their account, destroying their session cookies.

The passport library automatically adds a logout method onto the req object, which makes it easy to log a user out of their account.

Once we’ve logged the user out, we simply redirect them back to the home page.

Writing the Templates

The last big thing we have to do is define our templates. The templates are the HTML layer that gets presented to users.

Let’s get started!

Create a Layout

The first thing we’ll want to do is create a layout.jade template. By default, our new express app is using the jade templating language (check it out if you haven’t, it’s quite cool).

Here’s our views/layout.jade template:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
doctype html
html
  head
    meta(charset='utf-8')
    meta(content='IE=edge', http-equiv='X-UA-Compatible')
    meta(content='width=device-width, initial-scale=1', name='viewport')
    title= 'Express-Stormpath (sample) | ' + title
    link(href='/css/bootstrap.min.css', rel='stylesheet')
    link(href='/css/style.css', rel='stylesheet')
    <!--[if lt IE 9 ]>
    <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
  body
    .container
      .header
        ul.nav.nav-pills.pull-right
          li
            a(href='/') Home
          if user
            li
              a(href='/dashboard') Dashbaord
            li
              a(href='/logout') Logout
          else
            li
              a(href='/login') Login
        h3.text-muted Flask-Express
      block body
    script(src='https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js')
    script(src='/js/bootstrap.min.js')

The main thing our fancy new layout template does is provide a basic HTML page layout that all our other pages will use.

The line which reads block body will be overridden by our other templates.

The most important bit to take note of here is the nav menu:

1
2
3
4
5
6
7
8
9
if user
  li
    a(href='/dashboard') Dashbaord
  li
    a(href='/logout') Logout
else
  li
    a(href='/login') Login
      block body

We’re using a simple conditional here to check to see whether or not a user is logged in or not (if user), and changing the links the visitor sees accordingly. This ensures that if a user is logged in, and on the homepage — they won’t see a ‘Login’ button displayed in the navbar.

The Home Page Template

Place the following code into: views/index.jade:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
extends layout

block body

  #welcome.jumbotron
    h1 Welcome to Stormpath-Express
    p.lead.
      <br/>
      <br/>
      Welcome to this gloriously simple <a href="https://github.com/stormpath/stormpath-express-sample">Stormpath</a>
      sample app!
    ul
      li First, take a look through this very basic site.
      li.
        Then, check out this project's source code
        <a href="https://github.com/stormpath/stormpath-express-sample">on GitHub</a>.
      li Lastly, integrate Stormpath into your own sites!
    <br/>
    <br/>
    h2 What this Sample App Demonstrates
    br
    p.
      This simple app demonstrates how easy it is to register, login, and
      securely authenticate users on your website using Stormpath.
    p.
      Aren't a Stormpath user yet?
      <a href="https://stormpath.com">Go signup now!</a>
    p.
      <b>NOTE</b>:
      This app will NOT work until you have gone through the bootstrapping
      instructions found in this project's <code>README.md</code> file. For more
      information, please follow the guide on this project's
      <a href="https://github.com/stormpath/stormpath-express-sample">GitHub page</a>.
    p.bigbutton
      a.bigbutton.btn.btn-lg.btn-danger(href='/register', role='button') Register

This is our home page template. All it does is render some static information for users, so there isn’t much to go into here.

Since our layout.jade template is already handling our user-smart nav bar, we don’t need to do anything special :)

The Registration Template

Place the following code into views/register.jade:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
extends layout

block body

  .register
    .row
      .col-lg-6.col-lg-offset-3
        form.bs-example.form-horizontal(method='post', action='')
          fieldset
            legend Create a New Account
            if error
              .alert.alert-dismissable.alert-danger.register-fail
                button.close(data-dismiss='alert', type='button') &times;
                p.
                  #{error}
            p.
              Registering for this site will create a new user account for you
              via <a href="https://stormpath.com">Stormpath</a>, then log you in
              automatically.
            .alert.alert-dismissable.alert-info
              button.close(data-dismiss='alert', type='button') &times;
              strong NOTE:&nbsp;
              Your password must be between 8 and 100 characters, and must
              contain lowercase letters, uppercase letters, and numbers.
            .form-group
              label.col-lg-4.control-label(for='username') Email
              .col-lg-4
                input#username.form-control(name='username', type='email', placeholder='Email', autofocus)
            .form-group
              label.col-lg-4.control-label(for='password') Password
              .col-lg-4
                input#password.form-control(name='password', type='password', placeholder='Password')
            .form-group
              .col-lg-10.col-lg-offset-4
                button.btn.btn-primary(type='submit') Register
        h2 A Note About Stormpath Security
        p.
          In a real environment, you should <b>only deploy your application</b>
          behind SSL / TLS to avoid having user credentials sent in plain text
          over the network.
        p.
          Stormpath user creation is incredibly secure, is not susceptible to
          any known vulnerabilities (MITM, hashing issues, replace attacks,
          etc.), and provides you with a number of options to improve security
          (including buil-in email verification, among other things).  We will
          not verify your account by email now, but this can be easily enabled.
        p.last-p.
          Stormpath can also be configured to allow for weaker (or force
          stronger) passwords, so it can fit into any application workflow.

This page handles user registration.

Take a close look at the form — we’re specifying two fields for the user to input: email and password. Take a look at the email input box, however:

1
input#username.form-control(name='username', type='email', placeholder='Email', autofocus)

Although we’re collecting a user’s email address here, we’re setting the HTML name attribute to the value username. This is to make passport happy.

Passport expects username and password form elements, so that’s what we’ll use (despite the fact that we’re signing a user with just email / password).

We’ll also render an error message to the user (if there is one). This will be called if the registration fails for some reason, displaying a user-friendly error message.

The Login Template

Start by putting the following code into views/login.jade:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
extends layout

block body

  .login
    .row
      .col-lg-6.col-lg-offset-3
        form.bs-example.form-horizontal(method='post', action='')
          fieldset
            legend Login
            if error
              .alert.alert-dismissable.alert-danger.login-fail
                button.close(type='button', data-dismiss='alert') &times;
                p.
                  #{error}
            p.last-p.
              Once you enter your credentials and hit the Login button below,
              your credentials will be securely sent to
              <a href="https://stormpath.com">Stormpath</a> and verified.  If
              your credentials are valid, you'll be logged in using a secure
              session -- otherwise, you'll get a user friendly error message.
            .form-group
              label.col-lg-4.control-label(for='username') Email
              .col-lg-4
                input#username.form-control(type='email', name='username', placeholder='Email', autofocus)
            .form-group
              label.col-lg-4.control-label(for='password') Password
              .col-lg-4
                input#password.form-control(type='password', name='password', placeholder='Password')
            .form-group
              .col-lg-10.col-lg-offset-4
                button.btn.btn-primary(type='submit') Login

The login template works almost exactly like the registration template we talked about previously. Although we ask users to log in with an email and password, we secretly name the email input field username to make passport happy.

Other than that, things work as you would expect if there is an error, we’ll display a user-friendly error message.

The Dashboard Template

Put the following code into views/dashboard.jade:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
extends layout

block body

  .dashboard
    .row
      .col-lg-12
        .jumbotron
          h1 Dashboard
          br
          br
          p Welcome to your user dashboard!
          p.
            This page displays some of your user information using Jade
            templates.
          p.
            If you click the Logout link in the navbar at the top of this page,
            you'll be logged out of your account and redirected back to the main
            page of this site.
          p.
            Your user account information is being securely stored using
            passport sessions, and Stormpath as the authentication backend.
          br
          br

This is probably the simplest of all the templates — it just renders some static content.

This page is only accessible to logged in users.

Static Assets

The last thing we need to do before we can run our awesome new project is drop in our static assets. This mainly involves copying over Twitter Bootstrap (I’m not a good designer, OK!).

You can run the following commands to download the necessary files locally (into your public directory):

1
2
3
4
$ mkdir -p public/{css,js}
$ wget https://raw.githubusercontent.com/stormpath/stormpath-express-sample/master/public/css/bootstrap.min.css --directory-prefix public/css
$ wget https://raw.githubusercontent.com/stormpath/stormpath-express-sample/master/public/css/style.css --directory-prefix public/css
$ wget https://raw.githubusercontent.com/stormpath/stormpath-express-sample/master/public/js/bootstrap.min.js --directory-prefix public/js

Let’s Run This Thing

Now that we’ve gone through the entire project from start to finish, let’s run this thing!

From the command line, you should be able to run npm start at the root of your project, to launch a local web server on port 3000:

1
2
3
4
5
$ npm start

> stormpath-express-sample@0.0.1 start
> /Users/rdegges/stormpath-express-sample
> node ./bin/www

Now, open your browser and visit http://localhost:3000. Assuming everything is working well, you should be able to register a new account on the site, visit the dashboard, logout, and log back in again — with no problems.

Here’s how things should look:

Lastly — all this code is available on Github here: https://github.com/stormpath/stormpath-express-sample

Final Thoughts

Firstly, if you made it to the bottom of this post: thanks! Hopefully you enjoyed building this node app along with me!

With that said, in the future, we’re planning on expanding our Stormpath support for both node.js and passport.js to make integration even simpler.

Among other things, we’d like to:

  • Make registering users a one liner (instead of requiring custom development work).
  • Make asserting user permissions simple and effortless (making it easy to handle user groups and permissions at a fine-grained level).
  • Make our passport.js middleware more magical by having it automatically patch user data into templates for rendering.
  • Make our passport.js strategy support caching clusters (or either Redis or Memcached) — this way you’ll be able to speed up user sessions quite a bit by avoiding round-trips to the Stormpath REST API.

Got anything else you think would be cool to see added? Please drop us a line! We’d love to hear from you :)

Best,

-Randall

New Flask-Stormpath Release

$
0
0

Flask App in 30 minutes

Like writing websites in Flask? Me too!

Over the past several weeks I’ve spent a ton of time hacking on the latest release of our brand new Flask-Stormpath library.

Since the first release last month, I’ve received a ton of feedback — suggestions, ideas, and criticisms about what could be done better. It was incredibly exciting!

With the latest release of the Flask-Stormpath library (0.2.0), the entire library has changed — dramatically. It’s no longer a simple wrapper around Stormpath, but a full blown user authentication system that goes out of its way to automate and remove as much pain as possible from your web apps.

NOTE: Want to skip the fuss and just use it already? You can install it via pip: $ pip install -U flask-stormpath

What’s New!

The latest edition of Flask-Stormpath includes several awesome new features:

  • Completely revamped documentation (check it out!)
  • Built-in views for handling registration, login, and logout
  • Built-in templates for registration and login pages. (They even look good!)
  • Fully integrated social login with Facebook and Google
  • Incredibly flexible library settings — you can fully control all aspects of the library just by modifying your Flask config: no coding needed!

What’s my favorite thing about the new release? Good question!

You can now add simple and secure user authentication to any Flask website in as little as one line of code! Seriously. And you don’t even need a database!

Here’s what our new built-in registration and login pages look like (without customization, of course):

Flask Registration Page Flask Login Page

Quick Usage

Want to give it a go? Read through our new and improved quickstart

Get stuck? Have questions? Email me! randall@stormpath.com

Future Additions

In the near future we’re going to be adding several features which will make the library even nicer:

  • API authentication. (Building a public or private API service? Secure it with Stormpath!)
  • Account verification via email. There will be a setting that allows you to automatically handle user account verification via email.
  • Password reset views and templates (by default!).
  • Cache cluster support (speed up your site by caching to redis or memcache).
  • Single factor authentication. Want to log users in with email only? Just wait!
  • Post-registration hooks. Want to plug your new users into MailChimp or Intercom? The integrations are coming!
  • Have something you want to see included? Email me! randall@stormpath.com

Facebook Login Guide

$
0
0

Facebook Login Guide

Social login is becoming a more and more popular form of web authentication — it’s easy and convenient for users, which means more and more sites are adopting it. When it comes to social login, there are essentially two providers people care about: Facebook and Google.

At Stormpath, we recently built our own Facebook and Google Login integration — and figured we’d share what we’ve learned recently in this article.

This article will show you exactly how Facebook Login works, and how you can easily plug it into your website.

NOTE: If you’re looking for a drop-dead easy way to do Facebook Login, you might want to check out our brand new Facebook Login integration. I think you’ll enjoy it.

High Level Overview

I’m sure you’ve used Facebook Login at least once or twice (if not, where do you live? Under a rock!?).

The way Facebook Login works is theoretically quite simple:

  • A user visits your site and sees a big “Sign in with Facebook” button somewhere.
  • A user clicks that button, and gets a little popup window asking the user to accept an array of permissions.
  • The user clicks “Okay”, the popup closes, and the user is back on their original page — but this time, they’re “logged in”.

This high-level flow is what’s known as OAuth 2.0. OAuth is convenient for users because it means they don’t need to manually create an account on each website they visit — they can use a single account everywhere.

Adding Facebook Login to Your Site

Adding Facebook Login to a site is a fairly involved process. The simplest way to do it is by using the Facebook Javascript SDK.

The idea is that you add a button to your site which, when clicked, redirects the user to Facebook to accept permissions, then back to your site when everything is done.

The downside to using Facebook Login this way is that all authentication is done via Javascript, so complex server-side applications require substantially more work to function.

This guide will cover using the Javascript SDK only (as it is much simpler to explain).

Getting Started: Create a Facebook App

The first thing you need to do in order to support Facebook Login on your site is create a Facebook App.

To do this, you’ll want to head over to the Facebook Developer Center and create or log into your Facebook account.

Once you’ve logged in, you should be redirected back to the main Facebook Developer page, where you’ll see a top navbar that looks like this:

Facebook Dev Center Navbar

To create a new Facebook App, click the “Apps” navbar tab, then click “Create a New App”. You’ll now see a window where you can enter a “Display Name” (usually the name of your website), and pick a “Category” (the category of your website).

You should see something that looks like this:

Facebook Create App

Enter these values, then click “Create App”. This will provision a new Facebook App for your website, eventually allowing users to log into your website.

After you’ve created your new Facebook App, you’ll be redirected to your new App dashboard! If all went well, you should now be at a page that looks like this:

Facebook App Dashboard

This Dashboard page contains some useful stats (how many people have logged into your website?) which you might find useful in the future — as well as your Application’s ID and Secret.

The Application ID and Secret will be used later on.

Set Your Site URL

In order to support Facebook Login, you need to let Facebook know what URL(s) your website will be running at. This way, Facebook can verify that a user is actually being asked for permissions from the correct Facebook App.

To do this, click the “Settings” tab on the left nav menu, and click the “Add Platform” button near the bottom of the page.

When prompted, select “Website” as your platform.

In the “Site URL” box that appears, you’ll want to enter your website URL.

For this example, I’m going to enter “http://localhost:8000” — as I’m going to be testing this out on my local machine, on port 8000. You might want to set this to something like: “http://mysite.com” if you’re testing this out on a public domain.

Facebook URLs

NOTE: If you want to allow Facebook Login to work from multiple URLs (maybe you use http://localhost:8000 for local development, and https://mysite.com in production) you can simply click the “Add Platform” button again and enter another URL.

Include the Facebook Javascript SDK in Your HTML

The next thing you need to do is include the Facebook Login button somewhere on your website. You can do this by copy+pasting the following code into your HTML code (this will render a Facebook Login button on your website).

Here’s the code you need to add:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<button onclick="facebookLogin()">Facebook</button>
<script>
  function facebookLogin() {
    var FB = window.FB;
    var scopes = 'email,user_likes,public_profile';

    FB.login(function(response) {
      if (response.status === 'connected') {
        console.log('The user has logged in!');
        FB.api('/me', function(response) {
          console.log('Good to see you, ' + response.name + '.');
        });
      }
    }, {scope: scopes});
  }

  window.fbAsyncInit = function() {
    FB.init({
      appId      : 'YOUR_FACBEOOK_APP_ID',
      cookie     : true,
      xfbml      : true,
      version    : 'v2.0'
    });
  };

  (function(d, s, id){
     var js, fjs = d.getElementsByTagName(s)[0];
     if (d.getElementById(id)) {return;}
     js = d.createElement(s); js.id = id;
     js.src = "//connect.facebook.net/en_US/sdk.js";
     fjs.parentNode.insertBefore(js, fjs);
   }(document, 'script', 'facebook-jssdk'));
</script>

There are a few things to take notice of here:

  1. You can choose what permissions you request from the user by modifying the scopes variable (in this example it is set to request 'email,user_likes,public_profile). For more information on Facebook permissions, visit this page: https://developers.facebook.com/docs/facebook-login/permissions

  2. You need to replace YOUR_FACBEOOK_APP_ID with your App ID number from the App Dashboard page you saw earlier.

  3. When a user clicks the Facebook button, the facebookLogin() Javascript function will run. This is what controls the pop-up, and post-login behavior. In this case, after a user has logged in, we’re using the Facebook API to grab the user’s information and print some debug information to the developer console.

If you run this code in a simple HTML document, you’ll get a page that looks like the following:

Facebook Login Raw

When you click the Facebook button, you should then see the standard permissions pop-up — it looks like this:

Facebook Perm Request

Lastly, when you accept the permissions, you’ll notice that our Javascript console.log messages worked!

Facebook Console

Handle User Authentication

After including the Facebook Login button on your site, you can then handle user authentication with Javascript.

On any web page where you want to enforce user authentication, you can do something like the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<script>
  FB.getLoginStatus(function(response) {
    if (response.status === 'connected') {
      // If the user gets here, they're logged in.
      console.log('Logged in.');
    }
    else {
      // Redirect unauthenticated users to the login page.
      window.location.replace('/login');
    }
  });

  window.fbAsyncInit = function() {
    FB.init({
      appId      : 'YOUR_FACBEOOK_APP_ID',
      cookie     : true,
      xfbml      : true,
      version    : 'v2.0'
    });
  };

  (function(d, s, id){
     var js, fjs = d.getElementsByTagName(s)[0];
     if (d.getElementById(id)) {return;}
     js = d.createElement(s); js.id = id;
     js.src = "//connect.facebook.net/en_US/sdk.js";
     fjs.parentNode.insertBefore(js, fjs);
   }(document, 'script', 'facebook-jssdk'));
</script>

The FB.getLoginStatus function provided by the Facebook Javascript SDK allows you to easily check to see whether or not the current visitor is successfully authenticated with Facebook (or not).

This code above will redirect any non-authenticated users back to the login page (/login), and all other users will remain on the page.

NOTE: While this is great for simple apps, if you’re building something where security is an issue, you should probably use the more complicated server-side Facebook authentication flow. Stormpath makes this incredibly easy: https://stormpath.com/blog/the-social-integration/

Conclusion

Facebook Login (via Javascript) isn’t that bad! It’s easy to implement and style (you can change your button styles with CSS), but for more complex authentication requirements, you should probably use the server-side flow.

Hopefully this short guide has been helpful! Have any questions? Shoot us an email! support@stormpath.com

Flask Auth in One Line of Code

$
0
0

Flask Auth in One Line of Code

Ever since I wrote about the authentication problem in the Flask ecosystem a few months back, I’ve been working hard to build a simple abstraction to solve these issues.

When I launched the first version of Flask-Stormpath, I got a ton of incredibly great feedback from the community, and learned a lot — namely, people don’t want to worry about user authentication at all.

The Problem (a Recap) + A v.1 Solution

The “Authentication Problem” in the Flask ecosystem is this: since Flask has no built-in ORM or tooling — almost every Flask developer ends up rolling their own form of user authentication. There are currently no libraries which solve all of the authentication problems. So, I built a first release of a Flask + Stormpath integration, which solved some big authentication problems in Flask:

  • Centralized (secure) user store.
  • No need to worry about hashing passwords or JOIN’ing database tables — that bit was handled automatically.
  • Easy to use user accounts.
  • Secure sessions.

After launch, I got a ton of excellent user feedback (thanks everyone!). After talking with lots of people, using the library myself, and writing a Flask beginner tutorial, I realized that the first version of Flask-Stormpath was not really as good as I initially thought.

Learning and Planning

I realized that by even explaining how to do things like create registration, login, and logout views was a total waste of time — why should developers have to do this stuff themselves?

So, I decided to revamp the initial Flask-Stormpath design and simplify all developer-facing code, such that:

  • Users could get registration, login, and logout working without writing any view code at all.
  • Users could control basic authentication features through app config variables (this way things are still flexible).
  • Users should be able to support social login with both Google and Facebook without doing any additional work.

Introducing the New Flask-Stormpath

I’m incredibly excited to announce the newest release of Flask-Stormpath — it contains a huge number of improvements over the first release, and makes handling user authentication in Flask apps incredibly simple.

In simple cases, registration, login, and logout are only a single line of code! No database required!

Here’s how this looks in practice:

1
2
3
4
5
6
7
8
9
10
11
from os import environ

from flask.ext.stormpath import StormpathManager

# ...
app.config['STORMPATH_API_KEY_ID'] = environ.get('STORMPATH_API_KEY_ID')
app.config['STORMPATH_API_KEY_SECRET'] = environ.get('STORMPATH_API_KEY_SECRET')
app.config['STORMPATH_APPLICATION'] = environ.get('STORMPATH_APPLICATION')

# This is where the magic happens.
StormpathManager(app)

As you can see, we’re defining some settings, and initializing a StormpathManager. What does this get you?

Firstly, you get a fully functional registration page out-of-the-box:

New Flask Registration Page

You also get a beautiful login page out-of-the-box (note the Google and Facebook buttons):

New Flask Login Page

And lastly, you get logout functionality (if a user visits /logout they’ll be logged out and redirected back to the site root).

There are currently three built-in views (along with templates and URL routes):

  • A registration view / template / route (bound to /register by default).
  • A login view / template / route (bound to /login by default).
  • A logout view / route (bound to /logout by default).

To make things even nicer, each of these views is 100% customizable — and dynamically configure themselves based on your Flask settings.

Let’s take a deeper look!

Authentication Customization

Let’s say you’d like to modify the registration fields you accept when signing up new users. Flask-Stormpath supports several user fields for registration:

  • email (required)
  • password (required)
  • given_name (first name)
  • surname (last name)
  • middle_name
  • username

So, let’s say you want to remove the first, middle, and last name fields from the registration page — you could simply set the following configuration variables:

1
2
3
4
# ...
app.config['STORMPATH_ENABLE_GIVEN_NAME'] = False
app.config['STORMPATH_ENABLE_MIDDLE_NAME'] = False
app.config['STORMPATH_ENABLE_SURNAME'] = False

And just like that, those fields will disappear:

New Flask Login Page (no names)

Want to include an optional username field? Simple! Just add the following config:

1
2
3
# ...
app.config['STORMPATH_ENABLE_USERNAME'] = True
app.config['STORMPATH_REQUIRE_USERNAME'] = False

Each of the available fields can be both ‘ENABLED’ and ‘REQUIRED’ to your liking. This makes building dynamic registration / login pages incredibly easy.

But wait! There’s more!

You can also easily change the default routes around:

1
2
3
4
# ...
app.config['STORMPATH_REGISTRATION_URL'] = '/user/register'
app.config['STORMPATH_LOGIN_URL'] = '/user/login'
app.config['STORMPATH_LOGOUT_URL'] = '/user/logout'

And changing templates is equally easy:

1
2
3
# ...
app.config['STORMPATH_REGISTRATION_TEMPLATE'] = 'register.html'
app.config['STORMPATH_LOGIN_TEMPLATE'] = 'login.html'

NOTE: The official template documentation has all the information you could ever need / want on how to build you own registration / login templates (it’s super easy!).

Furthermore, handling social login is incredibly simple. You can easily enable or disable social login support for both Facebook and Google by modifying configuration variables alone:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# ...
app.config['STORMPATH_ENABLE_FACEBOOK'] = True
app.config['STORMPATH_ENABLE_GOOGLE'] = True
app.config['STORMPATH_SOCIAL'] = {
    'FACEBOOK': {
        'app_id': 'xxx',
        'app_secret': 'xxx',
        'scopes': ['user_likes'],
    },
    'GOOGLE': {
        'client_id': 'xxx',
        'client_secret': 'xxx',
        'scopes': ['profile'],
    },
}

Full examples for adding social login to your site can be found here (including in-depth instructions for creating Facebook / Google apps).

And if you’re not interested in any of the automatic stuff that’s built in, you can disable it all with only three config variables:

1
2
3
4
# ...
app.config['STORMPATH_ENABLE_REGISTRATION'] = False
app.config['STORMPATH_ENABLE_LOGIN'] = False
app.config['STORMPATH_ENABLE_LOGOUT'] = False

Not bad, right?

New Design

The new Flask-Stormpath design is based around abstraction: the main idea is to make authentication as simple and painless as humanly possible. If you’re building a Flask app, you no longer have to worry about storing / securing user data at all — it’s completely handled, scaled, and secured.

From this point forward, I’ll be slowly adding more convenience features to the Flask-Stormpath integration to handle other things as well:

  • Email verification for new users.
  • API key authentication (an awesome new feature for securing REST APIs).
  • Password reset.
  • Distributed caching support (redis, memcache, etc.).

I’m extremely excited about the new Flask-Stormpath, and hope you are too!

If you end up giving it a try, I’d love to hear your feedback.

Furthermore, if you aren’t already a Stormpath user — you should go create an account right now! It’s free for up to 100,000 API requests per month! That means most small to medium sized projects can use Stormpath for zero cost, ever.

And as always, I’d love to hear from you! Please hit me up (I’m randall@stormpath.com).


Enrich Your User Accounts with Stormpath

$
0
0

Bonsai Sketch

While Stormpath is great for storing user accounts — did you know you can also store custom data for each user? Stormpath’s custom data makes it possible to store rich profile data and other information on a user account.

Earlier this week I sat down and built a new tool, stormpath-enrich, using our brand new Node Library.

enrich is a simple Node.js command line tool which analyzes your Stormpath user accounts, finds a plethora of information on each user (by email address), then stores this data in your user account’s custom data store.

enrich makes it incredibly easy to build rich user profiles automatically!

Enrich Your User Accounts

Let’s take a look at what enrich actually does!

Let’s say you’ve got a Stormpath Application with several user accounts, one of which has an email address, r@rdegges.com.

When you run enrich, it’ll go through each user account, and do several things:

  • Grab the user’s email address.
  • Use FullContact’s API service to search for publicly available information on this user.
  • Store whatever information is available in your Stormpath user account’s custom data store — so you can access it later.

FullContact is an extremely useful API service which scours the web for information about users by email address — it will scrape information from Facebook, Twitter, Google, etc., and return a single record with all of the user’s information.

When I run enrich on my personal account, I get the following custom data stored in my user account:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
{
  "contactInfo": {
    "familyName": "Degges",
    "fullName": "Randall Degges",
    "givenName": "Randall",
    "websites": [
      {
        "url": "http://rdegges.com"
      },
      {
        "url": "http://www.theherokuhackersguide.com/"
      },
      {
        "url": "http://www.pycall.org/"
      },
      {
        "url": "http://rdegges.com/"
      },
      {
        "url": "http://www.telephonyresearch.com/"
      }
    ]
  },
  "demographics": {                                                                                                                                                          [81/208]
    "gender": "Male",
    "locationGeneral": "California, USA"
  },
  "organizations": [
    {
      "current": false,
      "isPrimary": true,
      "name": "Telephony Research",
      "startDate": "2012",
      "title": "Chief Hacker"
    },
    {
      "current": true,
      "isPrimary": true,
      "name": "Stormpath",
      "startDate": "2014-02",
      "title": "Developer Evangelist"
    },
    {
      "current": false,
      "endDate": "2009",
      "isPrimary": false,
      "name": "Fonality",
      "startDate": "2008",
      "title": "Programmer"
    },
    {
      "current": false,
      "endDate": "2012",
      "isPrimary": false,
      "name": "BTS",
      "startDate": "2009",
      "title": "Lead Developer"
    }
  ],
  "photos": [                                                                                                                                                                [45/208]
    {
      "isPrimary": true,
      "type": "facebook",
      "typeId": "facebook",
      "typeName": "Facebook",
      "url": "https://d2ojpxxtu63wzl.cloudfront.net/static/aaf383528d6026df23bb342bbde8b295_f44fb7ef5c407df39029ef3160f4c075a0f82acfa00d30028b396922158cdc01"
    },
    {
      "isPrimary": false,
      "type": "foursquare",
      "typeId": "foursquare",
      "typeName": "Foursquare",
      "url": "https://d2ojpxxtu63wzl.cloudfront.net/static/0cb868fc5a274771605c0e0d7f955ee6_2c5fa7a99f9d322c6476ee374a22467000e88730a06aacc95e328c4e1f8071f2"
    },
    {
      "isPrimary": false,
      "type": "googleplus",
      "typeId": "googleplus",
      "typeName": "Google Plus",
      "url": "https://d2ojpxxtu63wzl.cloudfront.net/static/9c9350196801eb617b70f00b29a78b1c_91431537e46e579dcfbcfaf069196dd1817c82a34ef4481dd06e5bdc6e630601"
    },
    {
      "isPrimary": false,
      "type": "twitter",
      "typeId": "twitter",
      "typeName": "Twitter",
      "url": "https://d2ojpxxtu63wzl.cloudfront.net/static/d0f046119d0f5438924c8442eadb6f1b_2fc73d27aa217ccfb1d969847d8d53d0687986c742a86dd6173cf689ffa749c9"
    },
    {
      "isPrimary": false,
      "photoBytesMD5": "e0139f33ef023149308b26076b240c9a",
      "type": "gravatar",
      "typeId": "gravatar",
      "typeName": "Gravatar",
      "url": "https://d2ojpxxtu63wzl.cloudfront.net/static/8058dbaadafd9ea2859c84c5ecb275d7_49977cacdcd42944e609608797cf5548ba3f8b66881f97399c143212e1809314"
    },
    {
      "isPrimary": false,
      "type": "linkedin",
      "typeId": "linkedin",
      "typeName": "LinkedIn",
      "url": "https://d2ojpxxtu63wzl.cloudfront.net/static/d6ff74c0e6d4e4c48d2daf2be82fd7b8_452404fa403cf2cc1b90611542d39197f8ef7d51b02ec8e8bba3f46142535132"
    }
  ],
  "socialProfiles": [
    {
      "bio": "I'm just a happy programmer that likes to hack stuff.",
      "id": "75427646",
      "type": "foursquare",
      "typeId": "foursquare",
      "typeName": "Foursquare",
      "url": "https://www.foursquare.com/user/75427646"
    },
    {
      "id": "53099533",
      "type": "gravatar",
      "typeId": "gravatar",
      "typeName": "Gravatar",
      "url": "http://gravatar.com/rdegges",
      "username": "rdegges"
    },
    {
      "bio": "I&#39;m the Chief Hacker @ Telephony Research, where I build telephony tools for developers using cool technologies.",
      "followers": 0,
      "following": 0,
      "id": "105723327194710521939",
      "type": "googleplus",
      "typeId": "googleplus",
      "typeName": "Google Plus",
      "url": "https://plus.google.com/105723327194710521939"
    },
    {
      "id": "85568398087900609",
      "type": "klout",
      "typeId": "klout",
      "typeName": "Klout",
      "url": "http://www.klout.com/user/rdegges",
      "username": "rdegges"
    },
    {
      "bio": "I'm just a happy programmer that likes to hack stuff.",
      "followers": 1623,
      "following": 1158,
      "id": "28896389",
      "type": "twitter",
      "typeId": "twitter",
      "typeName": "Twitter",
      "url": "http://www.twitter.com/rdegges",
      "username": "rdegges"
    },
    {
      "bio": "Developer Evangelist at Stormpath",
      "type": "linkedin",
      "typeId": "linkedin",
      "typeName": "LinkedIn",
      "url": "https://www.linkedin.com/pub/randall-degges/8b/34a/132"
    },
    {
      "type": "flickr",
      "typeId": "flickr",
      "typeName": "Flickr",
      "url": "http://www.flickr.com/photos/rdegges",
      "username": "rdegges"
    },
    {
      "bio": "I'm a happy programmer who enjoys using python, django, c, asterisk, freeswitch, opensips, and telephony to build fun, efficient, and awesome apps.",
      "type": "aboutme",
      "typeId": "aboutme",
      "typeName": "About.me",
      "url": "http://about.me/rdegges"
    },
    {
      "followers": 124,
      "following": 124,
      "id": "6717855",
      "type": "facebook",
      "typeId": "facebook",
      "typeName": "Facebook",
      "url": "https://www.facebook.com/rdegges",
      "username": "rdegges"
    }
  ]
}

As you can see, enrich was able to grab a LOT of information about me, based solely on my email address!

Enriched Data

By default, enrich will attempt to grab several data points for each user you have:

  • photos
  • contactInfo
  • organizations
  • demographics
  • socialProfiles

Depending on the what’s publicly available, some of these sections may not be available. When I ran a test on our Stormpath employees, I was able to find a lot of information on just about every person here!

Why Enrich Your Users?

Enrich allows you to customize your user experience very easily. Let’s say I wanted to build a very simple SaaS application — using enrich I’d be able to:

  • Register a new user with only an email address and password.
  • Automatically find this user’s avatar, and use it in my interface to help give my dashboard a more personalized feel.
  • Automatically find this user’s first and last name to greet them (“Welcome back, Randall!”).
  • Integrate deographic information like age, gender, and location into my analytics.
  • Figure out what organization this user is associated with (maybe they’re the CEO of a huge company, and you should email them directly!).

Using Enrich

Using enrich is simple.

First, you’ll need to install npm, the Node.js package manager. Once npm is installed, you can then install enrich by running:

1
$ npm install -g stormpath-enrich

Next, you’ll need to have two accounts:

After you’ve created your accounts, and have your API keys, all you have to do to configure enrich is run:

1
$ enrich --configure

And you will be prompted to enter your credentials.

Once that’s done, just run:

1
$ stormpath-enrich

And your user accounts will be automatically enriched!

NOTE: For best results, I recommend running enrich on a cron job periodically, this way you’ll continuously update your user accounts with the latest available information.

Thoughts, Feedback?

If you’ve got any thoughts or feedback, I’d love to hear it! Please leave a comment below, or drop me a line.

Stormpath Node.js Update: All New Support for Social Login and Custom Data

$
0
0

New Stormpath Node.js SDK

Today, I’m ecstatic to announce the 0.2.0 release of our Node.js SDK, complete with updated docs and a host of fixes and new functionality. When we first released the 0.1 version in March, the fast adoption surprised us. Since then, we’ve been working hard to incorporate all your feedback (thanks!), fill out the features, and make it awesome for Node users. In this article, I’ll walk through the major improvements we’ve made in this release. Please check out the new version and please share your feedback!

Social Login

You can now use the Node.js SDK to login your users with Facebook or Google. Stormpath Social Login retrieves user profiles from social networks and converts them to full Stormpath accounts, complete with functionality like passwords for your app and custom user profile data. Take a look at our Social Integrations guide for more information on how it works.

Full Custom Data Support

We finished implementing custom data support in Node.js. It’s the easiest way to add ad-hoc data to your Accounts and Groups. No database work and it’s super simple to implement:

account.customData.subscriptionLevel = 'premium';
account.customData.save(function(err, customData){
  // success!
});

Account Store Mappings

This release gives Node.js devs more sophisticated control over setting, querying, and updating the mappings between your account stores in Stormpath and your application.

Building a multi-tenant app? Account Store Mappings are a killer time-saver.

Updated Caching Support

We’ve expanded caching implementations to include network-accessible stores like Redis and Memcached. Caching improves performance by reducing round trip calls to Stormpath.

Caching is incredibly easy to implement for Node apps backed by Stormpath – without code changes. Simply provide an additional parameter when you create a Stormpath Client instance.

Iterator Methods on Collection Resources

Collection resources in Stormpath are pre-defined “parent” resources that contain “child” instance resources. This release brings new methods to make it easy to iterate over those collection resources. For instance, it’s now simple to produce an array of your Stormpath Application names:

function pluckAppName(application, cb){
  cb(null, application.name);
}

applications.map(pluckAppName, function(err, results){
  // results is now an array of names for each application
});

Updated Docs

Last but not least, we’ve massively updated the Node.js API docs. There are all-new sections, clearer explanations, revamped code samples, and more detail all around.

Stay tuned for two more major features coming soon to Stormpath and the Node SDK! And as always, leave us your feedback on today’s release in the comments, on support, or @goStormpath.

Node.js Reading List

$
0
0

Book Sketch

Over the past couple of months, I’ve been getting more involved in the Node.js community: writing more Node code, building apps, and getting familiar with the ecosystem.

As a developer, it’s really interesting getting familiar with a new language / framework / community. There’s a lot to learn: the language, ecosystem, tools, best practices and idiosyncrasies.

When it comes to mastering these, there’s really no substitute for experience and time. And, while I’m not exactly “at home” in Node yet, I’ve been reading through various resources trying to educate myself more, and reach that nirvana-esque state of development where everything comes naturally.

As I’ve been going along I’ve been putting a small reading list together, which I thought I’d share. Here’s my Node reading list!

Books

I read a lot of tech books. While some people learn best through hearing or trying something, I tend to learn best through reading.

With that in mind, here are my favorite Node books.

First up is Douglas Crockford’s classic book, Javascript: The Good Parts. It’s widely considered to be the best text on modern Javascript, as it covers exclusively the parts of the language that you should be actively using.

Javascript is a big language, and it has a lot of quirks. This book teaches you in a very clear and concise way exactly what language features you should be using, and why.

I’ve read this book several times over the past few years, but after getting more involved with Node I’ve come to realize how critical it is for any Javascript developer.

When you’re spending a lot of time writing server-side Javascript, you’ll be a lot better off armed with the knowledge from this book. There are a lot of language “gotchas” which make knowing the language very well a necessity for good Node development.

The next book I’d recommend to new Node developers is The Node Beginner Book. It’s a very simple and straightforward introduction to Node for developers who’ve primarily used Javascript on the front end, and never really messed with it as a backend language before.

What I really enjoyed about this book is it’s tone: it’s leisurely, enjoyable, and incredibly useful for new Node developers. It covers all Node basics, and gives you a good feel for basic usage. It’s definitely worth buying and reading over a weekend.

Sites

Another great way to get a good “feel” for a new language / framework is to keep up with popular sites.

How to Node is a popular Node community blog which publishes articles on a variety of Node related topics:

  • How to do something in Node.
  • Common gotchas.
  • What something is.
  • Why something works the way it does.
  • Introduction to a specific tool / concept.

I’ve found many of the articles extremely simple and useful — you might too!

NPM Awesome is a really great blog written by Alex Gorbatchev in which he reviews various npm modules.

I find NPM Awesome to be a great resource for learning what new Node modules are coming out, what’s good about them, what’s bad about them, and more generally: what stuff I should look into using.

It’s quickly become one of my favorite resources for discovering cool new stuff on npm and finding ways to sneak it into my projects >:)

Mailing Lists

There’s really only one mailing list you should subscribe to, and that’s node weekly. It’s a weekly email list that does an amazing job of finding relevant npm modules, node articles, and generally interesting node information.

It’s 100% worth signing up for, no question.

[Disclaimer: Stormpath has sponsored node weekly in the past. Because it is awesome.]

Podcasts

I usually do a lot of driving in the Bay Area (going from event-to-event), and have gotten in the habit of listening to a few podcasts to make the commuting more bearable.

nodeup is the only real Node podcast I’m familiar with — but it’s pretty great. The show covers:

  • Node core development.
  • Node modules.
  • Chatting with various Node developers.
  • Thoughts on various programming techniques / strategies.

Overall, I’d say it’s a really great podcast (particularly if you’re interested in learning more about Node tools and practices). The only downside (to me) is that episodes are roughly an hour each, which is longer than I want to be in the car.

It’s very casual, however, and easy to listen to.

Exercises

Although I don’t normally do exercises, I’ve spent some time playing around with various hands-on Node resources.

node school is without a doubt, my favorite hands-on Node resource. It’s an interactive command-line-driven lesson / tutorial in which you’re given some instruction, then sent off to write your own Node programs which it’ll then verify for correctness.

Not only are the exercises incredibly fun, but also very well written and sufficiently challenging.

If you’re going to give node school a try, I suggest you block off several hours of time to sit down and go through the exercises without any distraction.

Wrap Up

I hope this list has been of some help — if you have any other recommendations, please leave a comment below!

And if you’re interested in easy user management for your Node app, please checkout Stormpath or jump right in with our Node.js 7-Minute Tutorial .

Happy Hacking! -Randall

Making Express.js Authentication Fun Again

$
0
0

Express and Node

It’s no secret that if you’re building an Express web app, adding in user authentication is quite difficult. If you google “Express Authentication”, you’ll be directed to one of two tools:

While both Passport and everyauth are really great tools, as a relatively new Node developer, I had a difficult time figuring out how to actually use them in a real application.

I honestly don’t want to setup / configure my own session management stuff, or worry about creating my own login / registration views securely.

After a lot of discussion internally at Stormpath, we decided it would be awesome to build a really simple, powerful, and elegant authentication system for Express.

Which brings me to…

express-stormpath

For the past week, I’ve been working on building an authentication library that would abstract away all the details, and make adding user authentication to Express apps drop-dead easy.

With that said, I’m really happy to introduce express-stormpath! Visit the official docs here: http://docs.stormpath.com/nodejs/express/

NOTE: If you aren’t a Stormpath user already, Stormpath is an API service that makes managing users simple. It’s completely free for small apps.

express-stormpath allows you to painlessly add complete user authentication (including registration, login, and logout) into your Express apps in just a few lines of code.

First, install the library (and express, too!):

1
2
$ npm install express
$ npm install express-stormpath

Next, open up your editor and create an app.js file:

1
2
3
4
5
6
7
8
9
10
11
12
13
var express = require('express');
var stormpath = require('express-stormpath');

var app = express();

app.use(stormpath.init(app, {
  apiKeyId: 'xxx',
  apiKeySecret: 'xxx',
  application: 'xxx',
  secretKey: 'xxx',
}));

app.listen(3000);

The secretKey must be a long random string (used to secure sessions), while the other fields contain your Stormpath account settings. For more information on setting up a Stormpath account, you can check out the Setup section of our docs.

The above code sample is a fully functional Express app which has three pre-configured routes:

A registration route (/register), which looks like this:

Stormpath Express Registration

A login route (/login), which looks like this:

Stormpath Express Login

And a logout route (/logout) which logs users out of their account.

Out of the box you get user registration, login, and logout!

Just to demonstrate how easy it actually is, here’s a 90 second screencast I made in which I’ll create a brand new Express app from scratch with full user registration and login!

Customization

With express-stormpath, you can also customize essentially every part of the library very easily.

Let’s say, for instance, that after a user creates a new account or logs in, you’d like to redirect them to a dashboard page (/dashboard), you can easily do this by specifying the redirectUrl setting when initializing the middleware, like so:

1
2
3
app.use(stormpath.init(app, {
  redirectUrl: '/dashboard',
}));

What if you want to change the login and registration urls? It’s also a single setting:

1
2
3
4
app.use(stormpath.init(app, {
  loginUrl: '/user/login',
  registrationUrl: '/user/register',
}));

Or, what if you want to change the view code to add in your own styles / etc? It’s incredibly simple! I wrote a guide which explains how to do it in explicit detail.

You can easily change / remove / modify any part of the express-stormpath library by modifying middleware settings — it really is that simple.

Exploring express-stormpath

If you’d like to give express-stormpath a try, here are some code samples which illustrate how to use the library in a bit more depth.

Let’s say you want to write a route which requires a user to be logged in. You can do this easily by using the stormpath.loginRequired tooling:

1
2
3
app.get('/dashboard', stormpath.loginRequired, function(req, res) {
  res.send('If you can see this page, you must be logged into your account!');
});

When a user visits /dashboard, we’ll automatically check to ensure the user is logged in before allowing them to continue. If the user isn’t logged in, they’ll be redirected to /login?next=%2Fdashboard, so once they log into their account, they’ll be immediately sent back to the dashboard page!

Furthermore, you can also require a user to be a member of one or more groups in order to access a route. For instance, if you’d like to build an admin panel that’s exclusively available to users in the ‘admins’ group, you could do:

1
2
3
app.get('/admin', stormpath.groupsRequired(['admins']), function(req, res) {
  res.send('You are an admin!');
});

To assert that a user is a member of multiple groups, you can simply list multiple groups, ex:

1
2
3
app.get('/admin', stormpath.groupsRequired(['admins, developers']), function(req, res) {
  res.send('You are an admin and developer!');
});

You can also assert that a user is a member of one or more groups by passing an optional flag:

1
2
3
app.get('/hmm', stormpath.groupsRequired(['admins, developers', 'dudes'], false), function(req, res) {
  res.send('You are either an admin, developer, dude, or some combination of them all!');
});

In your route code, you can also access the current user object by calling res.locals.user like so:

1
2
3
app.get('/dashboard', stormpath.loginRequired, function(req, res) {
  res.send('Welcome back: ' + res.locals.user.email);
});

If you’re inside of a template, you can access the user object directly, here’s an example in Jade:

1
2
3
html
  body
    p Hi #{user.email}

Making Authentication Easier

Thanks for reading this far!

If you’d like to get started with express-stormpath, now would be a great time to check out the official documentation!

I’m super excited to launch the very first release of express-stormpath, and plan on adding lots of new features to it in the coming weeks:

  • Social login support.
  • API authentication support.
  • Password reset support.
  • etc.

If any of you give express-stormpath a try, I’d love to hear from you, please drop me a line: randall@stormpath.com — or tweet us @gostormpath!

Hosted Login for Modern Web Apps

$
0
0

Hosted Login from Stormpath

It’s no big secret: if you’re not using SaaS products to build your next great app, you’re wasting a lot of time.

Seasoned web developers have learned to solve common (i.e. annoying) problems with packaged solutions. If you’re really badass, your latest app is a symphony of amazing services, not a monolithic codebase that suffers from Not Invented Here.

But I’m gonna put money on this: you’re still building your login and registration forms from scratch and maintaining your own user database.

Why do we build login from scratch?

I have a few hypotheses on this, but one always seems to be true: user systems are the first thing we do after we master the Todo demo app. It’s fun, it’s a feature and we feel like we’ve accomplished something. Eventually we learn that there are a lot of things you can get wrong:

  • Storing passwords in a database, in plaintext
  • Giving users a cookie session that never expires
  • Building a crappy (or nonexistent!) password reset flow, to the ire of the support team
  • Storing the entire user object in application memory in order to improve page times

I could go on, but you already know. We commit these sins in the spirit of Ship It!.

Sometimes we use a framework like Rails, Express or Django and avoid most of these pitfalls by using their configurable user components. But we’re trying to get to App Nirvana, we want fewer concrete dependencies, less configuration, fewer resources to provision.

Login as a Service

What if you could send your user to a magical place, where they prove their identity and return to you authenticated?

Announcing Hosted Login – our latest offering from Stormpath!

With Hosted Login you simply redirect the user to a Stormpath-hosted login page, powered by our ID Site service. We handle all the authentication and send users back to your application with an Identity Assertion. This assertion contains all the information you need to get on with your business logic.

And the best part? Very minimal contact with your backend application. In fact, just two lines of code (using our SDKs):

  • One to create the URL which takes the user to the hosted login screen
  • One that parses the identity assertion when they return to your application

And with that.. your entire user system is now completely service-oriented. No more framework mashing, no more resource provisioning. Oh, did we mention that’s beautiful as well? That’s right: if you don’t want to do any frontend work either, you can just use our default screens:

Screenshot

What problems does it solve?

Hosted Login solves a lot of the problems that are sacrificed in the name of Ship It, plus a few you may not have thought of:

  • Security best practices (HTTPS for all components, enterprise grade security on our backend)
  • Complete flows for registration, verification, login, and password reset
  • Social login for Google and Facebook
  • No provisioning or securing your database

Customization

While we provide default screens for hosted login, you can fully customize your user experience. Just create a Github repository for your ID Site assets and give us the Github URL! We’ll import the files into our CDN for fast access and serve your custom login pages instead of our default.

To customize your hosted login pages, you’ll want to use Stormpath.js, a small library that I’ve written just for this purpose. It gives you easy access to the API for ID Site and at ~5k minified it won’t break the bank.

For more information on this feature please refer to our in-depth document: Using Stormpath’s ID Site to Host your User Management UI

We’d love to know how you find Hosted Login! Feel free to tweet us at @gostormpath or contact me directly via robert@stormpath.com

The Pain of Password Reset in Express

$
0
0

Node.js and Stormpath Rule

I’ve built many Express applications recently, and it’s reminded me of the pains of building password reset functionality since there are many Express tools for handling it. Building password reset is a drag for most developers, every application needs it, and getting it wrong can have a major impact on your application. This post is an effort to reduce the pain of building password reset for other node developers by first describing the systems you’re going to need and then offering a recommended workflow for password reset.

Systems Needed for Password Reset

For starters, Express requires you to build out a proper user system. Your first reaction would be to use Passport, but you’ll quickly find that Passport does not store accounts — you still have to do that yourself. Passport is good for adding authentication strategies (like Facebook vs username/password) if you already have a user management system in place. So, get coding.

With a user system in place, you start to build password reset. First, you need several additional routes for the pages in the password reset flow, and to include input validation and CSRF protection for your forms.

Then you’re going to need an email component to send the user their secure URLs and tokens. If you don’t already have email built into your application, you might want to use an email service like Sendgrid or Mailgun. Next, email templates for each part of the reset process.

Almost there. You now need to get those reset tokens working. First, you need the logic to create unique tokens for each reset attempt and expire them within a certain time frame and on first use. That will include an additional table to store the tokens and their expiration metadata. Then build the logic in your code to authenticate and verify those tokens before a reset can be completed.

All in all, it’s dozens of hours of work (possibly more) you would probably rather spend on core application business logic.

And while it’s not rocket science, hand-rolled password reset workflows can be error prone and those errors directly translate to vulnerabilities in your application — user accounts can be hijacked. Since password reset is not core to most applications, these types of vulnerabilities are often not discovered until they actually get exploited.

So, let’s talk about how to build it the right way.

Password Reset Workflows – The Right Way

Over the years I’ve used numerous password reset systems, and there is really only one good way to handle password reset functionality in your web applications.

Here’s how we recommend you do it:

  1. On your login page, there should be an obvious “Forgot your password?” link. Otherwise you’ll confuse users and increase either support tickets or abandonment.

  2. When a user gets to your password reset page, and enter their email address. You may want to ask for a second factor to identify the user at this stage or a later stage.

  3. After the user has entered their email address, send them an email with a link to the password reset page on your site. This link should contain a unique password reset token that expires after a certain amount of time and one first use. If your token isn’t unique, doesn’t expire — you’ve got a very real vulnerability on your hands.

  4. After you’ve sent the user an email, give them a message telling them what to do! Tell the user you sent them an email, and tell them to check their inbox. If you immediately redirect them somewhere else, they’ll be confused!

  5. After the user clicks the link in their email, they should be brought to a page on your site that prompts them to enter a new password. Ensure you make the user enter their new password twice so they don’t forget what they just typed. Make sure you validate their token before proceeding! If the token isn’t valid, you should display an error message and instructions on how to proceed.

  6. Once the user has reset their password, give them a confirmation message to eliminate confusion. “Your password has been reset” is typically good enough.

  7. Lastly, ensure you send the user an email once their password has been changed letting them know what happened. This will ensure the user knows what they did, and is a great auditing tool in the future. It’s also an easy alert in the event the user didn’t initiate the reset themselves.

If any of these steps is missing, you may confuse your users and open yourself up to security vulnerabilities.

Take the token, for instance. If this token isn’t validated — that means anyone can reset one of your user’s passwords — and that’ isn’t a good thing.

If your tokens don’t expire after a short period of time (usually 24 hours), then you’ve got an issue. What if this user’s email gets compromised in the near future? What if the token can be easily guessed?

And lastly, if your token isn’t actually unique — you’ll be in for some embarrassing work meetings. For instance, I’ve noticed that many sites set the password reset token to a guessable number! For instance, if you use an incrementing integer value (1, 2, 3, …), it’s quite easy for attackers to guess at these numbers until they find a valid one.

NOTE: It’s also worth mentioning explicitly that you should NEVER send your users an email containing their password. This means that you’re more than likely storing your passwords in plain text (an awful idea), and exposes users to additional risk: what happens if someone looks over their shoulder as they read their email and sees their password? That doesn’t just happen in movies.

Stormpath’s Password Reset Workflow

The Stormpath API has always handle password reset for developers so you don’t have to go through this pain. And we have a great ExpressJS integration. And I just added password reset to it, so you don’t have to!

If you aren’t familiar with Stormpath, we’re API service you can use to deploy complete user management in your application — login, user profiles, password reset, Facebook integration, etc. And it’s all under the hood, your end-users never know we exist.

Our popular express-stormpath library fully supports password reset. You can instantly add password reset into your ExpressJS web applications with a single line of configuration information:

app.use(stormpath.init(app, {
  enableForgotPassword: true,
  ...
}));

After enabling the password reset functionality with the Stormpath middleware, a magical link will appear on your login page that allows users to start the password reset process.

Below are some screenshots that demonstrate what users will see with the baked-in views (100% customizable, of course):

If you’d like to check it out, give some feedback, or point out ways to improve the new Express integration, please take a look at the new password reset documentation and let me know what you think.

If any of you give express-stormpath a try, I’d love to hear from you, please drop me a line: randall@stormpath.com — or tweet us @gostormpath!

SSO Vs. Centralized Authentication

$
0
0

Single Sign-On (SSO) has become an over-loaded term for many developers. It’s used, sometimes inaccurately, to refer to any tool that simplifies login for the end-user. But SSO has a very specific technical definition, and the confusion increasingly makes it difficult for developers to find the right tool for the job.

In most cases, what a developer is really looking for is one (or a combination) of three different tools: Centralized Authentication, Social Login (i.e. Facebook Login), or actual Single Sign-on.

Social Login is pretty well defined at this point, and most developers know what it is— the user logs into your application by clicking a facebook button and using their Facebook credentials (usually through a custom Facebook OAuth flow). You can learn all about it in our Facebook Login Guide.

Less clear and often more misunderstood is the difference between Single Sign-On and Centralized Authentication. At Stormpath we see this confusion often and wrote this article to help developers find the right solution for their application.

Single Sign-On

With single sign-on (SSO), users are authenticated only once, regardless of how many other applications they attempt to access after the initial login. In general, this is achieved when the SSO Identity Provider (IDP) sends the target applications an assertion that the user has been authenticated and should be trusted by that application.

For example, say a user logs on to Application 1, then decides to access Application 2. Typically, Application 2 would require another username and password for authentication. But in an SSO environment, Application 2 simply determines whether it can authenticate the user based on information the SSO IDP provides. The assertions are typically based on a common protocol like SAML, OpenID Connect, or JWT.

SSO solves two major problems for users:

  1. They don’t need to enter authentication information multiple times
  2. …or remember multiple sets of login credentials

It also requires a user repository in order to authenticate a user for the first time. Typical user repositories include Active Directory, LDAP, a custom database, or Stormpath. In turn, these same repositories are often centralized authentication and user management systems.

On its own, SSO is a poor solution for sharing user data across applications, as SSO generally expects the application (or “Service Provider” in SSO speak) to maintain its own user management system. More specifically, when an SSO provider sends an authentication assertion to an application, it still needs to create or look up the user in the app’s own local repository. Even though the application can trust that the user is authenticated.

Centralized Authentication

With centralized authentication, the authentication process is different. Once a user has logged into Application 1, logging into App 2 doesn’t feel automatic. Even though the required credentials are identical, the user would still need to enter her authentication information again.

Like SSO, Centralized authentication solves two problems, but the problems are different:

  1. Users don’t need to remember multiple sets of authentication credentials
  2. The applications they are logging into can share user data.

Typically, centralized authentication solutions completely offload user management from an application. They provide powerful APIs or query languages to connect the user system to one or many applications. Moreover, centralized authentication is often the first step toward a true SSO environment.

SSO vs Centralized Authentication? Why not both?!

So, should you use SSO or Centralized Authentication in your application? Of course the answer is: it depends.

  • If you’re trying to create a single user repository that all your applications can share, you will want a centralized authentication and user management system.

  • If, on the other hand, you have a variety of applications with their own built-in user data and management, but you want to create a seamless user experience, you’ll be best served by SSO (if those apps support it).

However, SSO and Centralized Authentication are not direct competitors. In fact, many developers implement both to give customers a seamless user experience across applications or web properties. At the same time, an SSO/Centralized Authentication combo allows development teams to share user infrastructure across applications, so they aren’t reinventing the identity system with each new application.

Stormpath combines both SSO and Centralized Authentication in one clean and elegant user management system. With an elegant API, powerful SDKs, and easy to use framework integrations, your applications have full access to user and group data .

In addition, we now offer SSO across your custom applications with little to no coding on your end through our new ID Site feature, so you can offer customers a seamless user experience.


Manage your API Keys with Java, Jersey, and Stormpath

$
0
0

If you are a Java developer, then you are undoubtedly familiar with frameworks such as Spring, Play!, and Struts. While all three provide everything a web developer wants, I decided to write a RESTful web application using the Jersey framework. This sample app uses Java + Jersey on the back-end and Angular JS on the front-end.

Jersey annotation service makes it easy to do routing, injection, and other functions important to a RESTful web application. My goal was to demonstrate the use of the Stormpath Java SDK for user management and the protection of a REST endpoint using API Keys and Oauth Tokens, all while relying on Jersey.

You can check out the Stormpath Jersey sample app in github, and follow along here for the implementation details and concepts I found most important while building this application. I will explain Stormpath SDK calls, Jersey annotations, and the general flow of the application, so it the codebase is easy to decipher.

Let’s code!

Login

Stormpath provides username/password authentication in three lines of Java SDK method calls. That makes it very simple to launch a basic login form, securely.

As soon as a user enters their credentials and clicks the “Sign In” button, an AJAX request is made to the /login endpoint. Let’s take a look at the server side login code:

@Path("/login")
public class Login {

@Context
private HttpServletResponse servletResponse;

@POST
@Consumes(MediaType.APPLICATION_JSON)
public void getDashboard(UserCredentials userCredentials)
  throws Exception {

  Application application = StormpathUtils.myClient.getResource(
    StormpathUtils.applicationHref, Application.class);

  AuthenticationRequest request = new UsernamePasswordRequest(
    userCredentials.getUsername(), userCredentials.getPassword());

  Account authenticated;

  //Try to authenticate the account
  try {
   authenticated = application.authenticateAccount(request).getAccount();

  } catch (ResourceException e) {
    System.out.println("Failed to authenticate user");
    servletResponse.sendError(401);
    return;
  }

  Cookie myCookie = new Cookie("accountHref", authenticated.getHref());
  myCookie.setMaxAge(60 * 60);
  myCookie.setPath("/");
  myCookie.setHttpOnly(true);
  servletResponse.addCookie(myCookie);
  }
}

Here we see three examples of Jersey’s annotation feature. The @Path annotation acts as our router. The @Context annotation injects the HTTP Request object into our class. Finally, the @POST specifies the CRUD operation.

User authentication is done by first creating an Application object, creating an AuthenticationRequest object, and finally calling application.authenticationAccount(request) to ask Stormpath to authenticate this account.

Create Account

Creating an account is just as simple as logging in to the service:

@Path("/makeStormpathAccount")
public class StormpathAccount {

@POST
public void createAccount(UserAccount userAccount) throws Exception {

  Application application = StormpathUtils.myClient.getResource(
    StormpathUtils.applicationHref, Application.class);
  Account account = StormpathUtils.myClient.instantiate(Account.class);

  //Set account info and create the account
  account.setGivenName(userAccount.getFirstName());
  account.setSurname(userAccount.getLastName());
  account.setUsername(userAccount.getUserName());
  account.setEmail(userAccount.getEmail());
  account.setPassword(userAccount.getPassword());

  application.createAccount(account);
  }
}

All we had to do here, was create an Application and an Account, set the Account attributes, and call createAccount.

Generating an API Key ID/Secret

Once a user logs in, they will be given API Key credentials. In this application, generation of the Keys is a simple AJAX call to /getApiKey:

@Path("/getApiKey")
public class Keys {

@Context
private HttpServletRequest servletRequest;

@Context
private HttpServletResponse servletResponse;

@GET
@Produces(MediaType.APPLICATION_JSON)
public Map getApiKey(@CookieParam("accountHref") String accountHref) throws Exception {

  Account account = StormpathUtils.myClient.getResource(accountHref,
    Account.class);

  ApiKeyList apiKeyList = account.getApiKeys();

  boolean hasApiKey = false;
  String apiKeyId = "";
  String apiSecret = "";

  //If account already has an API Key
  for(Iterator<ApiKey> iter = apiKeyList.iterator(); iter.hasNext();) {
     hasApiKey = true;
     ApiKey element = iter.next();
     apiKeyId = element.getId();
     apiSecret = element.getSecret();
  }

  //If account doesn't have an API Key, generate one
  if(hasApiKey == false) {
     ApiKey newApiKey = account.createApiKey();
     apiKeyId = newApiKey.getId();
     apiSecret = newApiKey.getSecret();
  }

  //Get the username of the account
  String username = account.getUsername();

  //Make a JSON object with the key and secret to send back to the client
  Map<String, String> response = new HashMap<>();

  response.put("api_key", apiKeyId);
  response.put("api_secret", apiSecret);
  response.put("username", username);

  return response;
}
}

We use Jersey’s @CookieParam annotation to grab the account Href from the Cookie that was created at login. We create an account, and an ApiKeyList object. We then check if this account already has an API Key. If so, our job is to simply request it from Stormpath; if not, we tell Stormpath to make a new one for this account and return this back to the client. By Base64 encoding the API Key:Secret pair, a developer can now target our endpoint using Basic authentication:

Using a Jersey Filter

A cool feature of the Jersey framework is its Request filter. By implementing ContainerRequestFilter we can intercept an HTTP request even before it gets to our endpoint. To demonstrate, I added an additional level of security around API Key generation. Before a user is allowed to target the /getApiKey endpoint they must pass through the Jersey request filter, which will check if the client is actually logged in (a.k.a has a valid session in the form of a cookie).

@Provider
public class JerseyFilter implements ContainerRequestFilter {

@Context
private HttpServletResponse servletResponse;

@Override
public void filter(ContainerRequestContext requestContext) throws
  IOException {

  URI myURI =  requestContext.getUriInfo().getAbsolutePath();
  String myPath = myURI.getPath();

  if(myPath.equals("/rest/getApiKey")) {
    Iterator it = requestContext.getCookies().entrySet().iterator();
    String accountHref = "";

    while(it.hasNext()) {
      Map.Entry pairs = (Map.Entry)it.next();

      if(pairs.getKey().equals("accountHref")) {
       String hrefCookie = pairs.getValue().toString();
       accountHref =
        hrefCookie.substring(hrefCookie.indexOf("https://"));
      }
        }
    if(!accountHref.equals("")) {
      //Cookie exists, continue.
      return;
    }
    else {
      System.out.println("Not logged in");
      servletResponse.sendError(403);
    }
  }
}
}

If a client is trying to get an API Key without being logged in, they will get a 403 before even reaching the actual endpoint.

Exchanging your API Keys for an Oauth Token

Want even more security? How about trading your API Key for an Oauth Token? Using Oauth also brings the functionality of scope, which we can use to allow users to get weather from specified cities.

Let’s take a look at the code:

@Path("/oauthToken")
public class OauthToken {

@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String getToken(@Context HttpHeaders httpHeaders,
                       @Context HttpServletRequest myRequest,
                       @Context final HttpServletResponse servletResponse,
                       @FormParam("grant_type") String grantType,
                       @FormParam("scope") String scope) throws Exception {

/*Jersey's request.getParameter() always returns null, so we have to
    reconstruct the entire request ourselves in order to keep data
See: https://java.net/jira/browse/JERSEY-766
*/

  Map<String, String[]> headers = new HashMap<String, String[]>();

  for(String httpHeaderName : httpHeaders.getRequestHeaders().keySet()) {
    //newBuilder.header(String, String[]);
    List<String> values = httpHeaders.getRequestHeader(httpHeaderName);
    String[] valueArray = new String[values.size()];
    httpHeaders.getRequestHeader(httpHeaderName).toArray(valueArray);
    headers.put(httpHeaderName, valueArray);
  }

  Map<String, String[]> body = new HashMap<String, String[]>();
  String[] grantTypeArray = {grantType};
  String[] scopeArray = {scope};

  body.put("grant_type", grantTypeArray );
  body.put("scope", scopeArray);

  HttpRequest request = HttpRequests.method(HttpMethod.POST).headers(
    headers).parameters(body).build();

  Application application = StormpathUtils.myClient.getResource(
    StormpathUtils.applicationHref, Application.class);

  //Build a scope factory
  ScopeFactory scopeFactory = new ScopeFactory(){
    public Set createScope(AuthenticationResult result,
      Set requestedScopes) {

      //Initialize an empty set, and get the account
      HashSet returnedScopes = new HashSet();
      Account account = result.getAccount();

        /***
        In this simple web application, the scopes that were sent in the
        body of the request are exactly the ones we want to return. If
        however we were building something more complex, and only wanted
        to allow a scope to be added if it was verified on the server
        side, then we would do something as shown in this for loop. The
        'allowScopeForAccount()' method would contain the logic which
        would check if the scope is truly allowed for the given account.

        for(String scope: requestedScopes){
                if(allowScopeForAccount(account, scope)){
                    returnedScopes.add(scope);
                }
            }
        ***/

      return requestedScopes;
    }
  };

  AccessTokenResult oauthResult = application.authenticateOauthRequest(
    request).using(scopeFactory).execute();

  TokenResponse tokenResponse = oauthResult.getTokenResponse();

  String json = tokenResponse.toJson();

  return json;
}
}

Notice the 10 lines of code right after the getToken() declaration. This is a workaround for Jersey’s lack of providing us with a complete request object. Calling request.getParamter() or request.getParameterMap() will always return null, and since creating an AccessTokenResult object requires the Request object with the body still intact, we must recreate the entire request ourselves.

Finally: Securing your REST endpoint

Ahh, the moment we’ve all been waiting for. Now that we have given our users the ability to target this weather endpoint using Basic and Oauth authentication, it is up to us to figure out which protocol they choose to use.

@Path("/api/weather/{city}")
public class WeatherApi {

@Context
private HttpServletRequest servletRequest;
@Context
private HttpServletResponse servletResponse;

private String weatherResult;

@GET
@Produces(MediaType.APPLICATION_JSON)
public String getWeatherApi(@PathParam("city") final String myCity)
  throws Exception {

  Application application = StormpathUtils.myClient.getResource(
    StormpathUtils.applicationHref, Application.class);

  System.out.println(servletRequest.getHeader("Authorization"));

  //Make sure this use is allowed to target is endpoint
  try {
    ApiAuthenticationResult authenticationResult =
      application.authenticateApiRequest(servletRequest);

    authenticationResult.accept(new AuthenticationResultVisitorAdapter() {

      public void visit(ApiAuthenticationResult result) {
        System.out.println("Basic request");

        URL weatherURL = getURL(myCity);

        //Parse weather data into our POJO
        ObjectMapper mapper = new ObjectMapper();

        mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        City city = null;

        try {
           InputStream in = weatherURL.openStream();
           city = mapper.readValue(in, City.class);

        } catch (IOException e) {
            e.printStackTrace();
        }

        weatherResult = city.toString() + " °F";
      }

      public void visit(OauthAuthenticationResult result) {

        //Check scopes
        if(result.getScope().contains("London") && myCity.equals("London")){
          weatherResult = getWeather(myCity) + " °F";;
        }
        else if(result.getScope().contains("Berlin") && myCity.equals("Berlin")){
          weatherResult = getWeather(myCity) + " °F";;
        }
        else if(result.getScope().contains("SanMateo") && myCity.equals("San Mateo")){
          weatherResult = getWeather(myCity) + " °F";;
        }
        else if(result.getScope().contains("SanFrancisco") && myCity.equals("San Francisco")){
          weatherResult = getWeather(myCity) + " °F";;
        }
        else {
          try {
            servletResponse.sendError(403);
          } catch (IOException e) {
            /* To change body of catch statement use File | Settings | File Templates.*/
            e.printStackTrace();
          }
        }
      }
    });

  return weatherResult;

} catch (ResourceException e) {
  System.out.println(e.getMessage());
  servletResponse.sendError(403);
  return "Cannot authenticate user.";
}
}

To do this we use a visitor. We create a visitor for each type of authentication protocol that we expect our clients to use (in our case Basic and Oauth). Based on the type of the ApiAuthenticationResult object, the appropriate visitor will be targeted. Notice how inside the OauthAuthenticationResult visitor, we check the scope of the Oauth token that we received, and appropriately give/forbid access to the requested cities.

When we generated our Oauth token in the sceenshot above, we gave access to view weather in London, Berlin, and San Francisco. Thus we can view London’s weather using Oauth:

However, since San Mateo was not included in the scope of the Oauth token, we cannot see its weather:

Conclusion

Jersey is yet another Java framework that seamlessly integrates with the Stormpath SDK to offer user management, API Key management, Oauth, and more. If you’d like to see more code and even run this application yourself please visit: https://github.com/rkazarin/sample-jersey-webapp

Build a Node API Client – Part 1: REST Principles

$
0
0

Build a Node API Client – Part 1: REST Principles FTW

If you want developers to love your API, focus the bulk of your efforts on designing a beautiful one. If you want to boost adoption of your API, consider a tool to make life easier on your users: client libraries. Specifically, Node.js client libraries.

This series will cover our playbook for building a stable, useful Node.js client in detail, in three parts:

Part 1: Need-to-know RESTful Concepts

Part 2: REST client design in Node.js

Part 3: Functionality

If you would like to learn general REST+JSON API design best practices, check out this video. In this article series, we are going to focus exclusively on client-side concepts.

Lastly, keep in mind that while these articles use Node.js, the same concepts apply to any other language client with only syntax differences.

OK. Let’s begin with the RESTful concepts that make for a killer client. After all, if we don’t nail these down, no amount of JavaScript will save us later.

HATEOAS

HATEOAS, usually pronounced ‘Haiti-ohs’, is an acronym for “Hypermedia As The Engine of Application State”. Aside from being an unfortunate acronym, HATEOAS dictates that REST API clients should not know anything about that REST API: a REST client should issue an initial request and everything it needs from that point on can be discovered from the initial response.

HATEOAS is still considered the ideal target for REST API design, but at times, HATEOAS will present a challenge to our REST client design efforts. Think of it this way:

  1. Your end-users will want to use your shiny new client to do the things they know are possible in your API. They will want to invoke known / defined behavior.
  2. You will want to provide them convenience functions to make it super easy for them to interact with your API – things that may not be as easy or possible with standard HTTP requests.
  3. Reconciling 1 and 2 with HATEOAS simply won’t always possible.

Our philosophy takes the pragmatic view: while HATEOS is ideal for automated software agents (like browsers), it is often not as nice for humans that want library functions that address specific needs, so we will diverge from HATEOAS when it makes sense.

REST Resources

Resources transferred between the client and the API server represent things (nouns), not behaviors (verbs). Stormpath is a User Management API, so for us, resources are records like user accounts, groups, and applications.

No matter what your API’s resources are, each resource should always have it’s own canonical URL. This globally unique HREF will identify each resource and only that resource. This point really can’t be stressed enough; canonical URLs are the backbone of RESTful architecture.

In addition to having a canonical URL, resources should be coarse-grained. In practice, this means we return all resource properties in their entirety in the REST payload instead of as partial chunks of data. Assumptions about who will use the resource and how they will use it only make it more difficult to expand your use cases in the future. Besides, coarse-grained resources translate to fewer overall endpoints!

Collection Resources

Collection resources are first-class citizens with their own first-class properties. These properties contain data that in turn describe the collection itself, such as limit and offset.

Collection resources should have a canonical URL and follow a plural naming convention, like /applications (and not /application) to make identification easy. A collection resource always represents potentially many other resources, so plural naming conventions are the most intuitive.

Collections usually support create requests as well as query requests, for example, ‘find all children resources that match criteria X’.

Instance Resources

An instance resource is usually represented as a child of some parent collection. In the example below, the URI references a particular application within the /applications collection. The implication is that if you interact with this endpoint, you interact with a single application.

/applications/8sZxUoExA30mp74

For the most part, instance resources only need to support read, update, and delete operations. While not a hard and fast rule, reserving create for collections is a common convention in REST API design, especially if you want to generate unique identifiers for each newly-created resource.

Resource Code Examples

Ok, now the fun stuff – code!

If we are to translate these REST resource concepts to working code, it would make sense to have code artifacts that represent both collection and instance resources.

Here’s an example of what it might look like to define a very general resource concept in a Node.js library:

var util = require('util');

function Resource(...) { ... }
util.inherits(Resource, Object);

someResource.href

We’re using JavaScript’s prototypical inheritance here to simulate classical Object Oriented inheritance. We’ve found this to be the easiest to understand abstraction for most developers using code libraries, so we went with this paradigm.

As you can see, The Resource ‘class’ above takes advantage of the standard Node util library to create a resource constructor function. If you want to simulate a classical OO hierarchy, util is a great way to do it.

Next, we’ll extend this general resource class to create more specific Instance and Collection resource classes.

function InstanceResource(...) {...}
util.inherits(InstanceResource, Resource);

anInstanceResource.save(function (err, saved) {
    ...
});

anInstanceResource.delete(function (err) {
    ...
});

As mentioned, you’ll notice save and delete methods on InstanceResource, but no create. The callback on save returns either an error or the successfully saved object; delete has no object to return, so only an error might be provided to the callback. Both methods are called asynchronously after the operation is complete.

So what’s the takeaway? You can save or delete individual things, but not necessarily entire collections. Which leads us to our next resource class:

function CollectionResource(...) {...}
util.inherits(CollectionResource, Resource);

aCollResource.each(function (item, callback) {
    ...
}, function onCompletion(err) {
    ...
});

aCollResource.eachSeries
aCollResource.map
aCollResource.filter
... other async.js methods ...

CollectionResource can support a number of helper functions, but the most common is each. each takes an iterator function which is invoked asynchronously for every instance in the collection.

applications.each(function(app, callback){
    console.log(app);
    callback();
}, function finished(err) {
    if (err) console.log(‘Error: ‘ + err);
});

This example uses each to simply log all the instance resources.

As a great convenience, we made the decision early on to assimilate all of async.js’ collection utility functions into all Collection resources. This allows developers to call Stormpath methods using the semantics of async.js and allows the client to delegate those methods to the corresponding async.js functions behind the scenes. Eliminating even just one package to import has proven to be really convenient, as we’ll discuss more in part 3. We’re big fans of async.js.

(Note that async.js requires you to invoke a callback method when you’re done with a given iteration step.)

That’s it for the RESTful groundwork! We have a number of other articles and videos pertaining to REST security, linking, POST vs PUT, and more on the blog if you’re interested.

Part two of this series will be all about the nitty-gritty details of coding the client. Expect sections on encapsulation, public vs. private API implementation, and our component architecture. Stay tuned!

API Management with Stormpath

Stormpath makes it easy to manage your API keys and authenticate developers to your API service. Learn more in our API Key Management Guide and try it for free!

Build a Node API Client: Encapsulation, Resources, & Architecture

$
0
0

Build a Node API Client – Part 2: Encapsulation, Resources, & Architecture... oh my!

Welcome to Part Two of our series on Node.js Client Libraries. This post serves as our guide to REST client design and architecture. Be sure to check out Part One on Need-To-Know RESTful Concepts before reading on.

API Encapsulation

Before sinking our teeth into resources and architecture, let’s talk about encapsulation. At Stormpath, we like to clearly separate the public and private portions of our API client libraries, aka ‘SDKs’ (Software Development Kit).

All private functionality is intentionally encapsulated, or hidden from the library user. This allows the project maintainers to make frequent changes like bug fixes, design and performance enhancements, all while not impacting users. This leads to a much greater level of maintainability, allowing the team to deliver better quality software, faster, to our user community. And of course, an easier-to-maintain client results in less friction during software upgrades and users stay happy.

To achieve this, your Node.js client should only expose users to the public version of your API and never the private, internal implementation. If you’re coming from a more traditional Object Oriented world, you can think of the public API as behavior interfaces. Concrete implementations of those interfaces are encapsulated in the private API. In Node.js too, functions and their inputs and output should rarely change. Otherwise you risk breaking backwards compatibility.

Encapsulation creates lot of flexibility to make changes in the underlying implementation. That being said, semantic versioning is still required to keep your users informed of how updates to the public will affect their own code. Most developers will already be familiar semantic versioning, so it’s an easy usability win.

Encapsulation In Practice

We ensure encapsulation primarily with two techniques: Node.js module.exports and the ‘underscore prefix’ convention.

module.exports

Node.js gives you the ability to expose only what you want via its module.exports capability: any object or function in a module’s module.exports object will be available to anyone that calls.

This is a big benefit to the Node.js ecosystem and helps improve encaspsulation goals better than traditional JavaScript environments.

Underscore Names

Additionally we use the ‘underscore prefix’ convention for objects or functions that are considered private by the development team but still accessible at runtime because of JavaScript’s weak encapsulation behavior. That is, any object or function that starts with the underscore _ character is considered private and its state or behavior can change, without warning or documentation, on any given release.

The takeaway is that external developers should never explicitly code against anything that has a name that starts with an underscore. If they see a name that starts with an underscore, it’s simply ‘hands off’.

Alternatively, other libraries use @public and @private annotations in their JS docs as a way of indicating what is public/allowed vs. private/disallowed. However, we strongly prefer the underscore convention because anyone reading or writing code that does not have immediate access to the documentation can still see what is public vs private. For example it is common when browsing code in GitHub or Gists that annotations in documentation are not easily available. However, you can still always tell that underscore-prefixed methods are to be considered private.

Either way, you need to consistently convey which functions to use and which to leave alone. You may want to omit the private API from publicly hosted docs to prevent confusion.

Public API

The public API consists of all non-private functions, variables, classes, and builder/factory functions.

This may be surprising to some, but object literals used as part of configuration are also part of the public API. Think of it like this: if you tell people to use a function that requires an object literal, you are making a contract with them about what you support. It’s better to just maintain backwards and forwards compatibility with any changes to these object literals whenever possible.

Prototypical OO Classes

We use prototypical inheritance and constructor functions throughout the client, but the design reflects a more traditional OO style. We’ve found this makes sense to most of our customers of all skill/experience levels.

Stormpath is a User Management API, so our classes represent common user objects like Account, in addition to more generic classes, like ApiKey. A few classes used as examples in this post:

  • Client
  • ApiKey
  • Application
  • Directory
  • Account

Builder Functions

Node.js and other APIs often use method chaining syntax to produce a more readable experience. You may have also heard of this referred to as a Fluent Interface.

In our client, it’s possible to perform any API operation using a client instance. For example, getApplications obtains all Applications by using the client and method chaining:

client.getApplications()
.where(name).startsWith(‘foo’)
.orderBy(name).asc()
.limit(10)
.execute(function (err, apps){
  ...
});

There are two important things to note from this getApplications example:

  1. Query construction with where, startsWith and orderBy functions is synchronous. These are extremely lightweight functions that merely set a variable, so there is no I/O overhead and as such, do not need to be asynchronous.
  2. The execute function at the end is asynchronous and actually does the work and real I/O behavior. This is always asynchronous to comply with Node.js performance best practices.

Did you notice getApplications does not actually return an applications list but instead returns a builder object?

A consistent convention we’ve added to our client library is that get* methods will either make an asynchronous call or they will return a builder that is used to make an asynchronous call.

But we also support direct field access, like client.foo, and this implies a normal property lookup on a dictionary and a server request will not be made.

So, calling a getter function does something more substantial. Both still retain familiar dot notation to access internal properties. This convention creates a clear distinction between asynchronous behavior and simple property access, and the library user knows clearly what to expect in all cases.

Writing code this way helps with readability too – code becomes more simple and succinct, and you always know what is going on.

Base Resource Implementation

The base resource class has four primary responsibilities:

  1. Property manipulation methods – Methods (functions) with complicated interactions
  2. Dirty Checking – Determines whether properties have changed or not
  3. Reference to DataStore – All our resource implementations represent an internal DataStore object (we’ll cover this soon)
  4. Lazy Loading – Loads linked resources

Resource and all of its subclasses are actually lightweight proxies around a DataStore instance, which is why the constructor function below takes two inputs:

  1. data (an object of name/value pairs)
  2. A DataStore object.

     var utils = require('utils');
    
     function Resource(data, dataStore) {
    
       var DataStore = require('../ds/DataStore');
    
       if (!dataStore && data instanceof DataStore){
         dataStore = data;
         data = null;
       }
    
       data = data || {};
    
       for (var key in data) {
         if (data.hasOwnProperty(key)) {
           this[key] = data[key];
         }
       }
    
       var ds = null; //private var, not enumerable
       Object.defineProperty(this, 'dataStore', {
         get: function getDataStore() {
           return ds;
         },
         set: function setDataStore(dataStore) {
           ds = dataStore;
         }
       });
    
       if (dataStore) {
         this.dataStore = dataStore;
       }
     }
     utils.inherits(Resource, Object);
    
     module.exports = Resource;
    

When CRUD operations are performed against these resource classes, they just delegate work to the backend DataStore. As the DataStore is a crucial component of the private API, we keep it hidden using object-defined private property semantics. You can see this in practice with the public getters and setters around the private attribute above. This is one of the few ways to implement proper encapsulation in JavaScript.

If you remember to do just two things when implementing base resource classes, let them be:

  1. Copy properties over one-to-one
  2. Create a reference to a DataStore object to use later

Base Instance Resource Implementation

InstanceResource is a subclass of Resource. The base instance resource class prototypically defines functions such as save and delete, making them available to every concrete instance resource.

Note that the saveResource and deleteResource functions delegate work to the DataStore.

var utils = require('utils');
var Resource = require('./Resource');

function InstanceResource() {
  InstanceResource.super_.apply(this, arguments);
}
utils.inherits(InstanceResource, Resource);

InstanceResource.prototype.save = function saveResource(callback) {
  this.dataStore.saveResource(this, callback);
};

InstanceResource.prototype.delete = function deleteResource(callback) {
  this.dataStore.deleteResource(this, callback);
};

In traditional object oriented programming, the base instance resource class would be an abstract. It isn’t meant to be instantiated directly, but instead should be used to create concrete instance resources like Application:

var utils = require('utils');
var InstanceResource = require('./InstanceResource');

function Application() {
  Application.super_.apply(this, arguments);
}
utils.inherits(Application, InstanceResource);

Application.prototype.getAccounts = function
getApplicationAccounts(/* [options,] callback */) {
  var self = this;
  var args = Array.prototype.slice.call(arguments);
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;
  return self.dataStore.getResource(self.accounts.href, options,
                                    require('./Account'), callback);
};

How do you support variable arguments in a language with no native support for function overloading? If you look at the getAccounts function on Applications, you’ll see we’re inspecting the argument stack as it comes into the function.

The comment notation indicates what the signature could be and brackets represent optional arguments. These signal to the client’s maintainer(s) (the dev team) what the arguments are supposed to represent. It’s a handy documentation syntax that makes things clearer.

...
Application.prototype.getAccounts = function
getApplicationAccounts(/* [options,] callback */) {
  ...
}
...

options is an object literal of name/value pairs and callback is the function to be invoked. The client ultimately directs the work to the DataStore by passing in an href. The DataStore uses the href to know which resource it’s interacting with server-side.

Usage Paradigm

Let’s take a quick look at an example JSON resource returned by Stormpath:

{
  “href”: “https://api.stormpath.com/v1/accounts/x7y8z9”,
  “givenName”: “Tony”,
  “surname”: “Stark”,
  ...,
  “directory”: {
    “href”: “https://api.stormpath.com/v1/directories/g4h5i6”
  }
}

Every JSON document has an href field that exists in all resources, everywhere. JSON is exposed as data via the resource and can be referenced via standard dot notation like any other JavaScript object.

Note: Check out this blog post on linking and resource expansion if you’re wondering how we handle linking in JSON.

Proxy Pattern

Applications using a client will often have an href for one concrete resource and need access to many others. In this case, the client should support a method (e.g. getAccount) that takes in the href they have, to obtain the ones they need.

String href = 'https://api.stormpath.com/v1/...etc...';

client.getAccount(href, function(err, acct) {
  if (err) throw err;

  account.getDirectory(function(err, dir) {
    if (err) throw err;
    console.log(dir);
  });
});

In the above code sample,getAccount returns the corresponding Account instance, and then the account can be immediately used to obtain its parent Directory object. Notice that you did not have to use the client again!

The reason this works is that the Account instance is not a simple object literal. It is instead a proxy, that wraps a set of data and the underlying DataStore instance. Whenever it needs to do something more complicated than direct property access, it can automatically delegate work to the datastore to do the heavy lifting.

This proxy pattern is popular because it allows for many benefits, such as programmatic interaction between references, linked references, and resources. In fact, you can traverse the entire object graph with just the initial href! That’s awfully close to HATEOS! And it dramatically reduces boilerplate in your code by alleviating the need to repeat client interaction all the time.

SDK architecture diagram

So how does this work under the hood? When your code calls account.getDirectory, the underlying (wrapped) DataStore performs a series of operations under the hood:

  1. Create the HTTP request
  2. Execute the request
  3. Receive a response
  4. Marshal the data into an object
  5. Instantiate the resource
  6. Return it to the caller

Client Component Architecture

Clearly, the DataStore does most of the heavy lifting for the client. There’s actually a really good reason for this model: future enhancements.

Your client will potentially handle a lot of complexity that is simpler in the long run to decouple from resource implementations. Because the DataStore is part of the private API, we can leverage it to plugin new functionality and add new features without changing the Public API at all. The client will just immediately see the benefits.

Datastore

Here is a really good example of this point. The first release of our SDK Client did not have caching built in. Any time a Stormpath-backed app called getAccount, getDirectory, or any number of other methods, the client always had to execute an HTTP request to our servers. This obviously introduced latency to the application and incurred an unnecessary bandwidth hit.

However our DataStore-centric component architecture allowed us to go back in and plug in a cache manager. The instant this was enabled, caching became a new feature available to everyone and no one had to change their source code. That’s huge.

Anyway, let’s walk through the sequence of steps in a request, to see how the pieces work together.

Cache Manager Diagram

First, the DataStore looks up the cache manager, finds a particular region in that cache, and checks if the requested resource is in cache. If it is, the client returns the object from the cache immediately.

If the object is not in cache, the DataStore interacts with the RequestExecutor. The RequestExecutor is another DataStore component that in turn delegates to two other components: an AuthenticationStrategy and the RequestAuthenticator.

RequestExecutor

REST clients generally authenticate by setting values in the authorization header. This approach is incredibly convenient because it means swapping authentication strategies is a simple matter of changing out the header. All that is required is to change out the AuthenticationStrategy implementation and that’s it – no internal code changes required!

Many clients additionally support multiple/optional authentication schemes. More on this topic in part 3.

After authentication, the RequestExecutor communicates the outgoing request to the API server.

RequestExecutor to API Server

Finally, the ResourceFactory takes the raw JSON returned by the API server and invokes a constructor function to create the instance resource that wraps (proxies) this data, and again, the DataStore.

ResourceFactory

All of the client components represented in this diagram should be pluggable and swappable based on your particular implementation. To make this a reality as you architect the client, try to adhere to the Single Responsibility Principle: ensure that your functions and classes do one and only one thing so you can swap them out or remove them without impacting other parts of your library. If you have too many branching statements in your code, you might be breaking SRP and this could cause you pain in the future.

And there you have it! Our approach to designing a user-friendly and extremely maintainable client to your REST API. Check back for Part Three and a look at querying, authentication, and plugins!

API Management with Stormpath

Stormpath makes it easy to manage your API keys and authenticate developers to your API service. Learn more in our API Key Management Guide and try it for free!

Build a Node API Client - Part 2: Encapsulation, Resources, & Architecture

$
0
0

Build a Node API Client – Part 2: Encapsulation, Resources, & Architecture... oh my!

Welcome to Part Two of our series on Node.js Client Libraries. This post serves as our guide to REST client design and architecture. Be sure to check out Part One on Need-To-Know RESTful Concepts before reading on.

API Encapsulation

Before sinking our teeth into resources and architecture, let’s talk about encapsulation. At Stormpath, we like to clearly separate the public and private portions of our API client libraries, aka ‘SDKs’ (Software Development Kit).

All private functionality is intentionally encapsulated, or hidden from the library user. This allows the project maintainers to make frequent changes like bug fixes, design and performance enhancements, all while not impacting users. This leads to a much greater level of maintainability, allowing the team to deliver better quality software, faster, to our user community. And of course, an easier-to-maintain client results in less friction during software upgrades and users stay happy.

To achieve this, your Node.js client should only expose users to the public version of your API and never the private, internal implementation. If you’re coming from a more traditional Object Oriented world, you can think of the public API as behavior interfaces. Concrete implementations of those interfaces are encapsulated in the private API. In Node.js too, functions and their inputs and output should rarely change. Otherwise you risk breaking backwards compatibility.

Encapsulation creates lot of flexibility to make changes in the underlying implementation. That being said, semantic versioning is still required to keep your users informed of how updates to the public will affect their own code. Most developers will already be familiar semantic versioning, so it’s an easy usability win.

Encapsulation In Practice

We ensure encapsulation primarily with two techniques: Node.js module.exports and the ‘underscore prefix’ convention.

module.exports

Node.js gives you the ability to expose only what you want via its module.exports capability: any object or function in a module’s module.exports object will be available to anyone that calls.

This is a big benefit to the Node.js ecosystem and helps improve encaspsulation goals better than traditional JavaScript environments.

Underscore Names

Additionally we use the ‘underscore prefix’ convention for objects or functions that are considered private by the development team but still accessible at runtime because of JavaScript’s weak encapsulation behavior. That is, any object or function that starts with the underscore _ character is considered private and its state or behavior can change, without warning or documentation, on any given release.

The takeaway is that external developers should never explicitly code against anything that has a name that starts with an underscore. If they see a name that starts with an underscore, it’s simply ‘hands off’.

Alternatively, other libraries use @public and @private annotations in their JS docs as a way of indicating what is public/allowed vs. private/disallowed. However, we strongly prefer the underscore convention because anyone reading or writing code that does not have immediate access to the documentation can still see what is public vs private. For example it is common when browsing code in GitHub or Gists that annotations in documentation are not easily available. However, you can still always tell that underscore-prefixed methods are to be considered private.

Either way, you need to consistently convey which functions to use and which to leave alone. You may want to omit the private API from publicly hosted docs to prevent confusion.

Public API

The public API consists of all non-private functions, variables, classes, and builder/factory functions.

This may be surprising to some, but object literals used as part of configuration are also part of the public API. Think of it like this: if you tell people to use a function that requires an object literal, you are making a contract with them about what you support. It’s better to just maintain backwards and forwards compatibility with any changes to these object literals whenever possible.

Prototypical OO Classes

We use prototypical inheritance and constructor functions throughout the client, but the design reflects a more traditional OO style. We’ve found this makes sense to most of our customers of all skill/experience levels.

Stormpath is a User Management API, so our classes represent common user objects like Account, in addition to more generic classes, like ApiKey. A few classes used as examples in this post:

  • Client
  • ApiKey
  • Application
  • Directory
  • Account

Builder Functions

Node.js and other APIs often use method chaining syntax to produce a more readable experience. You may have also heard of this referred to as a Fluent Interface.

In our client, it’s possible to perform any API operation using a client instance. For example, getApplications obtains all Applications by using the client and method chaining:

client.getApplications()
.where(name).startsWith(‘foo’)
.orderBy(name).asc()
.limit(10)
.execute(function (err, apps){
  ...
});

There are two important things to note from this getApplications example:

  1. Query construction with where, startsWith and orderBy functions is synchronous. These are extremely lightweight functions that merely set a variable, so there is no I/O overhead and as such, do not need to be asynchronous.
  2. The execute function at the end is asynchronous and actually does the work and real I/O behavior. This is always asynchronous to comply with Node.js performance best practices.

Did you notice getApplications does not actually return an applications list but instead returns a builder object?

A consistent convention we’ve added to our client library is that get* methods will either make an asynchronous call or they will return a builder that is used to make an asynchronous call.

But we also support direct field access, like client.foo, and this implies a normal property lookup on a dictionary and a server request will not be made.

So, calling a getter function does something more substantial. Both still retain familiar dot notation to access internal properties. This convention creates a clear distinction between asynchronous behavior and simple property access, and the library user knows clearly what to expect in all cases.

Writing code this way helps with readability too – code becomes more simple and succinct, and you always know what is going on.

Base Resource Implementation

The base resource class has four primary responsibilities:

  1. Property manipulation methods – Methods (functions) with complicated interactions
  2. Dirty Checking – Determines whether properties have changed or not
  3. Reference to DataStore – All our resource implementations represent an internal DataStore object (we’ll cover this soon)
  4. Lazy Loading – Loads linked resources

Resource and all of its subclasses are actually lightweight proxies around a DataStore instance, which is why the constructor function below takes two inputs:

  1. data (an object of name/value pairs)
  2. A DataStore object.

     var utils = require('utils');
    
     function Resource(data, dataStore) {
    
       var DataStore = require('../ds/DataStore');
    
       if (!dataStore && data instanceof DataStore){
         dataStore = data;
         data = null;
       }
    
       data = data || {};
    
       for (var key in data) {
         if (data.hasOwnProperty(key)) {
           this[key] = data[key];
         }
       }
    
       var ds = null; //private var, not enumerable
       Object.defineProperty(this, 'dataStore', {
         get: function getDataStore() {
           return ds;
         },
         set: function setDataStore(dataStore) {
           ds = dataStore;
         }
       });
    
       if (dataStore) {
         this.dataStore = dataStore;
       }
     }
     utils.inherits(Resource, Object);
    
     module.exports = Resource;
    

When CRUD operations are performed against these resource classes, they just delegate work to the backend DataStore. As the DataStore is a crucial component of the private API, we keep it hidden using object-defined private property semantics. You can see this in practice with the public getters and setters around the private attribute above. This is one of the few ways to implement proper encapsulation in JavaScript.

If you remember to do just two things when implementing base resource classes, let them be:

  1. Copy properties over one-to-one
  2. Create a reference to a DataStore object to use later

Base Instance Resource Implementation

InstanceResource is a subclass of Resource. The base instance resource class prototypically defines functions such as save and delete, making them available to every concrete instance resource.

Note that the saveResource and deleteResource functions delegate work to the DataStore.

var utils = require('utils');
var Resource = require('./Resource');

function InstanceResource() {
  InstanceResource.super_.apply(this, arguments);
}
utils.inherits(InstanceResource, Resource);

InstanceResource.prototype.save = function saveResource(callback) {
  this.dataStore.saveResource(this, callback);
};

InstanceResource.prototype.delete = function deleteResource(callback) {
  this.dataStore.deleteResource(this, callback);
};

In traditional object oriented programming, the base instance resource class would be an abstract. It isn’t meant to be instantiated directly, but instead should be used to create concrete instance resources like Application:

var utils = require('utils');
var InstanceResource = require('./InstanceResource');

function Application() {
  Application.super_.apply(this, arguments);
}
utils.inherits(Application, InstanceResource);

Application.prototype.getAccounts = function
getApplicationAccounts(/* [options,] callback */) {
  var self = this;
  var args = Array.prototype.slice.call(arguments);
  var callback = args.pop();
  var options = (args.length > 0) ? args.shift() : null;
  return self.dataStore.getResource(self.accounts.href, options,
                                    require('./Account'), callback);
};

How do you support variable arguments in a language with no native support for function overloading? If you look at the getAccounts function on Applications, you’ll see we’re inspecting the argument stack as it comes into the function.

The comment notation indicates what the signature could be and brackets represent optional arguments. These signal to the client’s maintainer(s) (the dev team) what the arguments are supposed to represent. It’s a handy documentation syntax that makes things clearer.

...
Application.prototype.getAccounts = function
getApplicationAccounts(/* [options,] callback */) {
  ...
}
...

options is an object literal of name/value pairs and callback is the function to be invoked. The client ultimately directs the work to the DataStore by passing in an href. The DataStore uses the href to know which resource it’s interacting with server-side.

Usage Paradigm

Let’s take a quick look at an example JSON resource returned by Stormpath:

{
  “href”: “https://api.stormpath.com/v1/accounts/x7y8z9”,
  “givenName”: “Tony”,
  “surname”: “Stark”,
  ...,
  “directory”: {
    “href”: “https://api.stormpath.com/v1/directories/g4h5i6”
  }
}

Every JSON document has an href field that exists in all resources, everywhere. JSON is exposed as data via the resource and can be referenced via standard dot notation like any other JavaScript object.

Note: Check out this blog post on linking and resource expansion if you’re wondering how we handle linking in JSON.

Proxy Pattern

Applications using a client will often have an href for one concrete resource and need access to many others. In this case, the client should support a method (e.g. getAccount) that takes in the href they have, to obtain the ones they need.

String href = 'https://api.stormpath.com/v1/...etc...';

client.getAccount(href, function(err, acct) {
  if (err) throw err;

  account.getDirectory(function(err, dir) {
    if (err) throw err;
    console.log(dir);
  });
});

In the above code sample,getAccount returns the corresponding Account instance, and then the account can be immediately used to obtain its parent Directory object. Notice that you did not have to use the client again!

The reason this works is that the Account instance is not a simple object literal. It is instead a proxy, that wraps a set of data and the underlying DataStore instance. Whenever it needs to do something more complicated than direct property access, it can automatically delegate work to the datastore to do the heavy lifting.

This proxy pattern is popular because it allows for many benefits, such as programmatic interaction between references, linked references, and resources. In fact, you can traverse the entire object graph with just the initial href! That’s awfully close to HATEOS! And it dramatically reduces boilerplate in your code by alleviating the need to repeat client interaction all the time.

SDK architecture diagram

So how does this work under the hood? When your code calls account.getDirectory, the underlying (wrapped) DataStore performs a series of operations under the hood:

  1. Create the HTTP request
  2. Execute the request
  3. Receive a response
  4. Marshal the data into an object
  5. Instantiate the resource
  6. Return it to the caller

Client Component Architecture

Clearly, the DataStore does most of the heavy lifting for the client. There’s actually a really good reason for this model: future enhancements.

Your client will potentially handle a lot of complexity that is simpler in the long run to decouple from resource implementations. Because the DataStore is part of the private API, we can leverage it to plugin new functionality and add new features without changing the Public API at all. The client will just immediately see the benefits.

Datastore

Here is a really good example of this point. The first release of our SDK Client did not have caching built in. Any time a Stormpath-backed app called getAccount, getDirectory, or any number of other methods, the client always had to execute an HTTP request to our servers. This obviously introduced latency to the application and incurred an unnecessary bandwidth hit.

However our DataStore-centric component architecture allowed us to go back in and plug in a cache manager. The instant this was enabled, caching became a new feature available to everyone and no one had to change their source code. That’s huge.

Anyway, let’s walk through the sequence of steps in a request, to see how the pieces work together.

Cache Manager Diagram

First, the DataStore looks up the cache manager, finds a particular region in that cache, and checks if the requested resource is in cache. If it is, the client returns the object from the cache immediately.

If the object is not in cache, the DataStore interacts with the RequestExecutor. The RequestExecutor is another DataStore component that in turn delegates to two other components: an AuthenticationStrategy and the RequestAuthenticator.

RequestExecutor

REST clients generally authenticate by setting values in the authorization header. This approach is incredibly convenient because it means swapping authentication strategies is a simple matter of changing out the header. All that is required is to change out the AuthenticationStrategy implementation and that’s it – no internal code changes required!

Many clients additionally support multiple/optional authentication schemes. More on this topic in part 3.

After authentication, the RequestExecutor communicates the outgoing request to the API server.

RequestExecutor to API Server

Finally, the ResourceFactory takes the raw JSON returned by the API server and invokes a constructor function to create the instance resource that wraps (proxies) this data, and again, the DataStore.

ResourceFactory

All of the client components represented in this diagram should be pluggable and swappable based on your particular implementation. To make this a reality as you architect the client, try to adhere to the Single Responsibility Principle: ensure that your functions and classes do one and only one thing so you can swap them out or remove them without impacting other parts of your library. If you have too many branching statements in your code, you might be breaking SRP and this could cause you pain in the future.

And there you have it! Our approach to designing a user-friendly and extremely maintainable client to your REST API. Check back for Part Three and a look at querying, authentication, and plugins!

API Management with Stormpath

Stormpath makes it easy to manage your API keys and authenticate developers to your API service. Learn more in our API Key Management Guide and try it for free!

Build a Node API Client – Part 3: Queries, Caching and Authentication

$
0
0

Build a Node API Client – Part 3: Queries, Caching and Authentication

Welcome to Part Three of our guide to Node.js REST clients. This third and final blogpost will wrap up the series with a look at topics like querying, caching, API authentication, and lessons learned the hard way.

If you haven’t already, please start with Part One, the RESTful principles important for REST clients. Or skip to Part Two on building the client’s Public API and designing a component-based architecture.

Queries

Robust querying support reduces the effort required to use your API, especially if you implemented it with familiar conventions.

For instance, say your client user needs to interact with a particular collection resource…hopefully a plausible scenario! They would probably write something along these lines:

account.getGroups(function(err,groups) {
  ... callback logic ...
});

Assuming the groups are not in cache, a request needs to be automatically sent to the server to obtain the account’s groups, for example:

GET https://api.stormpath.com/v1/accounts/a1b2c3/groups

This is a great start, but ultimately a limited one. What happens the client user wants to specify search parameters? We need more powerful request query capabilities.

Query Parameters with Object Literals

An improvement is to accept an object literal to populate query parameters. This is a common technique in Node.js that specifies query parameters or skips the optional object and passes in the proceeding callback function.

account.getGroups({
  name: ‘foo*’,
  description: ‘*test*’,
  orderBy: ‘name desc’,
  limit: 100
}, function onResult(err, groups) {
  ...
});

This would result in the following HTTP request:

GET https://api.stormpath.com/v1/accounts/a1b2c3/groups?name=foo*&description=*test*&orderBy=name%20desc&limit=100

The client simply takes the name/value pairs on the object and translates them to url-encoded query parameters. We accept an object literal rather than query strings because no one wants to mess with URL encoding. This is a perfect place to offload work from your client user to the client.

Fluent API Queries

While the above approach is nice and convenient, it still requires some specific knowledge of the API’s specific query syntax. In the above example, to find any group that starts with the name foo, you need to know to use a wildcard matching asterisk at the end of the search term, i.e.

account.getGroups({
  name: 'foo*', // for comparison, in SQL, this looks like
                // 'where name like foo%'
  ... etc ...

While it is easy enough to learn these syntax additions, it is even easier for client users if they have a Fluent API to help them construct queries in a fully explicit and self-documenting way. IDEs with intelligent auto-completion can even help tell you what methods are available while writing your query, helping you write queries much faster!

Consider the following example. The resulting query to the server is no different than the one above that used an object literal, but the query author now does not need to know any syntax-specific modifiers:

account.getGroups().where()
.name().startsWith(“foo”)
.description().contains(“test”)
.orderBy(“name”).desc()
.limitTo(100)
.execute(function onResult(err, result) {
  ... handle result ...
});

As expected, this results in the same HTTP request:

GET https://api.stormpath.com/v1/accounts/a1b2c3/groups?name=foo*&description=*test*&orderBy=name%20desc&limit=100

As you can see, the query author just chains method calls and then the client implementation constructs the relevant query parameter map and executes the request.

In addition to being easier to read and perhaps better self-documenting, this approach has some other very compelling benefits:

  • Because functions represent known queryable properties, it is not possible to specify query criteria that is not supported as a function.
  • Similarly, all possible functionality, like ordering and size limiting, are discoverable just by inspecting functions and code – there is less of a need to read external documentation! This is a huge help to those who just want to write queries quickly and move on – definitely a nice usability benefit.
  • It is much harder, if not impossible, to form a syntactically incorrect query. Query authors will likely ‘get it right’ the first time they write a query, thereby reducing bugs in their own code and increasing their overall happiness with your library.

There is, of course, a downside to supporting a fluent API for querying: implementation effort. It definitely requires a little more time and care to develop a builder/chaining API that client users can interact with easily. However, because of the self-documenting and syntatic checking nature, we feel fluent APIs are one of those features that really takes your library to the next level and can only make users happier.

Even with this downside though, there is one side benefit: when you’re ready to add a fluent query API to your library, your implementation can build directly on top of the object literal query capability described above. This means you can build and release your library in an iterative fashion: build in the object literal query support first, ensure that works, and then release your library.

When you’re ready, you can create a fluent query implementation that just generates the same exact object literals that a client user could have specified. This means you’re building on top of something that already works – there is no need to re-write another query mechanism from scratch, saving you time.

Caching

Our SDK utilizes a CacheManager, a component used by the DataStore to cache results that come back from the server. While the cache manager itself is a very simple concept, caching is extremely important for performance and efficiency. This is especially true for clients that communicate with REST servers over the public Internet. Cache if you can!

The CacheManager reflects a pluggable design. Users can configure the client to use the default in-memory implementation, or they can configure (plug in) out-of-the-box support for Memcache or Redis. This is a big benefit to many production-grade apps that run on more than one web server. Additionally, the CacheManager API itself is very simple; you can also implement and plug in new ones easily if the existing three implementations do not suit your needs.

Regardless of the specific CacheManager implementation selected, the client instance can access one or more Cache objects managed by the CacheManager. Typically, each Cache object represents a single region in the overall cache memory space (or cache cluster) where data can be stored. Each cache region typically has a specific Time-To-Live and Time-To-Idle setting that applies to all data records in that cache region.

Because of this per-region capability, the Stormpath SDK stores resource instances in a region by type. All Accounts are in one region, all Groups in another, etc. This allows the client user to configure caching policies for each data type as they prefer, based on their application’s data consistency needs.

So, how does this work internally in the Client?

Because of RESTful philosophies (covered in Part One of this blog series), every resource should have a globally-unique canonical HREF that uniquely identifies it among all others. Because of this canonical and unique nature, that means a resource’s HREF is a perfect candidate for cache key. Cache entries under a href key will never collide, so we’ll use the HREF as the cache key.

This allows a client DataStore to obtain a cached version of a resource before attempting to send a REST API server HTTP request. More importantly, the DataStore should be able to get an element out of the cache by passing in a resource HREF. In the example below, the callback function takes an error or the raw object stored in the cache.

var cache = cacheManager.getCache(regionName);

cache.ttl //time to live
cache.tti //time to idle
cache.get(href, function(err, obj) {
  ...
});

At Stormpath, we only store name/value pairs in the cache and nothing else. The data in our cache is the same stuff sent to and from the server.

client.getAccount(href, function(err, acct) {...});

// in the DataStore:
var cache = cacheManager.getCache(‘accounts’);

cache.get(href, function(err, entry) {
  if (err) return callback(err);
  if (entry) {
    ... omitted for brevity ...
    return callback(entry.value);
  }

  //otherwise, cache miss – execute a request:
  requestExecutor.get(href, function(err, body) {
    //1. cache body
    //2. convert to Resource instance
    //3. invoke callback w/ instance
  }
}

When getAccount is called, the client first interacts with cacheManager to get the cache region and then requests the cached object. If the object is found, it executes the callback. If the object isn’t found, it executes a request to the server using requestExecutor.

The fallback logic is fairly straightforward: Check the cache before issuing a request to the server. The beautiful thing is that your client users don’t have to change any of their code – they can just navigate the object tree regardless of whether the data is held in cache.

Recursive Caching

Recursive caching is, in a word, important.

When you request a resource from the server, you can use something called reference expansion or link expansion to not only obtain the desired resource, but any of its linked/referenced resources as well.

This means any expanded response JSON representation can be an object graph: the requested resource plus any other nested JSON objects for any linked resources. Each one of these resources needs to be cached independently (again, keyed based on each resource’s href).

Recursive caching is, then, basically walking this resource object graph, and for each resource found, caching that resource by its href key. Our implementation of this ‘graph walk’ utilizes recursion because it was simpler for us to implement and it’s fairly elegant. This is why it is called recursive caching. If we implemented it via iteration instead, I suppose we would have called it iterative caching.

Authentication

Secure authentication is near and dear to our hearts at Stormpath, which is why we recommend defaulting API authentication in your client to a digest-based scheme instead of HTTP basic. Although basic authentication is the simplest form of HTTP authentication, it is probably the one with the most security risks:

  • The secret (‘password’) is sent in an HTTP header essentially in plain text. This means HTTP basic can very easily expose raw passwords to potential attackers in any part of infrastructure that does not use TLS (previously known as SSL).
  • HTTP Basic authentication allows embedding the id and password in the URL, and this is never a good idea: URLs are logged all the time for analytics and reporting, exposing the secret password to anyone.
  • HTTP Basic authentication does not prevent Man-in-the-Middle (MitM) attacks at any point before or after network transmission. This is true even if you’re using TLS.

Because of these perils, we only advocate supporting HTTP Basic authentication if you have no other choice, and instead use what is known as a Digest-based authentication scheme. While digest authentication schemes are out of scope of this blogpost, OAuth 1.0a and Stormpath’s sauthc algorithm are good, very secure examples.

That being said, clients should offer basic authentication as an optional strategy for environments where digest schemes are incompatible. For instance, Google App Engine manipulates HTTP request object headers before sending requests out on the wire – the exact behavior that digest algorithms protect against. Our original clients didn’t work on GAE for this reason until we implemented optional basic auth.

Note: Basic authentication can only ever be implemented over TLS. It’s never okay to use basic without TLS, it’s simply too easy to find the raw password value.

Because of the need for this occasional customization, clients can be configured to specify an alternative Authentication Scheme as a constant object. For example:

  • AuthenticationScheme.SAUTHC1
  • AuthenticationScheme.Basic
  • AuthenticationScheme.OAUTH10a
  • … etc …

For example, if a client user needed to use BASIC authentication:

var client = new Stormpath.Client({
  authcScheme: ‘basic’ //defaults to 'sauthc1' otherwise
});

If they don’t specify a config value, default to the most secure option your API server supports.

Plugins

A well-defined API permits the client to support plugins/extensions without the support of type safety or interfaces. Duck typing helps too.

For example, Stormpath’s RequestExecutor relies on the Request.js module (as do many other Node.js applications). However, if anyone wanted to modify our client to use a different HTTP request library, they could implement an object with the same functions and signatures of the RequestExecutor API and just plug it in to the client configuration.

This flexibility becomes important as your client supports a broader variety of environments and applications.

Promises and Async.js

Callback Hell: The bane of Node.js library maintainers and end-users alike. Luckily, there are a couple good options to keep your Node.js code readable. For instance, Promises promote traceability even in async environments executing concurrently.

var promise = account.getGroups();

promise.then(function() {
  //called on success
}, function() {
  //called on error
}, function() {
  //called during progress
});

However, excessive use of Promises has been linked to degraded application performance – use them in a calculated fashion. Since Promises are a fairly new design approach in Node.js, most Node.js applications today use callbacks instead. If you want to stick with the dominant approach, and still avoid highly-nested functions, take a look at the fantastic async.js module.

Check out this waterfall style control flow!

async.waterfall([
  function(callback) {
    callback(null, 'one', 'two');
  },
  function(arg1, arg2, callback) {
    // arg1 now equals 'one' and arg2 now equals 'two'
    callback(null, 'three');
  },
  function(arg1, callback) {
    // arg1 now equals 'three'
    callback(null, 'done');
  }],
  function (err, result) {
  // result now equals 'done'
  }
);

This code is readable – it looks like more readable imperative-style programming code, but because async.js is managing invocation, the code is still asynchronous and conforms to Node.js performance best practices.

As we mentioned previously in Part One, all of the Stormpath SDK Collections inherit async.js iterator functions so you can use collections in the same way. Convenient!

Stormpath Node.js Client

The Stormpath Node.js client is Apache licensed and 100% open source. Now that you’ve gotten an idea for how we built ours, try cloning it for more real-world examples.

$ git clone https://github.com/stormpath/stormpath-sdk-node.git

$ cd Stormpath-sdk-node
$ npm install
$ grunt

API Management With Stormpath

Stormpath makes it easy to manage your API keys and authenticate developers to your API service. Learn more in our API Key Management Guide and try it for free!

Happy coding!

Viewing all 278 articles
Browse latest View live