Tech Tidbits - Ruby, Ruby On Rails, Merb, .Net, Javascript, jQuery, Ajax, CSS...and other random bits and pieces.

Saturday, July 26, 2008

authentication token

I had a need to both validate the source of data sent to a web service and to only accept the data if it was sent within a limited time period. One thing I didn't need, (but I imagine would be necessary in most cases) was to only allow the request once, in which case you would probably want to store the token in a database and flag it once it had been "redeemed."

To create the token, first concatenate current time in epoch seconds (or whatever time format you like, but stick with UTC since the end user may be any where in the world), username, and a password, then m5d and base64 that concatenated string and prepend it with the same timestamp, separated by a colon (':').

#!/usr/bin/ruby
require 'digest/md5'
require 'base64'

# Username/password
UID = 'marypoppins'
PWD = "supercalifragilisticexpialidocious"

# create token using utc secconds, uid, and pwd
def create_token(t=nil)
timestamp = t || Time.now.utc.to_i.to_s
plaintext = timestamp + UID + PWD
md5 = Digest::MD5.digest(plaintext)
return timestamp + ':' + Base64.encode64(md5).strip
end

# validate token
def validate_token(token)
token_timestamp = token.split(':')[0]
token2 = create_token(token_timestamp)
return token == token2 ? true : false
end

# validate timestamp and token
def validate_token_and_timestamp(token,num_secs=60)
token_timestamp = token.split(':')[0]
return nil if Time.now.to_i - token_timestamp.to_i > num_secs
token2 = create_token(token_timestamp)
return token == token2 ? true : false
end

The most basic example: create a token and validate it by creating a new token using the timestamp in the original token with the known user id and password. If the two tokens match, the original token is valid (which it will be in this contrived example):

# create a token and validate
if (validate_token(create_token))
puts "Valid token"
else
puts "Invalid token"
end

To check if the token was passed within a certain time period, just compare the timestamp on the original token with current time.

# create a token and validate timestamp and token
if (validate_token_and_timestamp(create_token,10))
puts "Valid token"
else
puts "Invalid token"
end


For demonstration only, use sleep to timeout a token:

# create a token, but let token timeout before trying to validate
timeout_token = create_token
sleep 15
if (validate_token_and_timestamp(timeout_token,10))
puts "Valid token"
else
puts "Invalid token"
end

No comments:

About Me

My photo
Developer (Ruby on Rails, iOS), musician/composer, Buddhist, HSP, Vegan, Aspie.

Labels