Class: FacebookClient::Session::SignedRequestParam

Inherits:
Base
  • Object
show all
Defined in:
lib/session/signed_request_param.rb

Instance Attribute Summary

Attributes inherited from Base

#fb

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#graph

Constructor Details

#initialize(fb, params) ⇒ SignedRequestParam

Returns a new instance of SignedRequestParam.



29
30
31
32
# File 'lib/session/signed_request_param.rb', line 29

def initialize(fb, params)
  @fb=fb
  @data=parse_signed_request!(params["signed_request"])
end

Class Method Details

.base64_url_decode(str) ⇒ Object

Ruby’s implementation of base64 decoding seems to be reading the string in multiples of 4 and ignoring any extra characters if there are no white-space characters at the end. Since facebook does not take this into account, this function fills any string with white spaces up to the point where it becomes divisible by 4, then it replaces ‘-’ with ‘+’ and ‘_’ with ‘/’ (URL-safe decoding), and decodes the result.



83
84
85
86
# File 'lib/session/signed_request_param.rb', line 83

def self.base64_url_decode(str)
  str = str + "=" * (4 - str.size % 4) unless str.size % 4 == 0
  return Base64.decode64(str.tr("-_", "+/"))
end

.create_and_secure(fb, params) ⇒ Object



23
24
25
26
27
# File 'lib/session/signed_request_param.rb', line 23

def self.create_and_secure(fb, params)
  session = new(fb, params)
  
  session.secure? ? session : nil
end

.parse_params(signed_request) ⇒ Object

looks like this: “algorithm”=>“HMAC-SHA256”, “user_id”=>“19392189382”, “oauth_token”=>“some-token”



66
67
68
69
# File 'lib/session/signed_request_param.rb', line 66

def self.parse_params(signed_request)
  encoded_url = signed_request.split(".").last
  data = JSON.parse(base64_url_decode(encoded_url))
end

.verify_signed_request(secret, signed_request) ⇒ Object

This function takes the app secret and the signed request, and verifies if the request is valid.



72
73
74
75
76
77
# File 'lib/session/signed_request_param.rb', line 72

def self.verify_signed_request(secret, signed_request)
  signature, encoded_url = signed_request.split(".")
  signature = base64_url_decode(signature)
  expected_sig = OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('SHA256'), secret, encoded_url.tr("-_", "+/"))
  return signature == expected_sig
end

Instance Method Details

#access_tokenObject



47
48
49
# File 'lib/session/signed_request_param.rb', line 47

def access_token
  @data["oauth_token"]
end

#calculate_sig(params) ⇒ Object



57
58
59
60
61
62
# File 'lib/session/signed_request_param.rb', line 57

def calculate_sig(params)
  args = params.reject{ |(k, v)| k == 'sig' }.sort.
    map{ |a| a.join('=') }.join

  Digest::MD5.hexdigest(args + @fb.secret)
end

#check_sig_and_return_data(signed_request, params) ⇒ Object

private



53
54
55
# File 'lib/session/signed_request_param.rb', line 53

def check_sig_and_return_data(signed_request, params)
  params if self.class.verify_signed_request(@fb.secret, signed_request)
end

#parse_signed_request!(str) ⇒ Object



34
35
36
37
# File 'lib/session/signed_request_param.rb', line 34

def parse_signed_request!(str)
  @data = str &&
    check_sig_and_return_data(str, self.class.parse_params(str))
end

#secure?Boolean

Returns:

  • (Boolean)


39
40
41
# File 'lib/session/signed_request_param.rb', line 39

def secure?
  @data.is_a?(Hash) and @data.has_key?('user_id')
end

#uidObject



43
44
45
# File 'lib/session/signed_request_param.rb', line 43

def uid
  @data['user_id']
end