facebook-signed-request 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +34 -29
- data/lib/facebook-signed-request/signed_request.rb +32 -16
- data/lib/facebook-signed-request/version.rb +1 -1
- data/test/signed_request_test.rb +18 -0
- metadata +1 -1
data/README.md
CHANGED
@@ -3,33 +3,38 @@ Usage
|
|
3
3
|
|
4
4
|
|
5
5
|
```ruby
|
6
|
-
require 'facebook-signed-request'
|
7
|
-
request = Facebook::SignedRequest.new( params[:signed_request], secret )
|
8
|
-
|
9
|
-
request.valid?
|
10
|
-
# => true / false
|
11
|
-
|
12
|
-
request.errors
|
13
|
-
# => [
|
14
|
-
# "Invalid Format. See http://developers.facebook.com/docs/authentication/signed_request/",
|
15
|
-
# "Invalid Base64 encoding for signature",
|
16
|
-
# "Invalid Base64 Encoding for data",
|
17
|
-
# "Invalid JSON object",
|
18
|
-
# "Invalid Algorithm. Expected: HMAC-SHA256",
|
19
|
-
# "Signatures do not match. #{expected} but was #{computed}"
|
20
|
-
#]
|
21
|
-
|
22
|
-
request.data
|
23
|
-
# => {
|
24
|
-
# "algorithm"=>"HMAC-SHA256",
|
25
|
-
# "expires"=>1308988800,
|
26
|
-
# "issued_at"=>1308985018,
|
27
|
-
# "oauth_token"=>"114998258593813|2.AQBAttRlLVnwqNPZ.3600.1308988800…",
|
28
|
-
# "user"=> {
|
29
|
-
# "country"=>"de",
|
30
|
-
# "locale"=>"en_US",
|
31
|
-
# "age"=>{"min"=>21}
|
32
|
-
# },
|
33
|
-
# "user_id"=>"100000656666199"
|
34
|
-
# }
|
6
|
+
require 'facebook-signed-request'
|
7
|
+
request = Facebook::SignedRequest.new( params[:signed_request], secret )
|
8
|
+
|
9
|
+
request.valid?
|
10
|
+
# => true / false
|
11
|
+
|
12
|
+
request.errors
|
13
|
+
# => [
|
14
|
+
# "Invalid Format. See http://developers.facebook.com/docs/authentication/signed_request/",
|
15
|
+
# "Invalid Base64 encoding for signature",
|
16
|
+
# "Invalid Base64 Encoding for data",
|
17
|
+
# "Invalid JSON object",
|
18
|
+
# "Invalid Algorithm. Expected: HMAC-SHA256",
|
19
|
+
# "Signatures do not match. #{expected} but was #{computed}"
|
20
|
+
#]
|
21
|
+
|
22
|
+
request.data
|
23
|
+
# => {
|
24
|
+
# "algorithm"=>"HMAC-SHA256",
|
25
|
+
# "expires"=>1308988800,
|
26
|
+
# "issued_at"=>1308985018,
|
27
|
+
# "oauth_token"=>"114998258593813|2.AQBAttRlLVnwqNPZ.3600.1308988800…",
|
28
|
+
# "user"=> {
|
29
|
+
# "country"=>"de",
|
30
|
+
# "locale"=>"en_US",
|
31
|
+
# "age"=>{"min"=>21}
|
32
|
+
# },
|
33
|
+
# "user_id"=>"100000656666199"
|
34
|
+
# }
|
35
|
+
|
36
|
+
|
37
|
+
Facebook::SignedRequest.encode_and_sign { :foo => bar }
|
38
|
+
# => g_eE3hoQDPKFusHcc_Tj7k2xxo3mCKsOEXKMViq0pAY=.eyJmb28iOiJiYXIifQ==
|
39
|
+
|
35
40
|
```
|
@@ -3,6 +3,19 @@ module Facebook
|
|
3
3
|
|
4
4
|
class << self
|
5
5
|
attr_accessor :secret
|
6
|
+
|
7
|
+
# Creates a signed_request with correctly padded Base64 encoding.
|
8
|
+
# Mostly useful for testing.
|
9
|
+
def encode_and_sign options
|
10
|
+
encoded_data = Base64.strict_encode64( options.to_json )
|
11
|
+
|
12
|
+
digestor = Digest::HMAC.new( @secret, Digest::SHA256 )
|
13
|
+
signature = digestor.digest( encoded_data )
|
14
|
+
encoded_signature = Base64.strict_encode64( signature )
|
15
|
+
encoded_signature = encoded_signature.gsub('+','_').gsub('/', '_')
|
16
|
+
|
17
|
+
"#{encoded_signature}.#{encoded_data}"
|
18
|
+
end
|
6
19
|
end
|
7
20
|
|
8
21
|
attr_reader :errors, :signature, :data
|
@@ -12,7 +25,24 @@ module Facebook
|
|
12
25
|
@secret = options[:secret] || SignedRequest.secret
|
13
26
|
@errors = []
|
14
27
|
|
28
|
+
check_for_invalid_arguments
|
29
|
+
|
30
|
+
@signature = extract_request_signature
|
31
|
+
@payload = extract_request_payload
|
32
|
+
@data = parse_request_playload
|
33
|
+
|
34
|
+
validate_algorithm
|
35
|
+
validate_signature
|
36
|
+
validate_timestamp if options[:strict] == true
|
37
|
+
end
|
38
|
+
|
39
|
+
def valid?
|
40
|
+
@errors.empty?
|
41
|
+
end
|
15
42
|
|
43
|
+
private
|
44
|
+
|
45
|
+
def check_for_invalid_arguments
|
16
46
|
if @encoded_signature.nil? || @encoded_data.nil?
|
17
47
|
raise ArgumentError, "Invalid Format. See http://developers.facebook.com/docs/authentication/signed_request/"
|
18
48
|
end
|
@@ -24,14 +54,6 @@ module Facebook
|
|
24
54
|
unless @secret.is_a?( String )
|
25
55
|
raise ArgumentError, "Secret should be a String"
|
26
56
|
end
|
27
|
-
|
28
|
-
@signature = extract_request_signature
|
29
|
-
@payload = extract_request_payload
|
30
|
-
@data = parse_request_playload
|
31
|
-
|
32
|
-
validate_algorithm
|
33
|
-
validate_signature
|
34
|
-
validate_timestamp if options[:strict] == true
|
35
57
|
end
|
36
58
|
|
37
59
|
def base64_url_decode( encoded_string )
|
@@ -39,15 +61,9 @@ module Facebook
|
|
39
61
|
Base64.strict_decode64(encoded_string.gsub("-", "+").gsub("_", "/"))
|
40
62
|
end
|
41
63
|
|
42
|
-
def valid?
|
43
|
-
@errors.empty?
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
64
|
def extract_request_signature
|
49
65
|
begin
|
50
|
-
return base64_url_decode(@encoded_signature)
|
66
|
+
return base64_url_decode(@encoded_signature)
|
51
67
|
rescue ArgumentError
|
52
68
|
@errors << "Invalid Base64 encoding for signature"
|
53
69
|
return nil
|
@@ -80,7 +96,7 @@ module Facebook
|
|
80
96
|
|
81
97
|
def validate_signature
|
82
98
|
digestor = Digest::HMAC.new( @secret, Digest::SHA256 )
|
83
|
-
computed_signature = digestor.
|
99
|
+
computed_signature = digestor.digest( @encoded_data )
|
84
100
|
|
85
101
|
if @signature != computed_signature
|
86
102
|
message = "Signatures do not match. " \
|
data/test/signed_request_test.rb
CHANGED
@@ -77,4 +77,22 @@ class SignedRequestTest < Test::Unit::TestCase
|
|
77
77
|
)
|
78
78
|
end
|
79
79
|
|
80
|
+
test "encode and sign request params" do
|
81
|
+
request_1 = Facebook::SignedRequest.new( @valid_request )
|
82
|
+
|
83
|
+
reencoded_request = Facebook::SignedRequest.encode_and_sign(request_1.data)
|
84
|
+
|
85
|
+
sig_1, data_1 = @valid_request.split(".", 2)
|
86
|
+
sig_2, data_2 = reencoded_request.split(".", 2)
|
87
|
+
|
88
|
+
# Simulate invalid raw Base64 from Facebook by removing padding
|
89
|
+
assert_equal sig_1, sig_2.gsub(/=+$/, "")
|
90
|
+
assert_equal data_1, data_2.gsub(/=+$/, "")
|
91
|
+
|
92
|
+
request_2 = Facebook::SignedRequest.new( reencoded_request )
|
93
|
+
|
94
|
+
assert_equal request_1.signature, request_2.signature
|
95
|
+
assert_equal request_1.data, request_2.data
|
96
|
+
end
|
97
|
+
|
80
98
|
end
|