Integration
Ruby
AgeOnce integration with Ruby (Ruby on Rails, Sinatra)
Ruby Integration
Complete AgeOnce integration example with Ruby.
Install dependencies
# Gemfile
gem 'httparty'
gem 'jwt'bundle installAgeOnce client
# lib/ageonce.rb
require 'httparty'
require 'securerandom'
class AgeOnce
include HTTParty
def initialize
@client_id = ENV['AGEONCE_CLIENT_ID']
@client_secret = ENV['AGEONCE_CLIENT_SECRET']
@redirect_uri = ENV['AGEONCE_REDIRECT_URI']
@api_url = ENV['AGEONCE_API_URL'] || 'https://app.ageonce.com'
end
def generate_verify_url
state = SecureRandom.hex(16)
params = {
client_id: @client_id,
redirect_uri: @redirect_uri,
state: state
}
url = "#{@api_url}/verify?#{URI.encode_www_form(params)}"
{ url: url, state: state }
end
def exchange_code_for_token(code)
response = self.class.post(
"#{@api_url}/api/oauth/token",
headers: { 'Content-Type' => 'application/json' },
body: {
client_id: @client_id,
client_secret: @client_secret,
code: code,
redirect_uri: @redirect_uri
}.to_json
)
raise "Token exchange failed: #{response['error_description']}" unless response.success?
response.parsed_response
end
def validate_token(token)
response = self.class.post(
"#{@api_url}/api/oauth/validate",
headers: { 'Content-Type' => 'application/json' },
body: { token: token }.to_json
)
return { 'valid' => false } unless response.success?
response.parsed_response
end
endUsage examples
# config/routes.rb
Rails.application.routes.draw do
get '/verify', to: 'ageonce#verify'
get '/callback', to: 'ageonce#callback'
get '/protected', to: 'ageonce#protected'
end
# app/controllers/ageonce_controller.rb
class AgeonceController < ApplicationController
before_action :require_age_verification, only: [:protected]
def verify
ageonce = AgeOnce.new
data = ageonce.generate_verify_url
session[:oauth_state] = data[:state]
redirect_to data[:url], allow_other_host: true
end
def callback
if params[:state] != session[:oauth_state]
render plain: 'Invalid state', status: :bad_request
return
end
begin
ageonce = AgeOnce.new
token_data = ageonce.exchange_code_for_token(params[:code])
result = ageonce.validate_token(token_data['age_token'])
if result['valid'] && result.dig('payload', 'age_verified')
session[:age_verified] = true
session[:min_age] = result.dig('payload', 'min_age')
redirect_to '/protected'
else
render plain: 'Age verification failed', status: :forbidden
end
rescue => e
render plain: "Error: #{e.message}", status: :internal_server_error
end
end
def protected
render plain: 'Welcome to age-restricted content!'
end
private
def require_age_verification
redirect_to '/verify' unless session[:age_verified]
end
end
# app/controllers/concerns/age_verification.rb
module AgeVerification
extend ActiveSupport::Concern
included do
before_action :require_age_verification
end
private
def require_age_verification
redirect_to '/verify' unless session[:age_verified]
end
end
# Usage in controller:
# class ProtectedController < ApplicationController
# include AgeVerification
# end# app.rb
require 'sinatra'
require 'sinatra/cookies'
require_relative 'lib/ageonce'
enable :sessions
set :session_secret, 'your-secret-key'
ageonce = AgeOnce.new
get '/verify' do
data = ageonce.generate_verify_url
session[:oauth_state] = data[:state]
redirect data[:url]
end
get '/callback' do
if params[:state] != session[:oauth_state]
halt 400, 'Invalid state'
end
begin
token_data = ageonce.exchange_code_for_token(params[:code])
result = ageonce.validate_token(token_data['age_token'])
if result['valid'] && result.dig('payload', 'age_verified')
session[:age_verified] = true
redirect '/protected'
else
halt 403, 'Age verification failed'
end
rescue => e
halt 500, "Error: #{e.message}"
end
end
def require_age_verification
redirect '/verify' unless session[:age_verified]
end
get '/protected' do
require_age_verification
'Welcome to age-restricted content!'
endLocal JWT validation
require 'jwt'
require 'net/http'
require 'json'
class AgeOnceJwtValidator
def initialize
@api_url = ENV['AGEONCE_API_URL'] || 'https://app.ageonce.com'
@public_keys = nil
end
def validate(token)
keys = fetch_public_keys
decoded = JWT.decode(
token,
nil,
true,
{
algorithms: ['RS256'],
iss: 'ageonce',
jwks: { keys: keys }
}
)
{ valid: true, payload: decoded.first }
rescue JWT::DecodeError => e
{ valid: false, error: e.message }
end
private
def fetch_public_keys
return @public_keys if @public_keys
uri = URI("#{@api_url}/api/oauth/jwks")
response = Net::HTTP.get(uri)
jwks = JSON.parse(response)
@public_keys = jwks['keys']
end
end
# Usage
validator = AgeOnceJwtValidator.new
result = validator.validate(age_token)
if result[:valid] && result[:payload]['age_verified']
# Grant access
endRuby provides elegant syntax for working with API and JWT.