forked from GoogleCloudPlatform/nodejs-docs-samples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move recaptcha demosite to nodejs-docs-samples (GoogleCloudPlatform#2968
) * Move recaptcha demosite to nodejs-docs-samples * add package.json * fix linting * add codeowners
- Loading branch information
1 parent
7ed4181
commit df2ae95
Showing
18 changed files
with
608 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ test/fixtures | |
build/ | ||
docs/ | ||
protos/ | ||
static/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
version: "3" | ||
services: | ||
livereload: | ||
image: demosite-livereload | ||
build: | ||
context: "app" | ||
dockerfile: Dockerfile | ||
args: | ||
- "GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT}" | ||
- "SITE_KEY=${SITE_KEY}" | ||
- "CHECKBOX_SITE_KEY=${CHECKBOX_SITE_KEY}" | ||
command: node index.js | ||
ports: ["8000:8000"] | ||
volumes: | ||
- "./app:/app" | ||
restart: always |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
# Google Cloud reCAPTCHA Enterprise | ||
|
||
Google [Cloud reCAPTCHA Enterprise](https://cloud.google.com/recaptcha-enterprise) helps protect your website from fraudulent activity, spam, and abuse without creating friction. | ||
|
||
# Google Cloud reCAPTCHA Enterprise | ||
|
||
## Prerequisites | ||
|
||
### Google Cloud Project | ||
|
||
Set up a Google Cloud project. | ||
Billing information is **not needed** to deploy this application. | ||
|
||
# One-click deploy | ||
|
||
1. Click the below "Open in Cloud Shell" button. | ||
|
||
<a href="https://shell.cloud.google.com/cloudshell/editor?cloudshell_git_repo=https://github.com/googleapis/nodejs-recaptcha-enterprise&cloudshell_git_branch=demosite"> | ||
<img alt="Open Cloud Shell" src ="http://gstatic.com/cloudssh/images/open-btn.png"></a> | ||
|
||
2. Run | ||
``` | ||
cd samples/demosite/app && sh init.sh | ||
``` | ||
|
||
3. Click on the localhost link in the terminal output. You'll find the deployed application. | ||
|
||
|
||
# Manual Deploy | ||
|
||
### 1. Enable the reCAPTCHA Enterprise API | ||
|
||
You must [enable the Google reCAPTCHA Enterprise API](https://console.cloud.google.com/flows/enableapi?apiid=recaptchaenterprise.googleapis.com) for your project in order to use this application. | ||
|
||
### 2. Create Score key and Checkbox key | ||
|
||
Create a Score key, and a Checkbox key via [Cloud Console.](https://console.cloud.google.com/security/recaptcha) | ||
|
||
### 3. Set Environment Variables | ||
|
||
Open the CloudShell from Cloud Console. | ||
Set your project ID and site keys. | ||
|
||
```angular2html | ||
export GOOGLE_CLOUD_PROJECT="<google-project-id-here>" | ||
export SITE_KEY="<score-key-id-here>" | ||
export CHECKBOX_SITE_KEY="<checkbox-key-id-here>" | ||
``` | ||
|
||
### 4. Clone, Build and Run | ||
|
||
The following instructions will help you prepare your development environment. | ||
|
||
|
||
1. Clone the nodejs-recaptcha-enterprise repository and navigate to ```samples/demosite``` directory. | ||
|
||
``` | ||
cloudshell_open --repo_url "https://github.com/googleapis/nodejs-recaptcha-enterprise.git" --dir "samples/demosite" --page "shell" --force_new_clone --git_branch "demosite" | ||
``` | ||
|
||
2. Run docker-compose | ||
|
||
``` | ||
/usr/local/bin/docker-compose -f $PWD/docker-compose.yaml up --build | ||
``` | ||
|
||
3. Click on the localhost link in the terminal output. You'll find the deployed application. | ||
|
||
## Authentication | ||
|
||
The above _**one-click**_ and _**manual**_ deployment works with the default **compute-engine** service account in the project. | ||
If you want to create a new service account, follow the below steps. | ||
|
||
### 1. Create Service account | ||
|
||
A service account with private key credentials is required to create signed bearer tokens. | ||
|
||
Create | ||
1. [Service account](https://console.cloud.google.com/iam-admin/serviceaccounts/create) | ||
2. [Key](https://cloud.google.com/iam/docs/creating-managing-service-account-keys#iam-service-account-keys-create-console) for the service account | ||
3. Download the key credentials file as JSON. | ||
|
||
### 2. Grant Permissions | ||
|
||
You must ensure that the [user account or service account](https://cloud.google.com/iam/docs/service-accounts#differences_between_a_service_account_and_a_user_account) you used to authorize your gcloud session has the proper permissions to edit reCAPTCHA Enterprise resources for your project. In the Cloud Console under IAM, add the following roles to the project whose service account you're using to test: | ||
|
||
* reCAPTCHA Enterprise Agent | ||
* reCAPTCHA Enterprise Admin | ||
|
||
More information can be found in the [Google reCAPTCHA Enterprise Docs](https://cloud.google.com/recaptcha-enterprise/docs/access-control#rbac_iam). | ||
|
||
### 3. Export the Service account credentials | ||
|
||
```angular2html | ||
export GOOGLE_APPLICATION_CREDENTIALS="<path-to-service-account-credentials-file>" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
FROM node:16-slim | ||
|
||
ARG GOOGLE_CLOUD_PROJECT | ||
ENV GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT} | ||
|
||
ARG SITE_KEY | ||
ENV SITE_KEY=${SITE_KEY} | ||
|
||
ARG CHECKBOX_SITE_KEY | ||
ENV CHECKBOX_SITE_KEY=${CHECKBOX_SITE_KEY} | ||
|
||
# Copy local code to the container image. | ||
ENV APP_HOME /app | ||
WORKDIR $APP_HOME | ||
COPY . ./ | ||
|
||
# Install production dependencies. | ||
RUN npm install |
26 changes: 26 additions & 0 deletions
26
recaptcha/demosite/app/controllers/assessmentController.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
const {createAssessment} = require('../recaptcha/createAssessment'); | ||
|
||
const assessmentController = async (req, res) => { | ||
try { | ||
const assessmentData = await createAssessment( | ||
process.env.GOOGLE_CLOUD_PROJECT, | ||
req.body.sitekey, | ||
req.body.token, | ||
req.body.action | ||
); | ||
|
||
res.json({ | ||
error: null, | ||
data: assessmentData, | ||
}); | ||
} catch (e) { | ||
res.json({ | ||
error: e.toString(), | ||
data: null, | ||
}); | ||
} | ||
}; | ||
|
||
module.exports = { | ||
assessmentController, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
const loginController = (req, res) => { | ||
const context = { | ||
project_id: process.env.GOOGLE_CLOUD_PROJECT, | ||
site_key: process.env.SITE_KEY, | ||
}; | ||
|
||
res.render('login', context); | ||
}; | ||
|
||
module.exports = { | ||
loginController, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
const signupController = (req, res) => { | ||
const context = { | ||
project_id: process.env.GOOGLE_CLOUD_PROJECT, | ||
checkbox_site_key: process.env.CHECKBOX_SITE_KEY, | ||
}; | ||
|
||
res.render('signup', context); | ||
}; | ||
|
||
module.exports = { | ||
signupController, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
const express = require('express'); | ||
const mustacheExpress = require('mustache-express'); | ||
const bodyParser = require('body-parser'); | ||
|
||
const router = require('./routes'); | ||
|
||
const app = express(); | ||
const port = 8000; | ||
|
||
app.use( | ||
bodyParser.urlencoded({ | ||
extended: true, | ||
}) | ||
); | ||
app.use(bodyParser.json()); | ||
|
||
app.engine('html', mustacheExpress()); | ||
app.set('view engine', 'html'); | ||
app.set('views', __dirname + '/templates'); | ||
|
||
app.use('/static', express.static('static')); | ||
app.use('/', router); | ||
|
||
app.listen(port, () => { | ||
console.log(`Recaptcha demosite app listening on port ${port}`); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#!/usr/bin/env bash | ||
|
||
# gcloud command to get the current GOOGLE Project id. | ||
export GOOGLE_CLOUD_PROJECT=$(gcloud config list --format 'value(core.project)' 2>/dev/null) | ||
gcloud config set project "$GOOGLE_CLOUD_PROJECT" | ||
|
||
# Enabling the reCAPTCHA Enterprise API | ||
gcloud services enable recaptchaenterprise.googleapis.com | ||
|
||
# gcloud command to create reCAPTCHA keys. | ||
gcloud alpha recaptcha keys create --display-name=demo-recaptcha-score-key --web --allow-all-domains --integration-type=SCORE 1>/dev/null 2>recaptchascorekeyfile | ||
export SITE_KEY=$(cat recaptchascorekeyfile | sed -n -e 's/.*Created \[\([0-9a-zA-Z_-]\+\)\].*/\1/p') | ||
gcloud alpha recaptcha keys create --display-name=demo-recaptcha-checkbox-key --web --allow-all-domains --integration-type=CHECKBOX 1>/dev/null 2>recaptchacheckboxkeyfile | ||
export CHECKBOX_SITE_KEY=$(cat recaptchacheckboxkeyfile | sed -n -e 's/.*Created \[\([0-9a-zA-Z_-]\+\)\].*/\1/p') | ||
|
||
# Docker compose up | ||
DOCKER_COMPOSE="/usr/local/bin/docker-compose -f $HOME/cloudshell_open/nodejs-recaptcha-enterprise/samples/demosite/docker-compose.yaml up --build" | ||
$DOCKER_COMPOSE | ||
DOCKER_COMPOSE_RESULT=$? | ||
if [[ $DOCKER_COMPOSE_RESULT == *"error"* ]]; | ||
then | ||
echo "Deployment error" | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"name": "recaptcha-demosite", | ||
"description": "", | ||
"version": "1.0.0", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/googleapis/nodejs-recaptcha-enterprise.git" | ||
}, | ||
"license": "MIT", | ||
"dependencies": { | ||
"@google-cloud/recaptcha-enterprise": "^3.0.0", | ||
"body-parser": "^1.20.0", | ||
"express": "^4.18.1", | ||
"mustache-express": "^1.3.2" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
const {RecaptchaEnterpriseServiceClient} = | ||
require('@google-cloud/recaptcha-enterprise').v1; | ||
|
||
const THRESHHOLD_SCORE = 0.5; | ||
|
||
async function createAssessment( | ||
projectId, | ||
recaptchSiteKey, | ||
token, | ||
recaptchaAction | ||
) { | ||
const client = new RecaptchaEnterpriseServiceClient(); | ||
|
||
const [response] = await client.createAssessment({ | ||
parent: `projects/${projectId}`, | ||
assessment: { | ||
event: { | ||
siteKey: recaptchSiteKey, | ||
token, | ||
}, | ||
}, | ||
}); | ||
|
||
// Check if the token is valid. | ||
if (!response.tokenProperties || !response.tokenProperties.valid) { | ||
throw new Error( | ||
`The Create Assessment call failed because the token was invalid for the following reasons: ${response.tokenProperties.invalidReason}` | ||
); | ||
} | ||
|
||
// Check if the expected action was executed. | ||
if (response.tokenProperties.action !== recaptchaAction) { | ||
throw new Error( | ||
'The action attribute in your reCAPTCHA tag does not match the action you are expecting to score. Please check your action attribute !' | ||
); | ||
} | ||
|
||
// Get the risk score and the reason(s) | ||
// For more information on interpreting the assessment, | ||
// see https://cloud.google.com/recaptcha-enterprise/docs/interpret-assessment | ||
for (const reason of response.riskAnalysis.reasons) { | ||
console.log(reason); | ||
} | ||
|
||
console.log( | ||
`The reCAPTCHA score for this token is: ${response.riskAnalysis.score}` | ||
); | ||
|
||
let verdict = 'Human'; | ||
|
||
if (response.riskAnalysis.score < THRESHHOLD_SCORE) { | ||
verdict = 'Not a human'; | ||
} | ||
|
||
return { | ||
score: response.riskAnalysis.score, | ||
verdict, | ||
}; | ||
} | ||
|
||
module.exports = { | ||
createAssessment, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
const express = require('express'); | ||
const router = express.Router(); | ||
|
||
const {loginController} = require('./controllers/loginController'); | ||
const {signupController} = require('./controllers/signupController'); | ||
const {assessmentController} = require('./controllers/assessmentController'); | ||
|
||
router.get('/login', loginController); | ||
router.get('/signup', signupController); | ||
router.post('/create_assessment', assessmentController); | ||
|
||
module.exports = router; |
Oops, something went wrong.