Skip to content

Commit e49c0a2

Browse files
[Workers] Adds rust example basic-auth
1 parent 8de8f91 commit e49c0a2

File tree

2 files changed

+74
-2
lines changed

2 files changed

+74
-2
lines changed

src/content/docs/workers/examples/basic-auth.mdx

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ tags:
77
languages:
88
- JavaScript
99
- TypeScript
10+
- Rust
1011
preview:
1112
- true
1213
pcx_content_type: example
@@ -258,4 +259,75 @@ export default {
258259
} satisfies ExportedHandler<Env>;
259260
```
260261
261-
</TabItem> </Tabs>
262+
</TabItem> <TabItem label="Rust" icon="seti:rust">
263+
```rs
264+
use base64::prelude::*;
265+
use worker::*;
266+
267+
#[event(fetch)]
268+
async fn fetch(req: Request, env: Env, _ctx: Context) -> Result<Response> {
269+
let basic_user = "admin";
270+
// You will need an admin password. This should be
271+
// attached to your Worker as an encrypted secret.
272+
// Refer to https://developers.cloudflare.com/workers/configuration/secrets/
273+
let basic_pass = match env.secret("PASSWORD") {
274+
Ok(s) => s.to_string(),
275+
Err(_) => "password".to_string(),
276+
};
277+
let url = req.url()?;
278+
279+
match url.path() {
280+
"/" => Response::ok("Anyone can access the homepage."),
281+
// Invalidate the "Authorization" header by returning a HTTP 401.
282+
// We do not send a "WWW-Authenticate" header, as this would trigger
283+
// a popup in the browser, immediately asking for credentials again.
284+
"/logout" => Response::error("Logged out.", 401),
285+
"/admin" => {
286+
// The "Authorization" header is sent when authenticated.
287+
let authorization = req.headers().get("Authorization")?;
288+
if authorization == None {
289+
let mut headers = Headers::new();
290+
// Prompts the user for credentials.
291+
headers.set(
292+
"WWW-Authenticate",
293+
"Basic realm='my scope', charset='UTF-8'",
294+
)?;
295+
return Ok(Response::error("You need to login.", 401)?.with_headers(headers));
296+
}
297+
let authorization = authorization.unwrap();
298+
let auth: Vec<&str> = authorization.split(" ").collect();
299+
let scheme = auth[0];
300+
let encoded = auth[1];
301+
302+
// The Authorization header must start with Basic, followed by a space.
303+
if encoded == "" || scheme != "Basic" {
304+
return Response::error("Malformed authorization header.", 400);
305+
}
306+
307+
let buff = BASE64_STANDARD.decode(encoded).unwrap();
308+
let credentials = String::from_utf8_lossy(&buff);
309+
// The username & password are split by the first colon.
310+
//=> example: "username:password"
311+
let credentials: Vec<&str> = credentials.split(':').collect();
312+
let user = credentials[0];
313+
let pass = credentials[1];
314+
315+
if user != basic_user || pass != basic_pass {
316+
let mut headers = Headers::new();
317+
// Prompts the user for credentials.
318+
headers.set(
319+
"WWW-Authenticate",
320+
"Basic realm='my scope', charset='UTF-8'",
321+
)?;
322+
return Ok(Response::error("You need to login.", 401)?.with_headers(headers));
323+
}
324+
325+
let mut headers = Headers::new();
326+
headers.set("Cache-Control", "no-store")?;
327+
Ok(Response::ok("🎉 You have private access!")?.with_headers(headers))
328+
}
329+
_ => Response::error("Not Found.", 404),
330+
}
331+
}
332+
```
333+
</TabItem> </Tabs>

src/content/docs/workers/examples/websockets.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ summary: Use the WebSockets API to communicate in real time with your Cloudflare
44
tags:
55
- WebSockets
66
languages:
7-
- Rust
87
- JavaScript
8+
- Rust
99
pcx_content_type: example
1010
title: Using the WebSockets API
1111
sidebar:

0 commit comments

Comments
 (0)