Web

緣由

發文或登入時阻擋機器人 (bot)

版本

  1. v3:分數驗證 (Google 會回覆 0~1 之間的分數)

  2. v2:問題驗證 (要回答 Google 問的圖形之類的問題)
    (1) checkbox:勾選 “我不是機器人” 來驗證要求
    (2) invisible:藏在背景,有疑慮才需驗證

備註:目前 ios 只支援 v2 invisible

步驟

申請 reCaptcha key

這裡以 v2 checkbox 為例
先到 這裏 申請
介面如下:

標籤填名稱
類型勾選 “v2” -> “我不是機器人核取方塊”
網域填寫網址或是 app 的 package name,如果是本地端測試也要填個 localhost127.0.0.1

複製 key

網站金鑰 (site key) 是前端用
密鑰 (secret) 則是後端用 (請保存好,小心外洩)

前端範例

以金鑰 = 6Lc3scAUAAAAAKtFexJH_-IBcgXj94IEyEORgLnm 為例

client.html 範例

在這邊模擬一個登入畫面

  1. 第 14 行;html 內放一個 hidden tag recaptcha-token 來存 token

  2. 第 17 行;html 內放一個 div tag recaptcha 來放 checkbox

  3. 第 19 ~ 20 行;底下再 load https://www.google.com/recaptcha/api.js./recaptcha.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html lang="en">

<head>
<title>reCAPTCHA V2 checkbox Test</title>
</head>

<body>
<form id="myForm" action="http://localhost:7777/login" method="post">
<label for="account">Account:</label>
<input name="account" required><br />
<label for="password">Password:</label>
<input name="password" type="password" required><br />
<input id="recaptcha-token" name="token" type="hidden" value="">
<button>登入</button>
</form>
<div id="recaptcha"></div>
<!--js-->
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
<script src="./recaptcha.js"></script>
</body>

</html>

recaptcha.js 範例

  1. 第 9 ~ 13 行;recaptcha 功能綁定到 recaptcha div 上

  2. 第 16 ~ 18 行;render 的 callback 把拿到的 token 存回 recaptcha-token

  3. 之後就能利用 form post 把 account、password、token 一起傳給後端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const myForm = document.getElementById("myForm");
const recaptcha = document.querySelector("#recaptcha");
const recaptchaToken = document.querySelector("#recaptcha-token");

// v2 checkbox key
const siteKey = "6Lc3scAUAAAAAKtFexJH_-IBcgXj94IEyEORgLnm";

function onloadCallback() {
window.grecaptcha.render(recaptcha, {
sitekey: siteKey,
size: "checkbox",
callback: updateToken
});
}

function updateToken(token) {
recaptchaToken.value = token;
}

Android 範例

請參考 這裏

iOS 範例

請參考 這裏

後端範例

這邊使用 express 來開一個後端 Server,axios 來發 request
要特別注意的是 siteverify API 雖然 method 是 POST
但只能用 querystring 來傳遞額外參數

  1. 第 12 行;接收 token 等參數

  2. 第 18 行;把 __your_secret__ 替換成申請的密鑰

  3. 第 15 ~ 21 行;把 secret、token 當參數 request siteverify API

  4. 第 22 ~ 31 行;收到 siteverify API 的 Response,如果 success 是 true,代表驗證成功,第 24 行以後可作後續的 login 行為

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const axios = require("axios");
const express = require("express");
const bodyParser = require("body-parser");
const querystring = require("querystring");

const app = express();

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.post("/login", async (req, res) => {
const { account, password, token } = req.body;

const { status, result } = await axios
.post(
"https://www.google.com/recaptcha/api/siteverify",
querystring.stringify({
secret: "__your_secret__",
response: token
})
)
.then(result => {
const { success, "error-codes": errorCode } = result.data;
if (success === true) {
// login code...
return { status: 200, result: { msg: "Success" } };
} else {
// verify error case
return { status: 404, result: { errorCode } };
}
});
res.status(status).json(result);
});

app.listen(7777);

成品畫面

如有設定成功的話會如以下畫面:

備註:如果 “我不是機器人” 區塊沒出來的話可去 控制台 確認有沒有把網域加進去

Error Code

如果 response 內的 success === false 時
error-codes 會有錯誤訊息的 code
詳細可參考 這裡

資料來源

  1. Developer’s Guide
  2. reCAPTCHA v2 Invisible,不用再把「我不是機器人」列入頁面設計考量
  3. reCaptcha Form with an Amazon AWS™ serverless backend environment
  4. How to Setup a Serverless Contact Form with AWS Lambda, reCAPTCHA and Storyblok
  5. 簡介:給人類方便給bot困難
  6. 如何整合“No CAPTCHA reCAPTCHA”(驗證碼)到你的網站裡

緣由

上一篇 網誌建完之後只有基本的樣式
可能有額外需求要設定,固寫在此篇

備份

hexo-cli 只上傳轉換後的 html 檔
如需要備份 markdown 原始檔與專案設定檔可安裝 hexo-git-backup

  1. 安裝

    1
    $ npm i hexo-git-backup

  2. _config.yml 增加設定:

    1
    2
    3
    4
    backup:
    type: git
    repository:
    github: http://github.com/yourname/yourname.github.io.git,branchname

    這裡的 “yourname” 改成你的 github 帳號
    “branchname” 改成備份的 branch name

  3. 設定完就能下指令備份:

    1
    $ hexo b

壓縮靜態網頁

這邊是用 hexo-yam
直接下指令安裝:

1
$ npm install hexo-yam

安裝完預設就會會啟動了,無須另外設定
如需特調細項可再去 _config.yml 做額外設定

分享功能

進入文章後預設底下會有 error 區塊

我們可以參考專案的 /themes/minos/_config.yml 檔案

minos 的分享預設是用 sharethis

  1. 註冊一個帳號

  2. 以 Domain 新增一筆 Property

  3. 選擇一個想使用的樣式,裡面可再做細項設定

  4. 設定好樣式後點選 “Get the Code”

  5. 複製 js code 的 “src” 的部分 (只要網址就好,不用整個 code)

  6. 網址複製到 /themes/minos/_config.yml 的 “share” 的 “install_url”

  7. 專案 deploy 後點選 “Verify Manually”

  8. 把線上站隨便一篇的網址複製過來進行檢測,檢測成功的話紅色區快會消失

  9. 設置成功的話網誌倒數第二塊會出現分享功能

留言功能

minos 的分享預設是用 disqus

  1. 註冊一個帳號

  2. 新增一個 Site

  3. 新增完後點選 “general” 並複製 “Shortname” 欄位

  4. short name 貼到 /themes/minos/_config.yml 的 “comment” 的 “install_url”

  5. 設置成功的話網誌最下方會出現留言功能

追蹤

這邊是用 Google Analytics

  1. Google 帳號登入

  2. 新增網站

  3. 追蹤碼貼到 /themes/minos/_config.yml 的 “Other plugins and their settings.” 的 “google-analytics” 的 “tracking_id”

調整網站 Menu

Menu 是這個:

可到 /themes/minos/_config.yml 來做調整:

更換 DNS Server

Google Domains 的功能滿陽春的
因此換到 CloudFlare 多了一些分析功能 (有些要付費)

  1. 註冊帳號

  2. 點選 “Add a Site”

  3. 填入 Blog 網址後點選 “Add site”

  4. 等待 CloudFlare 掃描
    基本上 “電子郵件轉寄” 與大部分 “自訂資源記錄” 的設定都會完整複製過去
    有缺少再補即可 (如 VPS 設定沒有複製過去)

  5. 複製 CloudFlare 提供的 DNS Server

  6. 回到 Google Domains -> DNS -> 名稱伺服器
    選擇 “使用自訂名稱伺服器” 並填入剛複製的 DNS Server 網址

更新 Blog 後刪除 Cache

使用 CloudFlare 後,網站就會有了 Cache 功能
如果你更新網站想馬上看線上站的結果
可到 Caching -> Purge everything,點選 “purge everything”

緣由

有時會有學習或工作用的電腦沒有實體 IP (在內網),但又需要連線到那台電腦
這時可以利用 Reverse SSH Tunneling 機制來連線

所需環境與工具

  1. 一台有實體 IP 的伺服器
    如沒有可購買 VPS,如 Linode,最便宜方案一個月 5 美金

  2. OpenSSH
    Linux 有內建
    Windows 10 可從 設定 來啟用

  3. autossh (選用)

範例環境介紹

MachineAccountIPPortInfo
ServerAuserA192.168.0.10122Private IP (內網;目標電腦)
ServerBuserB149.12.34.561234Public IP (外網;中繼電腦)
ClientuserUser (你的電腦)

你想從 Client 這台電腦連到工作用的電腦 ServerA,預期連線流程大概如下:

1
Client -----> ServerB --| 防火牆 |--> ServerA

又因為 ServerA 沒有實體 IP,ServerB 無法直接連到 ServerA
可以利用 Reverse SSH Tunneling 機制
ServerA 先連到 ServerB 建立隧道:

1
ServerB <==| 防火牆 |== ServerA

ServerB 再依靠該隧道 port 1234 連到 ServerA:

1
ServerB ≡≡| 防火牆 |≡≡> ServerA

免密碼登入

連線時會需要帳密
如果想免密碼登入可執行此步驟把 public key 傳給對方

1
2
[userA@ServerA] $ ssh-keygen # 產一對 key
[userA@ServerA] $ ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected] # 把 public key 送給對方

目標電腦設定

Server A 開一個隧道到 ServerB

1
[userA@ServerA] $ ssh -NfR 1234:localhost:22 [email protected]    # f 代表背景執行

連到目標電腦

方法 1

Client 先連到 ServerB

1
[user@Client] $ ssh [email protected]

因為前面 ServerA 已經開一個隧道過來
所以 ServerB 就能連到 ServerA 了

1
[userB@ServerB] $ ssh userA@localhost -p 1234

方法 2

使用一個指令來達成 “先連到 ServerB 再下指令連到 ServerA”

1
[user@Client] $ ssh -t [email protected] "ssh userA@localhost -p 1234"

方法 3

直接以 ServerB 當跳板連到 ServerA

1
[user@Client] $ ssh -o "ProxyJump [email protected]" userA@localhost -p 1234

或是

1
[user@Client] $ ssh -J [email protected] userA@localhost -p 1234

方法 4 (推薦)

原本 ServerB 只能透過 localhost 來連到 ServerA
此方法是 Server A 設定時加上 “-g” 這個 option
(允許遠端主機連到本地的轉發 port)
讓 Client 透過 ServerB 的 port 直連到 ServerA

  1. 仿照前面 開隧道 時 ServerA 改下指令:

    1
    [userA@ServerA] $ ssh -gNfR 0.0.0.0:1234:localhost:22 [email protected]

  2. ServerB 要設定 GatewayPorts:

    1
    [userB@ServerB] $ vim /etc/sshd_config

    裡面的 “GatewayPorts” 改成 yes (預設是 no) 並重開 sshd 服務:

    1
    [userB@ServerB] $ systemctl restart sshd

  3. 去防火牆把中繼 port 設為允許 (ssh 是 tcp)

    1
    [userB@ServerB] $ iptables -A INPUT -i eth0 -p tcp --dport 1234 -j ACCEPT

    把 iptables 設定存起來

    1
    [userB@ServerB] $ iptables-save

  4. Client 下指令 (記得這邊 account 要填 ServerB 的登入帳號)

    1
    [user@Client] $ ssh [email protected] -p 1234

其他相關指令

查看網路狀態

1
$ netstat -a|less       # less 代表翻頁檢視

登出

登入後如果想登出可執行以下指令:

1
$ exit

關閉 SSH Tunnel

以下為列出 process 資訊的指令:

1
2
3
$ ps -ef|grep 1234      # 列出使用 1234 port 的 process
$ ps aux|less # 列出正在進行的 process
$ ps aux|grep ssh # 列出 ssh 相關的 process

找到 process id 後就能刪除:

1
$ kill -9 [process id]  # 刪除指定 process id 的 process

斷線時自動重連

有連線就有可能斷線
這時候 serverA 就可以用 autossh 來建立 Reverse SSH Tunneling:

1
2
# -M 後面是監聽用的 port, 不可跟 localhost 前的 port 一樣, 設 0 代表強制關閉
[userA@ServerA] $ autossh -M 0 -o ServerAliveInterval=10 -o ExitOnForwardFailure=yes -gNfR 1234:localhost:22 [email protected]

或是可使用 cmd-boost 這個工具

如果要關閉 autossh:

1
$ pkill -3 autossh

參考資料

  1. Reverse SSH Tunnel實際運用,搭配auotssh永不斷線,putty建立反向tunnel
  2. 實現免密碼 ssh 登入遠端主機
  3. 25 Best SSH Commands / Tricks
  4. ssh通过代理登录远程主机及穿越跳板机
  5. What Is Reverse SSH Tunneling? (and How to Use It)
  6. SSH反向代理使用心得
  7. Reverse port tunnelling
  8. SSH COMMAND

緣由

原本想要一個較個人風的 email
參照 網路上 得知 Google Domains 不只提供 domain 同時提供指定 email 轉寄的功能
就直接照 這篇 來購買一個 domain
Google 相較其他網域商,雖然價格貴一點點,但每年價格都很一致
不像有些強打第一年優惠但第二年以後價格快翻倍跳反而比 Google 的還貴
在這邊最便宜的一年 9 USD,商用字詞的約 1X USD 即可入手 (我是買 12 USD 的)

設定 Email 轉寄

  1. 購買網域後,進入設定頁 -> 電子郵件

  2. 最下方 “電子郵件轉寄” 填入你想要的別名與轉寄的地址,儲存後就會轉寄了

利用 Hexo 與 GitHub Page 建立免費的靜態 Blog

所需環境與工具

  1. 一個 GitHub 帳號

  2. NodeJS

  3. Git

建立一個 Repository

  1. 登入 GitHub

  2. 建立 Repository

  3. name 填入 yourname.github.io (yourname 請改成你的 GitHub ID)
    下方的 type 記得請勾選 “public”

安裝 Hexo

1
2
3
4
$ npm i hexo-cli -g
$ hexo init blog
$ cd blog
$ npm i

安裝 Hexo Git

1
$ npm i hexo-deployer-git

安裝 Blog 主題

這邊我們以安裝 minos 為例子
其中 minos 需要 hexo-renderer-sass 這個套件

1
2
$ git clone https://github.com/ppoffice/hexo-theme-minos.git themes/minos
$ npm i hexo-renderer-sass

調整設定

在 blog 資料夾內可以看到 “_config.yml” 這個設定檔案
打開後在中下方有個 theme 的部分改成:

1
theme: minos

最下方 deploy 的部分則改成:

1
2
3
4
deploy:
type: git
repository: http://github.com/yourname/yourname.github.io.git
branch: master

這裡的 “yourname” 改成你的 github 帳號
其他更詳細的設定可參考 這裡

開啟 Server

1
$ hexo s -p [port]

預設在 http://localhost:4000 看 Local Page (裡面會有一篇 Hello World)

建置靜態網頁

把 Markdown File 轉成網頁

1
$ hexo g

發佈到 GitHub Page 上

1
$ hexo d

或是你也可以建置、發佈一起做

1
$ hexo d -g

網站轉址

既然我們已經有 Google Domain 跟 Hexo + GitHub Page 產的 Blog,該是串起來的時候了

設定 DNS

到 Google Domains 設定頁 -> DNS -> 自訂資源紀錄
添加一筆 Type A,IP 如下:

  • 185.199.108.153
  • 185.199.109.153
  • 185.199.110.153
  • 185.199.111.153

再添加一筆 CNAME:
name 填 subdomain (例如 “blog”)
data 填 yourname.github.io (yourname 請改成你的 github ID)

填完顯示如下:

設定 GitHub Page 的 Domain

  1. 在 /blog/source 資料夾建立 CNAME 檔案

    1
    2
    $ cd /blog/source
    $ touch CNAME

  2. 檔案內填寫入

    1
    subdomain.domain.com

    假設我的 subdomain 是 “blog”
    我買的 domain 是 brchen777.com
    那在這邊要填入的會是 blog.brchen777.com

  3. 假設有填好,進入 GitHub Repository -> Settings -> GitHub Pages 區塊,會有 “Your site is published at XXX” 的訊息,其中 XXX 就是 blog 的網址,顯示如下:

  4. GitHub Page 有內建 HTTPS,網站設定好一段時間之後就有 “Enforce HTTPS” 可選 (如上圖的下方)

設定多個 Subdomain 指向同一個 GitHub Page

因為 GitHub Page 不支援多個 CNAME 設定,所以其他的 subdomain 要自行設定轉址
到 Google Domains 設定頁 -> DNS -> 綜合記錄
假設要把 “www” 這個 subdomain 轉址,新增一筆子網域轉址如下:

以這篇案例來說,www.brchen777.combrchen777.github.io 都會指到 blog.brchen777.com

參考資料

  1. 在 Google Domains 註冊購買網域名稱教學
  2. Hexo+GitHub,新手也可以快速建立部落格
  3. 如何搭建個人 Blog 使用 Hexo + Gitpage
  4. Hexo - 前端也能建置部落格!更換主題與發表文章篇
  5. Configuring a custom domain for your GitHub Pages site
  6. 自訂網域名稱:Google Domain
  7. Troubleshooting custom domains and GitHub Pages
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×