Deno与Secure TypeScript:安全的后端开辟

打印 上一主题 下一主题

主题 994|帖子 994|积分 2982

Deno 是一个当代的后端 JavaScript/TypeScript 运行时,由 Node.js 的创始人 Ryan Dahl 创建。Deno 提供了很多内置的安全特性,使得后端开辟更加安全可靠。
Deno 简介

特点


  • 安全性:默认情况下禁用文件系统访问、网络访问等权限,必须显式授予。
  • 模块化:支持 ES 模块语法,无需额外的模块加载器。
  • 内置工具:提供了很多内置工具,如 HTTP 服务器、WebSocket 服务器等。
  • 跨平台:支持 Windows、macOS 和 Linux。
TypeScript 简介



  • 范例安全:提供强范例查抄,避免运行时错误。
  • 静态范例查抄:在编译阶段发现范例错误,进步代码质量。
  • 工具支持:丰富的 IDE 和编辑器支持,进步开辟效率。
安全性基础

权限管理


  • Deno 默认禁用所有权限,必须显式授予。
  • 权限包括文件系统访问、网络访问、情况变量访问等。
代码隔离


  • 每个模块都在沙箱情况中运行,防止恶意代码影响全局。
Deno 安装与基本利用

安装 Deno
  1. curl -fsSL https://deno.land/x/install/install.sh | sh
  2. deno --version
复制代码
创建项目
  1. mkdir my-deno-app
  2. cd my-deno-app
复制代码
编写基本代码
  1. // main.ts
  2. console.log("Hello, Deno!");
复制代码
运行代码
  1. deno run main.ts
复制代码
权限管理

默认权限
默认情况下,Deno 不允许任何权限。
  1. deno run --allow-read main.ts
复制代码
显式授予权限
授予读权限。
  1. deno run --allow-read main.ts
复制代码
权限组合
授予读和写权限。
  1. deno run --allow-read --allow-write main.ts
复制代码
HTTP 服务器

创建 HTTP 服务器
  1. // server.ts
  2. import { serve } from "https://deno.land/std@0.188.0/http/server.ts";
  3. const handler = (req: Request) => {
  4.   if (req.method === "GET") {
  5.     return new Response("Hello, World!");
  6.   }
  7.   return new Response("Method not allowed", { status: 405 });
  8. };
  9. serve(handler);
复制代码
运行 HTTP 服务器
  1. deno run --allow-net server.ts
复制代码
访问服务器
  1. curl http://localhost:8000
复制代码
安全的 HTTP 哀求

发送 HTTP 哀求
  1. // request.ts
  2. import { serve } from "https://deno.land/std@0.188.0/http/server.ts";
  3. import { fetch } from "https://deno.land/std@0.188.0/fetch/mod.ts";
  4. const handler = async (req: Request) => {
  5.   const response = await fetch("https://api.example.com/data");
  6.   const data = await response.json();
  7.   return new Response(JSON.stringify(data), { headers: { "Content-Type": "application/json" } });
  8. };
  9. serve(handler);
复制代码
运行哀求处理程序
  1. deno run --allow-net request.ts
复制代码
访问哀求处理程序
  1. curl http://localhost:8000
复制代码
数据验证与范例安全

数据验证
  1. // validator.ts
  2. import { serve } from "https://deno.land/std@0.188.0/http/server.ts";
  3. import { z } from "https://deno.land/x/zod@v3.21.4/mod.ts";
  4. interface User {
  5.   id: number;
  6.   name: string;
  7.   email: string;
  8. }
  9. const userSchema = z.object({
  10.   id: z.number(),
  11.   name: z.string().min(1),
  12.   email: z.string().email(),
  13. });
  14. const handler = async (req: Request) => {
  15.   const url = new URL(req.url);
  16.   const params = Object.fromEntries(url.searchParams.entries());
  17.   const result = userSchema.safeParse(params);
  18.   if (!result.success) {
  19.     return new Response(result.error.message, { status: 400 });
  20.   }
  21.   const user: User = result.data;
  22.   return new Response(JSON.stringify(user), { headers: { "Content-Type": "application/json" } });
  23. };
  24. serve(handler);
复制代码
运行验证处理程序
  1. deno run --allow-net validator.ts
复制代码
访问验证处理程序
  1. curl "http://localhost:8000?id=1&name=John&email=john@example.com"
复制代码
安全的数据库利用

毗连数据库
  1. // database.ts
  2. import { serve } from "https://deno.land/std@0.188.0/http/server.ts";
  3. import { sql } from "https://deno.land/x/sqlite@v3.4.2/mod.ts";
  4. const db = sql.open(":memory:");
  5. const createTable = `
  6.   CREATE TABLE IF NOT EXISTS users (
  7.     id INTEGER PRIMARY KEY AUTOINCREMENT,
  8.     name TEXT NOT NULL,
  9.     email TEXT NOT NULL UNIQUE
  10.   );
  11. `;
  12. db.query(createTable);
  13. const insertUser = `
  14.   INSERT INTO users (name, email) VALUES (?, ?);
  15. `;
  16. const selectUsers = `
  17.   SELECT * FROM users;
  18. `;
  19. const handler = async (req: Request) => {
  20.   const url = new URL(req.url);
  21.   const name = url.searchParams.get("name");
  22.   const email = url.searchParams.get("email");
  23.   if (!name || !email) {
  24.     return new Response("Missing parameters", { status: 400 });
  25.   }
  26.   try {
  27.     db.query(insertUser, [name, email]);
  28.     const users = db.query(selectUsers).fetchAll();
  29.     return new Response(JSON.stringify(users), { headers: { "Content-Type": "application/json" } });
  30.   } catch (error) {
  31.     return new Response(error.message, { status: 500 });
  32.   }
  33. };
  34. serve(handler);
复制代码
运行数据库处理程序
  1. deno run --allow-net --allow-read --allow-write database.ts
复制代码
访问数据库处理程序
  1. curl "http://localhost:8000?name=John&email=john@example.com"
复制代码
日志与错误处理

日志记载
  1. // logger.ts
  2. import { serve } from "https://deno.land/std@0.188.0/http/server.ts";
  3. import { format } from "https://deno.land/std@0.188.0/datetime/mod.ts";
  4. const handler = async (req: Request) => {
  5.   const now = format(new Date(), "yyyy-MM-dd HH:mm:ss");
  6.   console.log(`${now} - ${req.method} - ${req.url}`);
  7.   return new Response("OK");
  8. };
  9. serve(handler);
复制代码
错误处理
  1. // error-handler.ts
  2. import { serve } from "https://deno.land/std@0.188.0/http/server.ts";
  3. const handler = async (req: Request) => {
  4.   try {
  5.     // Perform some operation
  6.     return new Response("OK");
  7.   } catch (error) {
  8.     console.error(error);
  9.     return new Response(error.message, { status: 500 });
  10.   }
  11. };
  12. serve(handler);
复制代码
安全的最佳实践

最小权限原则
只授予须要的权限。
  1. deno run --allow-net --allow-read main.ts
复制代码
输入验证
对所有外部输入进行严酷验证。
  1. const userSchema = z.object({
  2.   id: z.number(),
  3.   name: z.string().min(1),
  4.   email: z.string().email(),
  5. });
复制代码
加密敏感数据
对敏感数据进行加密处理。
  1. import { crypto } from "https://deno.land/std@0.188.0/crypto/mod.ts";
  2. const secret = crypto.randomUUID();
  3. const encryptedData = crypto.encrypt(secret, sensitiveData);
复制代码
安全的数据库利用
利用参数化查询防止 SQL 注入。
  1. const insertUser = `
  2.   INSERT INTO users (name, email) VALUES (?, ?);
  3. `;
  4. db.query(insertUser, [name, email]);
复制代码
安全的会话管理
利用安全的会话管理机制。
  1. import { serve, Cookie } from "https://deno.land/std@0.188.0/http/server.ts";
  2. const handler = async (req: Request) => {
  3.   const sessionCookie = req.headers.get("Cookie");
  4.   let sessionId = null;
  5.   if (sessionCookie) {
  6.     const cookie = new Cookie(sessionCookie);
  7.     sessionId = cookie.get("session_id")?.value;
  8.   }
  9.   if (!sessionId) {
  10.     sessionId = crypto.randomUUID();
  11.     const cookie = new Cookie({
  12.       name: "session_id",
  13.       value: sessionId,
  14.       httpOnly: true,
  15.       secure: true,
  16.       sameSite: "strict",
  17.     });
  18.     return new Response("Session created", {
  19.       headers: { "Set-Cookie": cookie.toString() },
  20.     });
  21.   }
  22.   // Perform session-related operations
  23.   return new Response("OK");
  24. };
  25. serve(handler);
复制代码
利用 HTTPS
确保所有通信都利用 HTTPS。
  1. const server = serve({ port: 443, hostname: "example.com", secure: true });
复制代码
CORS 计谋
设置得当的 CORS 计谋。
  1. const handler = async (req: Request) => {
  2.   const origin = req.headers.get("Origin");
  3.   if (origin === "https://example.com") {
  4.     return new Response("OK", {
  5.       headers: { "Access-Control-Allow-Origin": origin },
  6.     });
  7.   }
  8.   return new Response("Not allowed", { status: 403 });
  9. };
  10. serve(handler);
复制代码
安全的文件上传
对上传文件进行严酷的验证和限定。
  1. import { serve } from "https://deno.land/std@0.188.0/http/server.ts";
  2. import { parseMultipartFormData } from "https://deno.land/std@0.188.0/mime/multipart/form_data/parser.ts";
  3. const handler = async (req: Request) => {
  4.   const formData = await parseMultipartFormData(req, { maxFileSize: 1024 * 1024 * 5 }); // 5MB limit
  5.   if (!formData.has("file")) {
  6.     return new Response("File missing", { status: 400 });
  7.   }
  8.   const file = formData.get("file");
  9.   if (!file) {
  10.     return new Response("Invalid file", { status: 400 });
  11.   }
  12.   const fileName = file.name;
  13.   const fileSize = file.size;
  14.   const fileType = file.type;
  15.   if (fileType !== "image/jpeg" && fileType !== "image/png") {
  16.     return new Response("Unsupported file type", { status: 400 });
  17.   }
  18.   // Save the file securely
  19.   const filePath = `./uploads/${fileName}`;
  20.   const fileStream = Deno.openSync(filePath, { write: true, create: true });
  21.   await fileStream.write(file.data);
  22.   fileStream.close();
  23.   return new Response("File uploaded successfully");
  24. };
  25. serve(handler);
复制代码
安全的情况变量管理
利用情况变量存储敏感信息。
  1. const apiKey = Deno.env.get("API_KEY");
  2. const apiSecret = Deno.env.get("API_SECRET");
复制代码
定期审计与更新
定期进行安全审计,并及时更新依赖库。
  1. deno upgrade
复制代码
安全的认证与授权

JWT认证
利用 JWT 进行用户认证。
  1. import { serve } from "https://deno.land/std@0.188.0/http/server.ts";
  2. import { jwt } from "https://deno.land/x/djwt@v2.2/mod.ts";
  3. const secret = Deno.env.get("JWT_SECRET");
  4. const handler = async (req: Request) => {
  5.   const authHeader = req.headers.get("Authorization");
  6.   if (!authHeader || !authHeader.startsWith("Bearer ")) {
  7.     return new Response("Unauthorized", { status: 401 });
  8.   }
  9.   const token = authHeader.slice(7); // Remove "Bearer " prefix
  10.   try {
  11.     const decodedToken = await jwt.decode(token, { secret });
  12.     return new Response("Authenticated");
  13.   } catch (error) {
  14.     return new Response("Invalid token", { status: 401 });
  15.   }
  16. };
  17. serve(handler);
复制代码
角色与权限
利用角色和权限进行细粒度控制。
  1. const userRoles = {
  2.   admin: ["read", "write", "delete"],
  3.   user: ["read"],
  4. };
  5. const handler = async (req: Request) => {
  6.   const authHeader = req.headers.get("Authorization");
  7.   const token = authHeader.slice(7); // Remove "Bearer " prefix
  8.   const decodedToken = await jwt.decode(token, { secret });
  9.   const role = decodedToken.role;
  10.   const permissions = userRoles[role];
  11.   if (!permissions.includes("write")) {
  12.     return new Response("Permission denied", { status: 403 });
  13.   }
  14.   // Perform write operation
  15.   return new Response("Write successful");
  16. };
  17. serve(handler);
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

数据人与超自然意识

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表