/
manage_session.ts
105 lines (105 loc) 路 2.72 KB
/
manage_session.ts
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright 2019 Yusuke Sakurai. All rights reserved. MIT license.
import { createApp } from "../../../app.ts";
import { ServerRequest } from "../../../server.ts";
const app = createApp();
type User = {
id: string;
name: string;
};
const sessionMap: WeakMap<ServerRequest, User> = new WeakMap();
const sessionDB = new Map<string, User>();
async function setSession(sid: string, user: User) {
// save session to Database
sessionDB.set(sid, user);
}
async function getSession(sid: string): Promise<User | undefined> {
// get session from Database
return sessionDB.get(sid);
}
async function authenticate(
userId: string,
password: string,
name: string,
): Promise<User | 401> {
// do authenticate via Database
if (userId === "deno" && password === "land") {
return { id: "deno", name };
}
return 401;
}
app.use(async (req) => {
const sid = req.cookies.get("sid");
if (!sid) {
return req.redirect("/login");
}
const session = await getSession(sid);
if (!session) {
return req.redirect("/login");
}
// save session to store
sessionMap.set(req, session);
});
app.get("/", async (req, { match }) => {
const [_, id] = match;
await req.respond({
status: 200,
headers: new Headers({
"content-type": "application/json",
}),
body: JSON.stringify({ id }),
});
});
app.get("/login", async (req) => {
await req.respond({
status: 200,
headers: new Headers({
"content-type": "text/plain",
}),
body: `
<html lang="en">
<header>
<title>Login</title>
</header>
<body>
<form action="/login/auth" method="POST">
<div>
<label for="id-input">Id</label>
<input id="id-input" type="text" name="id" />
</div>
<div>
<label for="password-input">Password</label>
<input id="password-input" type="password" name="password" />
</div>
<div>
<label for="name-input">Name</label>
<input id="note-input" type="text" name="name" />
</div>
<input type="submit" value="login"/>
</form>
</body>
</html>
`,
});
});
app.post("/login/auth", async (req) => {
const form = await req.body!.formData(req.headers);
const userId = form.field("id");
const password = form.field("password");
const name = form.field("name");
if (!userId || !password || !name) {
return req.respond({ status: 400, body: "Bad Request" });
}
const user = await authenticate(userId, password, name);
if (user === 401) {
return req.respond({ status: 401, body: "Unauthorized" });
}
const sid = "..."; // create session id
await setSession(sid, user);
req.cookies.set("sid", sid);
return req.redirect("/");
});
app.get("/logout", async (req) => {
req.clearCookie("sid");
return req.redirect("/login");
});
app.listen({ port: 8899 });