|
1 | 1 | --- |
2 | 2 | title: 'HTTP Authentication' |
3 | | -excerpt: 'Scripting examples on how to use different authenitcation or authorization methods in your load test.' |
| 3 | +excerpt: 'Scripting examples on how to use different authentication or authorization methods in your load test.' |
4 | 4 | --- |
5 | 5 |
|
6 | 6 | Scripting examples on how to use different authentication or authorization methods in your load test. |
@@ -108,93 +108,68 @@ export default function () { |
108 | 108 |
|
109 | 109 | </CodeGroup> |
110 | 110 |
|
111 | | -## AWS Signature v4 authentication |
| 111 | +## AWS Signature v4 authentication with the [k6-jslib-aws](https://github.com/grafana/k6-jslib-aws) |
112 | 112 |
|
113 | | -Requests to the AWS APIs requires a special type of auth, called AWS Signature Version 4. k6 |
114 | | -does not support this authentication mechanism out of the box, so we'll have to resort to using |
115 | | -a Node.js library called [awsv4.js](https://github.com/mhart/aws4) and |
116 | | -[Browserify](http://browserify.org/) (to make it work in k6). |
| 113 | +To authenticate requests to AWS APIs using [AWS Signature Version 4](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html), k6 offers the [k6-jslib-aws](https://github.com/grafana/k6-jslib-aws) JavaScript library, which provides a dedicated `SignatureV4` class. This class can produce authenticated requests to send to AWS APIs using the `http` k6 module. |
117 | 114 |
|
118 | | -For this to work, we first need to do the following: |
119 | | - |
120 | | -1. Make sure you have the necessary prerequisites installed: [Node.js](https://nodejs.org/en/download/) |
121 | | - and [Browserify](http://browserify.org/) |
122 | | -2. Install the `awsv4.js` library: |
123 | | - |
124 | | - <CodeGroup labels={[""]} lineNumbers={[false]}> |
125 | | - |
126 | | - ```bash |
127 | | - $ npm install aws4 |
128 | | - ``` |
129 | | - |
130 | | - </CodeGroup> |
131 | | - |
132 | | -3. Run it through browserify: |
133 | | - |
134 | | - <CodeGroup labels={[""]} lineNumbers={[false]}> |
135 | | - |
136 | | - ```bash |
137 | | - $ browserify node_modules/aws4/aws4.js -s aws4 > aws4.js |
138 | | - ``` |
139 | | - |
140 | | - </CodeGroup> |
141 | | - |
142 | | -4. Move the `aws4.js` file to the same folder as your script file. Now you can import |
143 | | - it into your test script: |
144 | | - |
145 | | - <CodeGroup labels={[""]} lineNumbers={[false]}> |
146 | | - |
147 | | - ```javascript |
148 | | - import aws4 from './aws4.js'; |
149 | | - ``` |
150 | | - |
151 | | - </CodeGroup> |
152 | | - |
153 | | -Here's an example script to list all the regions available in EC2. Note that the AWS access key |
154 | | -and secret key needs to be provided through [environment variables](/using-k6/environment-variables). |
155 | | - |
156 | | -> ### ⚠️ CPU- and Memory-heavy |
157 | | -> |
158 | | -> As the browserified version of this Node.js library includes several Node.js APIs |
159 | | -> implemented in pure JS (including crypto APIs) it will be quite heavy on CPU and memory hungry |
160 | | -> when run with more than just a few VUs. |
| 115 | +Here's an example script to demonstrate how to sign a request to fetch an object from an S3 bucket: |
161 | 116 |
|
162 | 117 | <CodeGroup labels={["awsv4-auth.js"]} lineNumbers={[false]}> |
163 | 118 |
|
164 | 119 | ```javascript |
165 | 120 | import http from 'k6/http'; |
166 | | -import { sleep } from 'k6'; |
| 121 | +import { AWSConfig, SignatureV4 } from 'https://jslib.k6.io/aws/0.7.2/signature.js'; |
167 | 122 |
|
168 | | -// Import browserified AWSv4 signature library |
169 | | -import aws4 from './aws4.js'; |
| 123 | +const awsConfig = new AWSConfig({ |
| 124 | + region: __ENV.AWS_REGION, |
| 125 | + accessKeyId: __ENV.AWS_ACCESS_KEY_ID, |
| 126 | + secretAccessKey: __ENV.AWS_SECRET_ACCESS_KEY, |
170 | 127 |
|
171 | | -// Get AWS credentials from environment variables |
172 | | -const AWS_CREDS = { |
173 | | - accessKeyId: __ENV.AWS_ACCESSKEY, |
174 | | - secretAccessKey: __ENV.AWS_SECRETKEY, |
175 | | -}; |
| 128 | + /** |
| 129 | + * Optional session token for temporary credentials. |
| 130 | + */ |
| 131 | + sessionToken: __ENV.AWS_SESSION_TOKEN, |
| 132 | +}); |
176 | 133 |
|
177 | 134 | export default function () { |
178 | | - // Sign the AWS API request |
179 | | - const signed = aws4.sign( |
180 | | - { |
181 | | - service: 'ec2', |
182 | | - path: '/?Action=DescribeRegions&Version=2014-06-15', |
| 135 | + /** |
| 136 | + * Create a signer instance with the AWS credentials. |
| 137 | + * The signer will be used to sign the request. |
| 138 | + */ |
| 139 | + const signer = new SignatureV4({ |
| 140 | + service: 's3', |
| 141 | + region: awsConfig.region, |
| 142 | + credentials: { |
| 143 | + accessKeyId: awsConfig.accessKeyId, |
| 144 | + secretAccessKey: awsConfig.secretAccessKey, |
| 145 | + sessionToken: awsConfig.sessionToken, |
183 | 146 | }, |
184 | | - AWS_CREDS |
185 | | - ); |
186 | | - |
187 | | - // Make the actual request to the AWS API including the |
188 | | - // "Authorization" header with the signature |
189 | | - const res = http.get(`https://${signed.hostname}${signed.path}`, { |
190 | | - headers: signed.headers, |
191 | 147 | }); |
192 | 148 |
|
193 | | - // Print the response |
194 | | - console.log(res.body); |
| 149 | + /** |
| 150 | + * Use the signer to prepare a signed request. |
| 151 | + * The signed request can then be used to send the request to the AWS API. |
| 152 | + */ |
| 153 | + const signedRequest = signer.sign({ |
| 154 | + method: 'GET', |
| 155 | + protocol: 'https', |
| 156 | + hostname: 'test-jslib-aws.s3.us-east-1.amazonaws.com', |
| 157 | + path: '/bonjour.txt', |
| 158 | + headers: {}, |
| 159 | + uriEscapePath: false, |
| 160 | + applyChecksum: false, |
| 161 | + }, { |
| 162 | + signingDate: new Date(), |
| 163 | + signingService: 's3', |
| 164 | + signingRegion: 'us-east-1', |
| 165 | + }); |
195 | 166 |
|
196 | | - sleep(1); |
| 167 | + /** |
| 168 | + * The `signedRequest` object contains the signed request URL and headers. |
| 169 | + * We can use them to send the request to the AWS API. |
| 170 | + */ |
| 171 | + http.get(signedRequest.url, { headers: signedRequest.headers }); |
197 | 172 | } |
198 | 173 | ``` |
199 | 174 |
|
200 | | -</CodeGroup> |
| 175 | +</CodeGroup> |
0 commit comments