perimeter_x 1.2.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +3 -0
- data/Dockerfile +12 -7
- data/Gemfile.lock +36 -30
- data/Rakefile +1 -0
- data/changelog.md +58 -0
- data/examples/app/controllers/home_controller.rb +1 -1
- data/lib/perimeter_x.rb +195 -71
- data/lib/perimeterx/configuration.rb +74 -22
- data/lib/perimeterx/internal/clients/perimeter_x_activity_client.rb +32 -6
- data/lib/perimeterx/internal/exceptions/px_config_exception.rb +6 -0
- data/lib/perimeterx/internal/first_party/px_first_party.rb +124 -0
- data/lib/perimeterx/internal/{perimeter_x_cookie_v1.rb → payload/perimeter_x_cookie_v1.rb} +1 -1
- data/lib/perimeterx/internal/{perimeter_x_cookie_v3.rb → payload/perimeter_x_cookie_v3.rb} +1 -1
- data/lib/perimeterx/internal/{perimeter_x_cookie.rb → payload/perimeter_x_payload.rb} +12 -4
- data/lib/perimeterx/internal/payload/perimeter_x_token_v1.rb +38 -0
- data/lib/perimeterx/internal/payload/perimeter_x_token_v3.rb +36 -0
- data/lib/perimeterx/internal/perimeter_x_context.rb +74 -32
- data/lib/perimeterx/internal/validators/hash_schema_validator.rb +26 -0
- data/lib/perimeterx/internal/validators/perimeter_x_cookie_validator.rb +29 -21
- data/lib/perimeterx/internal/validators/perimeter_x_s2s_validator.rb +33 -9
- data/lib/perimeterx/utils/px_constants.rb +35 -17
- data/lib/perimeterx/utils/px_http_client.rb +60 -3
- data/lib/perimeterx/utils/px_template_factory.rb +18 -8
- data/lib/perimeterx/utils/templates/block_template.mustache +175 -0
- data/lib/perimeterx/utils/templates/ratelimit.mustache +9 -0
- data/lib/perimeterx/version.rb +1 -1
- data/perimeter_x.gemspec +3 -3
- data/readme.md +115 -31
- metadata +24 -20
- data/lib/perimeterx/internal/validators/perimeter_x_captcha_validator.rb +0 -65
- data/lib/perimeterx/utils/templates/block.mustache +0 -146
- data/lib/perimeterx/utils/templates/captcha.mustache +0 -185
@@ -3,19 +3,25 @@ require 'perimeterx/utils/px_constants'
|
|
3
3
|
module PxModule
|
4
4
|
module PxTemplateFactory
|
5
5
|
|
6
|
-
def self.get_template(px_ctx, px_config)
|
6
|
+
def self.get_template(px_ctx, px_config, px_template_object)
|
7
7
|
logger = px_config[:logger]
|
8
|
-
if (px_config[:challenge_enabled] && px_ctx.context[:block_action] ==
|
9
|
-
logger.debug(
|
8
|
+
if (px_config[:challenge_enabled] && px_ctx.context[:block_action] == 'challenge')
|
9
|
+
logger.debug('PxTemplateFactory[get_template]: px challange triggered')
|
10
10
|
return px_ctx.context[:block_action_data].html_safe
|
11
11
|
end
|
12
12
|
|
13
|
-
logger.debug("PxTemplateFactory[get_template]: rendering template")
|
14
|
-
template_type = px_config[:captcha_enabled] ? PxModule::CAPTCHA_TEMPLATE : BLOCK_TEMPLATE
|
15
|
-
|
16
|
-
Mustache.template_file = "#{File.dirname(__FILE__) }/templates/#{template_type}"
|
17
13
|
view = Mustache.new
|
18
14
|
|
15
|
+
if (px_ctx.context[:block_action] == 'rate_limit')
|
16
|
+
logger.debug('PxTemplateFactory[get_template]: rendering ratelimit template')
|
17
|
+
template_type = RATELIMIT_TEMPLATE
|
18
|
+
else
|
19
|
+
logger.debug('PxTemplateFactory[get_template]: rendering template')
|
20
|
+
template_type = CHALLENGE_TEMPLATE
|
21
|
+
end
|
22
|
+
|
23
|
+
Mustache.template_file = "#{File.dirname(__FILE__) }/templates/#{template_type}#{PxModule::TEMPLATE_EXT}"
|
24
|
+
|
19
25
|
view[PxModule::PROP_APP_ID] = px_config[:app_id]
|
20
26
|
view[PxModule::PROP_REF_ID] = px_ctx.context[:uuid]
|
21
27
|
view[PxModule::PROP_VID] = px_ctx.context[:vid]
|
@@ -23,9 +29,13 @@ module PxModule
|
|
23
29
|
view[PxModule::PROP_CUSTOM_LOGO] = px_config[:custom_logo]
|
24
30
|
view[PxModule::PROP_CSS_REF] = px_config[:css_ref]
|
25
31
|
view[PxModule::PROP_JS_REF] = px_config[:js_ref]
|
32
|
+
view[PxModule::PROP_HOST_URL] = px_template_object[:host_url]
|
26
33
|
view[PxModule::PROP_LOGO_VISIBILITY] = px_config[:custom_logo] ? PxModule::VISIBLE : PxModule::HIDDEN
|
34
|
+
view[PxModule::PROP_BLOCK_SCRIPT] = px_template_object[:block_script]
|
35
|
+
view[PxModule::PROP_JS_CLIENT_SRC] = px_template_object[:js_client_src]
|
36
|
+
view[PxModule::PROP_FIRST_PARTY_ENABLED] = px_ctx.context[:first_party_enabled]
|
27
37
|
|
28
38
|
return view.render.html_safe
|
29
39
|
end
|
30
40
|
end #end class
|
31
|
-
end #end module
|
41
|
+
end #end module
|
@@ -0,0 +1,175 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
6
|
+
<title>Access to this page has been denied.</title>
|
7
|
+
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300" rel="stylesheet">
|
8
|
+
<style>
|
9
|
+
html, body {
|
10
|
+
margin: 0;
|
11
|
+
padding: 0;
|
12
|
+
font-family: 'Open Sans', sans-serif;
|
13
|
+
color: #000;
|
14
|
+
}
|
15
|
+
|
16
|
+
a {
|
17
|
+
color: #c5c5c5;
|
18
|
+
text-decoration: none;
|
19
|
+
}
|
20
|
+
|
21
|
+
.container {
|
22
|
+
align-items: center;
|
23
|
+
display: flex;
|
24
|
+
flex: 1;
|
25
|
+
justify-content: space-between;
|
26
|
+
flex-direction: column;
|
27
|
+
height: 100%;
|
28
|
+
}
|
29
|
+
|
30
|
+
.container > div {
|
31
|
+
width: 100%;
|
32
|
+
display: flex;
|
33
|
+
justify-content: center;
|
34
|
+
}
|
35
|
+
|
36
|
+
.container > div > div {
|
37
|
+
display: flex;
|
38
|
+
width: 80%;
|
39
|
+
}
|
40
|
+
|
41
|
+
.customer-logo-wrapper {
|
42
|
+
padding-top: 2rem;
|
43
|
+
flex-grow: 0;
|
44
|
+
background-color: #fff;
|
45
|
+
visibility: {{logoVisibility}};
|
46
|
+
}
|
47
|
+
|
48
|
+
.customer-logo {
|
49
|
+
border-bottom: 1px solid #000;
|
50
|
+
}
|
51
|
+
|
52
|
+
.customer-logo > img {
|
53
|
+
padding-bottom: 1rem;
|
54
|
+
max-height: 50px;
|
55
|
+
max-width: 100%;
|
56
|
+
}
|
57
|
+
|
58
|
+
.page-title-wrapper {
|
59
|
+
flex-grow: 2;
|
60
|
+
}
|
61
|
+
|
62
|
+
.page-title {
|
63
|
+
flex-direction: column-reverse;
|
64
|
+
}
|
65
|
+
|
66
|
+
.content-wrapper {
|
67
|
+
flex-grow: 5;
|
68
|
+
}
|
69
|
+
|
70
|
+
.content {
|
71
|
+
flex-direction: column;
|
72
|
+
}
|
73
|
+
|
74
|
+
.page-footer-wrapper {
|
75
|
+
align-items: center;
|
76
|
+
flex-grow: 0.2;
|
77
|
+
background-color: #000;
|
78
|
+
color: #c5c5c5;
|
79
|
+
font-size: 70%;
|
80
|
+
}
|
81
|
+
|
82
|
+
@media (min-width: 768px) {
|
83
|
+
html, body {
|
84
|
+
height: 100%;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
</style>
|
88
|
+
<!-- Custom CSS -->
|
89
|
+
{{#cssRef}}
|
90
|
+
<link rel="stylesheet" type="text/css" href="{{{cssRef}}}"/>
|
91
|
+
{{/cssRef}}
|
92
|
+
</head>
|
93
|
+
|
94
|
+
<body>
|
95
|
+
<section class="container">
|
96
|
+
<div class="customer-logo-wrapper">
|
97
|
+
<div class="customer-logo">
|
98
|
+
<img src="{{customLogo}}" alt="Logo"/>
|
99
|
+
</div>
|
100
|
+
</div>
|
101
|
+
<div class="page-title-wrapper">
|
102
|
+
<div class="page-title">
|
103
|
+
<h1>Please verify you are a human</h1>
|
104
|
+
</div>
|
105
|
+
</div>
|
106
|
+
<div class="content-wrapper">
|
107
|
+
<div class="content">
|
108
|
+
|
109
|
+
<div id="px-captcha">
|
110
|
+
</div>
|
111
|
+
<p>
|
112
|
+
Access to this page has been denied because we believe you are using automation tools to browse the
|
113
|
+
website.
|
114
|
+
</p>
|
115
|
+
<p>
|
116
|
+
This may happen as a result of the following:
|
117
|
+
</p>
|
118
|
+
<ul>
|
119
|
+
<li>
|
120
|
+
Javascript is disabled or blocked by an extension (ad blockers for example)
|
121
|
+
</li>
|
122
|
+
<li>
|
123
|
+
Your browser does not support cookies
|
124
|
+
</li>
|
125
|
+
</ul>
|
126
|
+
<p>
|
127
|
+
Please make sure that Javascript and cookies are enabled on your browser and that you are not blocking
|
128
|
+
them from loading.
|
129
|
+
</p>
|
130
|
+
<p>
|
131
|
+
Reference ID: #{{refId}}
|
132
|
+
</p>
|
133
|
+
</div>
|
134
|
+
</div>
|
135
|
+
<div class="page-footer-wrapper">
|
136
|
+
<div class="page-footer">
|
137
|
+
<p>
|
138
|
+
Powered by
|
139
|
+
<a href="https://www.perimeterx.com/whywasiblocked">PerimeterX</a>
|
140
|
+
, Inc.
|
141
|
+
</p>
|
142
|
+
</div>
|
143
|
+
</div>
|
144
|
+
</section>
|
145
|
+
<!-- Px -->
|
146
|
+
<script>
|
147
|
+
window._pxAppId = '{{appId}}';
|
148
|
+
window._pxJsClientSrc = '{{{jsClientSrc}}}';
|
149
|
+
window._pxFirstPartyEnabled = {{firstPartyEnabled}};
|
150
|
+
window._pxVid = '{{vid}}';
|
151
|
+
window._pxUuid = '{{uuid}}';
|
152
|
+
window._pxHostUrl = '{{{hostUrl}}}';
|
153
|
+
</script>
|
154
|
+
<script>
|
155
|
+
var s = document.createElement('script');
|
156
|
+
s.src = '{{{blockScript}}}';
|
157
|
+
var p = document.getElementsByTagName('head')[0];
|
158
|
+
p.insertBefore(s, null);
|
159
|
+
if ({{firstPartyEnabled}}) {
|
160
|
+
s.onerror = function () {
|
161
|
+
s = document.createElement('script');
|
162
|
+
var suffixIndex = '{{{blockScript}}}'.indexOf('captcha.js');
|
163
|
+
var temperedBlockScript = '{{{blockScript}}}'.substring(suffixIndex);
|
164
|
+
s.src = '//captcha.px-cdn.net/{{appId}}/' + temperedBlockScript;
|
165
|
+
p.parentNode.insertBefore(s, p);
|
166
|
+
};
|
167
|
+
}
|
168
|
+
</script>
|
169
|
+
|
170
|
+
<!-- Custom Script -->
|
171
|
+
{{#jsRef}}
|
172
|
+
<script src="{{{jsRef}}}"></script>
|
173
|
+
{{/jsRef}}
|
174
|
+
</body>
|
175
|
+
</html>
|
data/lib/perimeterx/version.rb
CHANGED
data/perimeter_x.gemspec
CHANGED
@@ -22,8 +22,8 @@ Gem::Specification.new do |gem|
|
|
22
22
|
gem.bindir = "exe"
|
23
23
|
gem.executables = gem.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
24
|
gem.require_paths = ["lib"]
|
25
|
-
gem.add_development_dependency "bundler", "
|
26
|
-
gem.add_development_dependency "rake", "
|
25
|
+
gem.add_development_dependency "bundler", ">= 2.1"
|
26
|
+
gem.add_development_dependency "rake", ">= 12.3"
|
27
27
|
|
28
28
|
gem.extra_rdoc_files = ["readme.md", "changelog.md"]
|
29
29
|
gem.rdoc_options = ["--line-numbers", "--inline-source", "--title", "PerimeterX"]
|
@@ -33,7 +33,7 @@ Gem::Specification.new do |gem|
|
|
33
33
|
gem.add_dependency('concurrent-ruby', '~> 1.0', '>= 1.0.5')
|
34
34
|
gem.add_dependency('typhoeus', '~> 1.1', '>= 1.1.2')
|
35
35
|
gem.add_dependency('mustache', '~> 1.0', '>= 1.0.3')
|
36
|
-
gem.add_dependency('activesupport', '>=
|
36
|
+
gem.add_dependency('activesupport', '>= 5.2.4.3')
|
37
37
|
|
38
38
|
gem.add_development_dependency 'rspec', '~> 3.0'
|
39
39
|
gem.add_development_dependency 'mocha', '~> 1.2', '>= 1.2.1'
|
data/readme.md
CHANGED
@@ -1,20 +1,26 @@
|
|
1
|
-
![
|
1
|
+
[![Build Status](https://travis-ci.org/PerimeterX/perimeterx-ruby-sdk.svg?branch=master)](https://travis-ci.org/PerimeterX/perimeterx-ruby-sdk)
|
2
|
+
|
3
|
+
![image](https://storage.googleapis.com/perimeterx-logos/primary_logo_red_cropped.png)
|
2
4
|
#
|
3
5
|
[PerimeterX](http://www.perimeterx.com) Ruby SDK
|
4
6
|
=============================================================
|
5
7
|
|
8
|
+
> Latest stable version: [v2.1.0](https://rubygems.org/gems/perimeter_x)
|
9
|
+
|
6
10
|
Table of Contents
|
7
11
|
-----------------
|
8
|
-
|
12
|
+
**[Usage](#usage)**
|
9
13
|
* [Dependencies](#dependencies)
|
10
14
|
* [Installation](#installation)
|
11
15
|
* [Basic Usage Example](#basic-usage)
|
12
|
-
|
16
|
+
|
17
|
+
**[Configuration](#configuration)**
|
13
18
|
* [Configuring Required Parameters](#requireied-params)
|
14
19
|
* [Blocking Score](#blocking-score)
|
20
|
+
* [Custom Verification Action](#custom-verification-action)
|
15
21
|
* [Custom Block Page](#custom-block-page)
|
16
|
-
* [Custom Block Action](#custom-block-action)
|
17
22
|
* [Enable/Disable Captcha](#captcha-support)
|
23
|
+
* [Select Captcha Provider](#captcha-provider)
|
18
24
|
* [Extracting Real IP Address](#real-ip)
|
19
25
|
* [Custom URI](#custom-uri)
|
20
26
|
* [Filter Sensitive Headers](#sensitive-headers)
|
@@ -23,7 +29,11 @@ Table of Contents
|
|
23
29
|
* [Additional Page Activity Handler](#additional-page-activity-handler)
|
24
30
|
* [Monitor Only](#logging)
|
25
31
|
* [Debug Mode](#debug-mode)
|
26
|
-
|
32
|
+
* [Whitelist Routes](#whitelist-routes)
|
33
|
+
* [Update Configuration on Runtime](#update-config)
|
34
|
+
* [First Party](#first-party)
|
35
|
+
|
36
|
+
**[Contributing](#contributing)**
|
27
37
|
|
28
38
|
<a name="Usage"></a>
|
29
39
|
<a name="dependencies"></a> Dependencies
|
@@ -61,7 +71,7 @@ On the Rails controller include the PerimeterX SDK via the before_action and cal
|
|
61
71
|
class HomeController < ApplicationController
|
62
72
|
include PxModule
|
63
73
|
|
64
|
-
|
74
|
+
before_action :px_verify_request
|
65
75
|
...
|
66
76
|
...
|
67
77
|
end
|
@@ -80,7 +90,7 @@ All parameters are obtainable via the PerimeterX Portal. (Applications and Polic
|
|
80
90
|
|
81
91
|
<a name="blocking-score"></a>**Changing the Minimum Score for Blocking**
|
82
92
|
|
83
|
-
>Note: Default blocking value:
|
93
|
+
>Note: Default blocking value: 100
|
84
94
|
|
85
95
|
```ruby
|
86
96
|
params = {
|
@@ -90,69 +100,71 @@ params = {
|
|
90
100
|
}
|
91
101
|
```
|
92
102
|
|
103
|
+
<a name="custom-verification-action"></a>**Custom Verification Handler**
|
93
104
|
|
105
|
+
> Note: This handler replaces the now deprecated `custom_block_handler`.
|
94
106
|
|
95
|
-
|
107
|
+
A custom verification handler is being executed inside `px_verify_request` instead of the the default behavior and allows a user to use a custom action based on the risk score returned by PerimeterX.
|
96
108
|
|
97
|
-
|
109
|
+
When implemented, this method receives a hash variable as input which represents data from the PerimeterX context of the request (px_ctx).
|
98
110
|
|
99
|
-
|
111
|
+
- `px_ctx.context[:score]` - contains the risk score
|
112
|
+
- `px_ctx.context[:uuid]` - contains the request UUID
|
113
|
+
- `px_ctx.context[:verified]` - contains indication whether the request passed verification or was blocked (inspect `px_ctx.context[:block_reason]` for block reason)
|
100
114
|
|
101
|
-
|
102
|
-
- `px_ctx[:uuid] ` contains the request UUID
|
103
|
-
|
104
|
-
>> Note: to determine whether to return a captcha/block page (HTML) or block JSON payload a reference key on the context will be available: ```px_ctx.context[:format]```
|
115
|
+
> Note: to determine whether to return a captcha/block page (HTML) or block JSON payload a reference key on the context will be available: ```px_ctx.context[:format]```
|
105
116
|
|
106
117
|
To replace the default verification behavior, add the configuration a lambda member as shown in the example below.
|
107
118
|
|
108
|
-
The method must return boolen value.
|
109
|
-
|
110
119
|
```ruby
|
111
120
|
params = {
|
112
121
|
:app_id => <APP_ID>,
|
113
122
|
:auth_token => <AUTH_TOKEN>,
|
114
|
-
:
|
123
|
+
:custom_verification_handler => -> (px_ctx) {
|
115
124
|
if px_ctx.context[:score] >= 60
|
116
|
-
|
125
|
+
# take your action and render an html page or JSON with applicable status code.
|
126
|
+
render json: { :score => px_ctx.context[:score] }
|
117
127
|
end
|
118
|
-
return true
|
119
128
|
}
|
120
129
|
}
|
121
130
|
```
|
122
131
|
|
132
|
+
> Note: Unlike previous versions, the method no longer needs to return a boolean value.
|
133
|
+
|
123
134
|
**Example**
|
124
|
-
|
135
|
+
#### Serving a Custom HTML Page ####
|
125
136
|
```ruby
|
126
137
|
|
127
|
-
params
|
128
|
-
|
138
|
+
params = {
|
139
|
+
:app_id => <APP_ID>,
|
140
|
+
:auth_token => <AUTH_TOKEN>,
|
141
|
+
...
|
142
|
+
:custom_verification_handler => -> (px_ctx) {
|
129
143
|
block_score = px_ctx.context[:score];
|
130
|
-
|
144
|
+
client_uuid = px_ctx.context[:uuid];
|
131
145
|
full_url = px_ctx.context[:full_url];
|
132
146
|
|
133
147
|
html = "<html>
|
134
148
|
<body>
|
135
149
|
<div>Access to #{full_url} has been blocked.</div>
|
136
|
-
<div>Block reference - #{
|
150
|
+
<div>Block reference - #{client_uuid} </div>
|
137
151
|
<div>Block score - #{block_score} </div>
|
138
152
|
</body>
|
139
153
|
</html>".html_safe
|
140
154
|
response.headers["Content-Type"] = "text/html"
|
141
155
|
response.status = 403
|
142
156
|
render :html => html
|
143
|
-
|
144
|
-
}
|
145
|
-
|
146
|
-
PxModule.configure(params)
|
157
|
+
}
|
158
|
+
}
|
147
159
|
```
|
148
160
|
|
149
|
-
<a name="real-ip"></a>**
|
161
|
+
<a name="real-ip"></a>**Custom User IP**
|
150
162
|
|
151
163
|
> Note: IP extraction, according to your network setup, is very important. It is common to have a load balancer/proxy on top of your applications, in which case the PerimeterX module will send the system's internal IP as the user's. In order to properly perform processing and detection on server-to-server calls, PerimeterX module needs the real user's IP.
|
152
164
|
|
153
165
|
By default the clients IP is taken from the ``REMOTE_ADDR`` header, in case the user decides to use different header or custom function that extract the header the following key should be added to the configuration
|
154
166
|
|
155
|
-
***
|
167
|
+
***Custom header***
|
156
168
|
```ruby
|
157
169
|
configuration = {
|
158
170
|
"app_id" => <APP_ID>,
|
@@ -160,7 +172,7 @@ configuration = {
|
|
160
172
|
"custom_user_ip" => <HTTP_HEADER_NAME>,
|
161
173
|
```
|
162
174
|
|
163
|
-
***
|
175
|
+
***Custom Function***
|
164
176
|
> Note: the function receive as a first parameter the controller request and must return the ip at the end as string
|
165
177
|
|
166
178
|
```ruby
|
@@ -222,6 +234,17 @@ By enabling CAPTCHA support, a CAPTCHA will be served as part of the block page,
|
|
222
234
|
params[:captcha_enabled] = false
|
223
235
|
```
|
224
236
|
|
237
|
+
<a name="captcha-provider"></a>**Select CAPTCHA Provider**
|
238
|
+
|
239
|
+
The CAPTCHA part of the block page can use one of the following:
|
240
|
+
* [reCAPTCHA](https://www.google.com/recaptcha)
|
241
|
+
|
242
|
+
Default: 'reCaptcha'
|
243
|
+
|
244
|
+
```ruby
|
245
|
+
captchaProvider = "reCaptcha"
|
246
|
+
```
|
247
|
+
|
225
248
|
<a name="custom-uri"></a>**Custom URI**
|
226
249
|
|
227
250
|
Default: 'REQUEST_URI'
|
@@ -285,6 +308,67 @@ Enables debug logging mode to STDOUT
|
|
285
308
|
params[:debug] = true
|
286
309
|
```
|
287
310
|
|
311
|
+
<a name="whitelist-routes"></a>**Whitelist Routes**
|
312
|
+
Default: []
|
313
|
+
|
314
|
+
An array of route prefixes and/or regular expressions that are always whitelisted and not validated by PerimeterX.
|
315
|
+
A string value of a path will be treated as a prefix.
|
316
|
+
A regexp value of a path will be treated as is.
|
317
|
+
|
318
|
+
```ruby
|
319
|
+
params[:whitelist_routes] = ["/example", /\A\/example\z/]
|
320
|
+
```
|
321
|
+
|
322
|
+
<a name="update-config"></a>**Update Configuration on Runtime**
|
323
|
+
|
324
|
+
As mentioned before, PerimeterX Module should be configured in `<rails_app>/config/initializers/perimeterx.rb`.
|
325
|
+
However, it is possible to override configuration options on each request.
|
326
|
+
To do so, send the configuration options as an argument when calling to `px_verify_request` as described in the following example.
|
327
|
+
Notice that in case of an invalid argument, the module will raise an error. Therefore, when using this feature, make sure to wrap the call to `px_verify_request` with begin and rescue. It is highly recommended to log the error message to follow such errors.
|
328
|
+
|
329
|
+
```ruby
|
330
|
+
class HomeController < ApplicationController
|
331
|
+
include PxModule
|
332
|
+
|
333
|
+
|
334
|
+
before_action do call_perimeterx_verify_request end
|
335
|
+
|
336
|
+
def call_perimeterx_verify_request
|
337
|
+
params = {
|
338
|
+
:blocking_score => 70,
|
339
|
+
:module_mode => 2
|
340
|
+
}
|
341
|
+
begin
|
342
|
+
px_verify_request(params)
|
343
|
+
rescue StandardError => e
|
344
|
+
# $stdout.write(e.message)
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
end
|
349
|
+
```
|
350
|
+
|
351
|
+
<a name="first-party"></a>**First Party**
|
352
|
+
To enable first party on your enforcer, add the following routes to your `config/routes.rb` file:
|
353
|
+
|
354
|
+
```ruby
|
355
|
+
get '/:appid_postfix/init.js', to: 'home#index', constraints: { appid_postfix: /XXXXXXXX/ }
|
356
|
+
get '/:appid_postfix/captcha/:all', to: 'home#index', constraints: { appid_postfix: /XXXXXXXX/, all:/.*/ }
|
357
|
+
post '/:appid_postfix/xhr/:all', to: 'home#index', constraints: { appid_postfix: /XXXXXXXX/, all:/.*/ }
|
358
|
+
```
|
359
|
+
|
360
|
+
Notice that all occurences of `XXXXXXXX` should be replaced with your px_app_id without the "PX" prefix. For example, if your px_app_id is `PX2H4seK9L`, reeplace `XXXXXXXX` with `2H4seK9L`.
|
361
|
+
In case you are using more than one px_app_id, provide all of them with a `|` sign between them. For example: 2H4seK9L|9bMs6K94|Lc5kPMNx
|
362
|
+
|
363
|
+
|
364
|
+
First Party configuration:
|
365
|
+
Default: true
|
366
|
+
|
367
|
+
```ruby
|
368
|
+
params[:first_party_enabled] = false
|
369
|
+
```
|
370
|
+
|
371
|
+
|
288
372
|
<a name="contributing"></a># Contributing #
|
289
373
|
------------------------------
|
290
374
|
The following steps are welcome when contributing to our project.
|