0% found this document useful (0 votes)
66 views5 pages

Implementing Oauth On Top of Redis: Problem

The document describes implementing OAuth authentication on top of Redis. Key-value pairs like consumer keys, tokens, and nonces would be stored in Redis hashes, sets, and strings to model the OAuth data and verify requests. When a consumer requests a token, the consumer's key and a unique nonce are validated. If valid, a request token is issued and stored. If the user authorizes the request, an access token is generated and the request token is deleted. The access token is used to authenticate API requests after validating the consumer and token details match what is stored in Redis. Redis pub/sub is also described as a way to implement a real-time chat system by subscribing clients to messages on specific channels.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
66 views5 pages

Implementing Oauth On Top of Redis: Problem

The document describes implementing OAuth authentication on top of Redis. Key-value pairs like consumer keys, tokens, and nonces would be stored in Redis hashes, sets, and strings to model the OAuth data and verify requests. When a consumer requests a token, the consumer's key and a unique nonce are validated. If valid, a request token is issued and stored. If the user authorizes the request, an access token is generated and the request token is deleted. The access token is used to authenticate API requests after validating the consumer and token details match what is stored in Redis. Redis pub/sub is also described as a way to implement a real-time chat system by subscribing clients to messages on specific channels.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

Implementing OAuth on Top of Redis

Problem
In this recipe, we’ll implement a data model and interaction to support an OAuth v1.0a
API. This is usually achieved on top of MySQL or another RDBMS, but we’ll leverage
Redis’s data structures for a more efficient implementation.

Solution
We won’t be implementing the API or the OAuth interaction itself. Here we’re inter-
ested only in the data required for this sort of scenario. We’ll be storing five types of
data in Redis:
consumer keys
consumer secrets
request tokens
access tokens
nonces
So the needs are as follows: applications (consumers) are identified by their key and
secret, of which they have exactly one pair. Those consumers can have as many request
and access tokens as they desire, and the nonces should be unique per consumer/time-
stamp pair.
These types of data will be stored in hashes, sets, and strings depending on their specific
requirements and interactions.

Discussion
Initial setup
To start with, consumers must enter their data before they issue a request. Let’s put
this data in a hash with the consumer information. The key is the one we’ve stored for
the particular consumer when he or she registered with our system:
HMSET /consumers/key:dpf43f3p2l4k3l03 secret kd94hf93k423kf44 created_at 201103060000
redirect_url http://www.example.com/oauth_redirect name test_application

Please ignore newlines in commands; they’re only for styling purposes.


A command should be issued all on one line.

This command gives us, for every application, a hash containing its “general” data,
which can be extended over time. The same could be achieved in Memcache either by

22 | Chapter 3: Leveraging Redis

www.it-ebooks.info
storing all the values in different keys or by storing the data in some format like JSON
or YAML.

Quick Reference for Adding Values to Sets


HSET hash-name key value
Sets a value on a hash with the given key. As with other Redis commands, if the
hash doesn’t exist, it’s created.
HMSET hash-name key1 value1 [key2 value2 ...]
Allows you to set several values in a hash with a single command.

Getting a request token


In order to get a request token, consumers send their key, a timestamp, a unique gen-
erated nonce, a callback url, and a request signature that is a hash of the request path
and parameters using the consumer secret. (For security purposes, the consumer secret
is never sent—it’s a pre-shared secret since both parts know it).
The API provider needs to verify that the signature is correct using the key and secret,
check whether this nonce/timestamp combination was used previously (to prevent re-
playing), and generate a new request token.
In order to do so, the server needs to fetch the consumer data:
HGETALL /consumers/key:dpf43f3p2l4k3l03

and then check that this nonce hasn’t been used yet:
SADD /nonces/key:dpf43f3p2l4k3l03/timestamp:20110306182600 dji430splmx33448

Using a set to store the nonce data has a few advantages. First, sets assure uniqueness
(we’ll see in a minute how to tell whether the element was present already). Also, we
can delete all the nonces for past requests after a chosen period of time, by setting
expiration times on each one. For this application, let’s make the expiration time 30
minutes.
EXPIRE /nonces/key:dpf43f3p2l4k3l03/timestamp:20110306182600 1800

Now, if someone was to attempt to replay this request by sending the same timestamp
and nonce, issuing the same SADD command as before would return 0, indicating that
this value was already present in the set. Should this happen, the provider should refuse
to generate a new token.
After validating all the data, we need to create a token and matching secret:
HSET /request_tokens/key:dpf43f3p2l4k3l03 hh5s93j4hdidpola hdhd0244k9j7ao03

Implementing OAuth on Top of Redis | 23

www.it-ebooks.info
Quick Reference for Authorization Algorithm
HGETALL hash-name
Returns all the key/value pairs in the given hash.
SADD set-name element
Adds the element to the given set unless it’s already a member. The return value
is 1 if the element is added and 0 if it was already a member.
EXPIRE key seconds
Sets an expiration timeout on a key, after which it will be deleted. This can be used
on any type of key (strings, hashes, lists, sets or sorted sets) and is one of the most
powerful Redis features.
EXPIREAT key timestamp
Performs the same operation as EXPIRE, except you can specify a UNIX timestamp
(seconds since midnight, January 1, 1970) instead of the number of elapsed sec-
onds.
TTL key
Tells you the remaining time to live of a key with an expiration timeout.
PERSIST key
Removes the expiration timeout on the given key.

Redirections and consent


After successfully retrieving the request token, the consumer should redirect the user
to the API provider, which will authenticate the user and authorize the application to
access the user’s data. Should the user grant his permission, we’ll have to store it:
SET /authorizations/request_token:hh5s93j4hdidpola 16

Once that is done, we can redirect the user to the redirect URL we stored:
HGET /consumers/key:dpf43f3p2l4k3l03 redirect_url

Exchanging the request token for an access token


The access tokens are what the consumers need to authenticate with the API. These
are obtained by submitting the consumer key, request token, and secret that were pre-
viously fetched and generating an access token. Most APIs that rely on OAuth do so
for authentication purposes, so we’ll also check whether this access token was author-
ized by a user.
HGETALL /consumers/key:dpf43f3p2l4k3l03

As for the previous operations, we need to check whether the consumer key is valid
and matches an existing application.
HGET /request_tokens/key:dpf43f3p2l4k3l03 hh5s93j4hdidpola

24 | Chapter 3: Leveraging Redis

www.it-ebooks.info
We also need to check the request token and a failure to find it would probably mean
someone is attempting to reuse a request token which is not allowed by the spec.
GET /authorizations/request_token:hh5s93j4hdidpola

The last thing we need to check is which user authorized this application.
SADD /nonces/key:dpf43f3p2l4k3l03/timestamp:20110306182700 kllo9940pd9333jh
EXPIRE /nonces/key:dpf43f3p2l4k3l03/timestamp:20110306182600 1800

Once again, the nonce should be unique for this consumer—the output of SADD suffices
as sets assure uniqueness. A failure in any of the checks implies an invalid request and
therefore we shouldn’t generate an access token. If everything is OK, we can proceed:
HMSET /access_tokens/consumer_key:dpf43f3p2l4k3l03/access_token:nnch734d00sl2jdk
secret pfkkdhi9sl3r4s00 user_id 16 created_at 20110306182600
HDEL /request_tokens/key:dpf43f3p2l4k3l03 hh5s93j4hdidpola
DEL /authorizations/request_token:hh5s93j4hdidpola

Perhaps somewhere in our application we allow users to see which applications have
access to their credentials. To facilitate the retrieval of that information, let’s add it to
a hash of client applications:
HSET /users/user_id:16/applications dpf43f3p2l4k3l03 nnch734d00sl2jdk

A follow-up feature would be to allow users to revoke access to these applications.


Doing so is trivial:
HDEL /users/user_id:16/applications dpf43f3p2l4k3l03
DEL /access_tokens/consumer_key:dpf43f3p2l4k3l03/access_token:nnch734d00sl2jdk

Our application logic might also define different expiration times for each new token,
perhaps even at the user’s request. Let’s say that in this case the user gave permission
for 24 hours (86400 seconds):
EXPIRE /access_tokens/consumer_key:dpf43f3p2l4k3l03/access_token:nnch734d00sl2jdk
86400

Beware of one detail: if you are expiring the access tokens, you need either to check for
their existence (and remove them from the hash if they’re absent) before presenting the
user with the list of authorizated applications, or to do a regular clean-up operation
that checks that the keys in the /users/user_id:16/applications hash are still valid.

Quick Reference for Hash Operations


HGET hash-name key
Returns the value at key in the given hash.
HDEL hash-name key
Deletes a key/value pair in the given hash.

Implementing OAuth on Top of Redis | 25

www.it-ebooks.info
API Access
When the consumer is accessing the API, the process should be really simple: validate
the keys, secrets, signatures, and nonce.
HGETALL /consumers/key:dpf43f3p2l4k3l03
HGETALL /access_tokens/key:dpf43f3p2l4k3l03/access_token:nnch734d00sl2jdk
SADD /nonces/key:dpf43f3p2l4k3l03/timestamp:20110306182800 kllo9940pd9333jh
EXPIRE /nonces/key:dpf43f3p2l4k3l03/timestamp:20110306182600 1800

Using Redis’s Pub/Sub Functionality to Create a Chat System


Problem
You want to leverage Redis’s pub/sub functionality to create a light real-time chat sys-
tem with Node.js and Socket.IO.

Solution
Since Redis has native support for the publish/subscribe (or pub/sub) pattern, we can
easily use it in conjunction with Node.js and Socket.IO to quickly create a real-time
chat system.
The publish/subscribe pattern defines a way in which receivers subscribe to messages
that match a specific pattern (for instance, messages that are sent to a specific “chan-
nel”), and a way for an emitter to send messages to a message cloud. When a message
hits that cloud, clients that subscribe to messages of that kind will get the message. The
pattern allows then for emitters and clients to be loosely coupled—they don’t need to
know each other. They just need to be able to send messages in a given pattern, and
receive messages that match that pattern.
For a better understanding of how Publish/Subscribe works, see the Wikipedia page.
Redis has direct support for the pub/sub pattern, meaning that it lets clients subscribe
to specific channels matching a given pattern, and to publish messages to a given chan-
nel. This means that we can easily create channels like “chat:cars” for car-talk, or
“chat:sausage” for food-related conversation. The channel names are not related to the
Redis keyspace so you don’t have to worry about conflicts with existing keys. The pub/
sub functionality is supported by the following Redis commands:
PUBLISH
Publishes to a specific channel
SUBSCRIBE
Subscribes to a specific channel
UNSUBSCRIBE
Unsubscribes from a specific channel

26 | Chapter 3: Leveraging Redis

www.it-ebooks.info

You might also like