はじめに
サイトがBasic認証やDigest認証を設定していた場合、どうしたら良いか気になったので調べて試してみました。
ただ実行するだけだとピンとこない部分もあると思うので、curlコマンドのどの実行に相当するのかも併せて記載してます。
事前確認
ますは Basic認証 が設定されているサイトを確認します。
コマンドラインで確認すると以下が確認できます。
401 UNAUTHORIZED
$ curl -i https://httpbin.test.k6.io/basic-auth/user/passwd
HTTP/1.1 401 UNAUTHORIZED
Date: Sun, 11 Sep 2022 06:29:39 GMT
Content-Length: 0
Connection: keep-alive
WWW-Authenticate: Basic realm="Fake Realm"
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
200 OK
$ curl -i --user 'user:passwd' https://httpbin.test.k6.io/basic-auth/user/passwd
HTTP/1.1 200 OK
Date: Sun, 11 Sep 2022 06:40:43 GMT
Content-Type: application/json
Content-Length: 47
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
{
"authenticated": true,
"user": "user"
}
それでは実際に k6 を実行したいと思います。
負荷テスト
Basic認証とDigest認証に対してのBasic認証のサイトには2つの方法でアクセスができます。
方法1. URL埋め込み
認証情報をURLに埋め込む方法です。
basic-auth01.js
import encoding from 'k6/encoding';
import http from 'k6/http';
import { check } from 'k6';
const username = 'user';
const password = 'passwd';
export default function () {
const credentials = `${username}:${password}`;
const url = `https://${credentials}@httpbin.test.k6.io/basic-auth/user/passwd`;
let res = http.get(url);
// Verify response
check(res, {
'status is 200': (r) => r.status === 200,
'is authenticated': (r) => r.json().authenticated === true,
'is correct user': (r) => r.json().user === username,
});
}
ID
とPASS
を:
で繋げたという組み合わせで curlコマンド に置き換えると以下になります。
curl
$ curl -i https://user:passwd@httpbin.test.k6.io/basic-auth/user/passwd
それではスクリプトを実行します。
実行
% k6 run basic-auth01.js
/\ |‾‾| /‾‾/ /‾‾/
/\ / \ | |/ / / /
/ \/ \ | ( / ‾‾\
/ \ | |\ \ | (‾) |
/ __________ \ |__| \__\ \_____/ .io
execution: local
script: basic-auth01.js
output: -
scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
* default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)
running (00m00.8s), 0/1 VUs, 1 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs 00m00.8s/10m0s 1/1 iters, 1 per VU
✓ status is 200
✓ is authenticated
✓ is correct user
checks.........................: 100.00% ✓ 3 ✗ 0
data_received..................: 5.7 kB 7.5 kB/s
data_sent......................: 515 B 670 B/s
http_req_blocked...............: avg=579.44ms min=579.44ms med=579.44ms max=579.44ms p(90)=579.44ms p(95)=579.44ms
http_req_connecting............: avg=183.25ms min=183.25ms med=183.25ms max=183.25ms p(90)=183.25ms p(95)=183.25ms
http_req_duration..............: avg=185.8ms min=185.8ms med=185.8ms max=185.8ms p(90)=185.8ms p(95)=185.8ms
{ expected_response:true }...: avg=185.8ms min=185.8ms med=185.8ms max=185.8ms p(90)=185.8ms p(95)=185.8ms
http_req_failed................: 0.00% ✓ 0 ✗ 1
http_req_receiving.............: avg=287µs min=287µs med=287µs max=287µs p(90)=287µs p(95)=287µs
http_req_sending...............: avg=227µs min=227µs med=227µs max=227µs p(90)=227µs p(95)=227µs
http_req_tls_handshaking.......: avg=198.35ms min=198.35ms med=198.35ms max=198.35ms p(90)=198.35ms p(95)=198.35ms
http_req_waiting...............: avg=185.29ms min=185.29ms med=185.29ms max=185.29ms p(90)=185.29ms p(95)=185.29ms
http_reqs......................: 1 1.30138/s
iteration_duration.............: avg=766.35ms min=766.35ms med=766.35ms max=766.35ms p(90)=766.35ms p(95)=766.35ms
iterations.....................: 1 1.30138/s
方法2. Authorization ヘッダ指定
Authorization ヘッダを使ったアクセス方法です。
basic-auth02.js
import encoding from 'k6/encoding';
import http from 'k6/http';
import { check } from 'k6';
const username = 'user';
const password = 'passwd';
export default function () {
const credentials = `${username}:${password}`;
const encodedCredentials = encoding.b64encode(credentials);
const options = {
headers: {
Authorization: `Basic ${encodedCredentials}`,
},
};
let res = http.get(`https://httpbin.test.k6.io/basic-auth/${username}/${password}`, options);
check(res, {
'status is 200': (r) => r.status === 200,
'is authenticated': (r) => r.json().authenticated === true,
'is correct user': (r) => r.json().user === username,
});
}
curlコマンド では以下のようになります。
curl
$ ENC=`echo -n "user:passwd" | base64` | curl -i https://httpbin.test.k6.io/basic-auth/user/passwd -H "Authorization:Basic ${ENC}"
それではスクリプトを実行します。
実行
% k6 run basic-auth02.js
/\ |‾‾| /‾‾/ /‾‾/
/\ / \ | |/ / / /
/ \/ \ | ( / ‾‾\
/ \ | |\ \ | (‾) |
/ __________ \ |__| \__\ \_____/ .io
execution: local
script: basic-auth02.js
output: -
scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
* default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)
running (00m01.0s), 0/1 VUs, 1 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs 00m01.0s/10m0s 1/1 iters, 1 per VU
✓ status is 200
✓ is authenticated
✓ is correct user
checks.........................: 100.00% ✓ 3 ✗ 0
data_received..................: 5.7 kB 5.6 kB/s
data_sent......................: 515 B 505 B/s
http_req_blocked...............: avg=828.2ms min=828.2ms med=828.2ms max=828.2ms p(90)=828.2ms p(95)=828.2ms
http_req_connecting............: avg=181.86ms min=181.86ms med=181.86ms max=181.86ms p(90)=181.86ms p(95)=181.86ms
http_req_duration..............: avg=185.46ms min=185.46ms med=185.46ms max=185.46ms p(90)=185.46ms p(95)=185.46ms
{ expected_response:true }...: avg=185.46ms min=185.46ms med=185.46ms max=185.46ms p(90)=185.46ms p(95)=185.46ms
http_req_failed................: 0.00% ✓ 0 ✗ 1
http_req_receiving.............: avg=1.32ms min=1.32ms med=1.32ms max=1.32ms p(90)=1.32ms p(95)=1.32ms
http_req_sending...............: avg=696µs min=696µs med=696µs max=696µs p(90)=696µs p(95)=696µs
http_req_tls_handshaking.......: avg=201.94ms min=201.94ms med=201.94ms max=201.94ms p(90)=201.94ms p(95)=201.94ms
http_req_waiting...............: avg=183.44ms min=183.44ms med=183.44ms max=183.44ms p(90)=183.44ms p(95)=183.44ms
http_reqs......................: 1 0.981191/s
iteration_duration.............: avg=1.01s min=1.01s med=1.01s max=1.01s p(90)=1.01s p(95)=1.01s
iterations.....................: 1 0.981191/s
vus............................: 1 min=1 max=1
vus_max........................: 1 min=1 max=1
Digest認証
digest-auth.js
import http from 'k6/http';
import { check } from 'k6';
const username = 'user';
const password = 'passwd';
export default function () {
const credentials = `${username}:${password}`;
const res = http.get(
`https://${credentials}@httpbin.test.k6.io/digest-auth/auth/${username}/${password}`,
{ auth: 'digest' }
);
check(res, {
'status is 200': (r) => r.status === 200,
'is authenticated': (r) => r.json().authenticated === true,
'is correct user': (r) => r.json().user === username,
});
}
curlコマンド では以下のようになります。
curl
$ curl --digest --user "user:passwd" "https://httpbin.test.k6.io/digest-auth/auth/user/passwd"
実行
$ k6 run digest-auth.js
/\ |‾‾| /‾‾/ /‾‾/
/\ / \ | |/ / / /
/ \/ \ | ( / ‾‾\
/ \ | |\ \ | (‾) |
/ __________ \ |__| \__\ \_____/ .io
execution: local
script: digest-auth.js
output: -
scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
* default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)
running (00m00.9s), 0/1 VUs, 1 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs 00m00.9s/10m0s 1/1 iters, 1 per VU
✓ status is 200
✓ is authenticated
✓ is correct user
checks.........................: 100.00% ✓ 3 ✗ 0
data_received..................: 6.3 kB 6.8 kB/s
data_sent......................: 988 B 1.1 kB/s
http_req_blocked...............: avg=245.27ms min=5µs med=245.27ms max=490.55ms p(90)=441.49ms p(95)=466.02ms
http_req_connecting............: avg=90.66ms min=0s med=90.66ms max=181.33ms p(90)=163.2ms p(95)=172.27ms
http_req_duration..............: avg=216.54ms min=201.39ms med=216.54ms max=231.69ms p(90)=228.66ms p(95)=230.17ms
{ expected_response:true }...: avg=216.54ms min=201.39ms med=216.54ms max=231.69ms p(90)=228.66ms p(95)=230.17ms
http_req_failed................: 0.00% ✓ 0 ✗ 2
http_req_receiving.............: avg=164.5µs min=137µs med=164.5µs max=192µs p(90)=186.5µs p(95)=189.25µs
http_req_sending...............: avg=38µs min=17µs med=38µs max=59µs p(90)=54.8µs p(95)=56.89µs
http_req_tls_handshaking.......: avg=99.22ms min=0s med=99.22ms max=198.45ms p(90)=178.61ms p(95)=188.53ms
http_req_waiting...............: avg=216.34ms min=201.18ms med=216.34ms max=231.49ms p(90)=228.46ms p(95)=229.98ms
http_reqs......................: 2 2.157921/s
iteration_duration.............: avg=924.61ms min=924.61ms med=924.61ms max=924.61ms p(90)=924.61ms p(95)=924.61ms
iterations.....................: 1 1.07896/s
おわりに
負荷テストを行う際、認証が掛かってる場合は多々あると思います。
一時的に解除することが可能な場合は良いですが、そういうことが難しい場合などにとても有効な手段だと思います。
参考