0


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

文章目录

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

Deno 简介

特点

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

TypeScript 简介

  • 类型安全:提供强类型检查,避免运行时错误。
  • 静态类型检查:在编译阶段发现类型错误,提高代码质量。
  • 工具支持:丰富的 IDE 和编辑器支持,提高开发效率。

安全性基础

权限管理

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

代码隔离

  • 每个模块都在沙箱环境中运行,防止恶意代码影响全局。

Deno 安装与基本使用

安装 Deno

curl -fsSL https://deno.land/x/install/install.sh |sh
deno --version

创建项目

mkdir my-deno-app
cd my-deno-app

编写基本代码

// main.tsconsole.log("Hello, Deno!");

运行代码

deno run main.ts

权限管理

默认权限

默认情况下,Deno 不允许任何权限。

deno run --allow-read main.ts

显式授予权限

授予读权限。

deno run --allow-read main.ts

权限组合

授予读和写权限。

deno run --allow-read --allow-write main.ts

HTTP 服务器

创建 HTTP 服务器

// server.tsimport{ serve }from"https://deno.land/[email protected]/http/server.ts";consthandler=(req: Request)=>{if(req.method ==="GET"){returnnewResponse("Hello, World!");}returnnewResponse("Method not allowed",{ status:405});};serve(handler);

运行 HTTP 服务器

deno run --allow-net server.ts

访问服务器

curl http://localhost:8000

安全的 HTTP 请求

发送 HTTP 请求

// request.tsimport{ serve }from"https://deno.land/[email protected]/http/server.ts";import{ fetch }from"https://deno.land/[email protected]/fetch/mod.ts";consthandler=async(req: Request)=>{const response =awaitfetch("https://api.example.com/data");const data =await response.json();returnnewResponse(JSON.stringify(data),{ headers:{"Content-Type":"application/json"}});};serve(handler);

运行请求处理程序

deno run --allow-net request.ts

访问请求处理程序

curl http://localhost:8000

数据验证与类型安全

数据验证

// validator.tsimport{ serve }from"https://deno.land/[email protected]/http/server.ts";import{ z }from"https://deno.land/x/[email protected]/mod.ts";interfaceUser{
  id:number;
  name:string;
  email:string;}const userSchema = z.object({
  id: z.number(),
  name: z.string().min(1),
  email: z.string().email(),});consthandler=async(req: Request)=>{const url =newURL(req.url);const params = Object.fromEntries(url.searchParams.entries());const result = userSchema.safeParse(params);if(!result.success){returnnewResponse(result.error.message,{ status:400});}const user: User = result.data;returnnewResponse(JSON.stringify(user),{ headers:{"Content-Type":"application/json"}});};serve(handler);

运行验证处理程序

deno run --allow-net validator.ts

访问验证处理程序

curl"http://localhost:8000?id=1&name=John&[email protected]"

安全的数据库操作

连接数据库

// database.tsimport{ serve }from"https://deno.land/[email protected]/http/server.ts";import{ sql }from"https://deno.land/x/[email protected]/mod.ts";const db = sql.open(":memory:");const createTable =`
  CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT NOT NULL UNIQUE
  );
`;

db.query(createTable);const insertUser =`
  INSERT INTO users (name, email) VALUES (?, ?);
`;const selectUsers =`
  SELECT * FROM users;
`;consthandler=async(req: Request)=>{const url =newURL(req.url);const name = url.searchParams.get("name");const email = url.searchParams.get("email");if(!name ||!email){returnnewResponse("Missing parameters",{ status:400});}try{
    db.query(insertUser,[name, email]);const users = db.query(selectUsers).fetchAll();returnnewResponse(JSON.stringify(users),{ headers:{"Content-Type":"application/json"}});}catch(error){returnnewResponse(error.message,{ status:500});}};serve(handler);

运行数据库处理程序

deno run --allow-net --allow-read --allow-write database.ts

访问数据库处理程序

curl"http://localhost:8000?name=John&[email protected]"

日志与错误处理

日志记录

// logger.tsimport{ serve }from"https://deno.land/[email protected]/http/server.ts";import{ format }from"https://deno.land/[email protected]/datetime/mod.ts";consthandler=async(req: Request)=>{const now =format(newDate(),"yyyy-MM-dd HH:mm:ss");console.log(`${now} - ${req.method} - ${req.url}`);returnnewResponse("OK");};serve(handler);

错误处理

// error-handler.tsimport{ serve }from"https://deno.land/[email protected]/http/server.ts";consthandler=async(req: Request)=>{try{// Perform some operationreturnnewResponse("OK");}catch(error){console.error(error);returnnewResponse(error.message,{ status:500});}};serve(handler);

安全的最佳实践

最小权限原则

只授予必要的权限。

deno run --allow-net --allow-read main.ts

输入验证

对所有外部输入进行严格验证。

const userSchema = z.object({
  id: z.number(),
  name: z.string().min(1),
  email: z.string().email(),});

加密敏感数据

对敏感数据进行加密处理。

import{ crypto }from"https://deno.land/[email protected]/crypto/mod.ts";const secret = crypto.randomUUID();const encryptedData = crypto.encrypt(secret, sensitiveData);

安全的数据库操作

使用参数化查询防止 SQL 注入。

const insertUser =`
  INSERT INTO users (name, email) VALUES (?, ?);
`;

db.query(insertUser,[name, email]);

安全的会话管理

使用安全的会话管理机制。

import{ serve, Cookie }from"https://deno.land/[email protected]/http/server.ts";consthandler=async(req: Request)=>{const sessionCookie = req.headers.get("Cookie");let sessionId =null;if(sessionCookie){const cookie =newCookie(sessionCookie);
    sessionId = cookie.get("session_id")?.value;}if(!sessionId){
    sessionId = crypto.randomUUID();const cookie =newCookie({
      name:"session_id",
      value: sessionId,
      httpOnly:true,
      secure:true,
      sameSite:"strict",});returnnewResponse("Session created",{
      headers:{"Set-Cookie": cookie.toString()},});}// Perform session-related operationsreturnnewResponse("OK");};serve(handler);

使用 HTTPS

确保所有通信都使用 HTTPS。

const server =serve({ port:443, hostname:"example.com", secure:true});

CORS 策略

配置适当的 CORS 策略。

consthandler=async(req: Request)=>{const origin = req.headers.get("Origin");if(origin ==="https://example.com"){returnnewResponse("OK",{
      headers:{"Access-Control-Allow-Origin": origin },});}returnnewResponse("Not allowed",{ status:403});};serve(handler);

安全的文件上传

对上传文件进行严格的验证和限制。

import{ serve }from"https://deno.land/[email protected]/http/server.ts";import{ parseMultipartFormData }from"https://deno.land/[email protected]/mime/multipart/form_data/parser.ts";consthandler=async(req: Request)=>{const formData =awaitparseMultipartFormData(req,{ maxFileSize:1024*1024*5});// 5MB limitif(!formData.has("file")){returnnewResponse("File missing",{ status:400});}const file = formData.get("file");if(!file){returnnewResponse("Invalid file",{ status:400});}const fileName = file.name;const fileSize = file.size;const fileType = file.type;if(fileType !=="image/jpeg"&& fileType !=="image/png"){returnnewResponse("Unsupported file type",{ status:400});}// Save the file securelyconst filePath =`./uploads/${fileName}`;const fileStream = Deno.openSync(filePath,{ write:true, create:true});await fileStream.write(file.data);
  fileStream.close();returnnewResponse("File uploaded successfully");};serve(handler);

安全的环境变量管理

使用环境变量存储敏感信息。

const apiKey = Deno.env.get("API_KEY");const apiSecret = Deno.env.get("API_SECRET");

定期审计与更新

定期进行安全审计,并及时更新依赖库。

deno upgrade

安全的认证与授权

JWT认证

使用 JWT 进行用户认证。

import{ serve }from"https://deno.land/[email protected]/http/server.ts";import{ jwt }from"https://deno.land/x/[email protected]/mod.ts";const secret = Deno.env.get("JWT_SECRET");consthandler=async(req: Request)=>{const authHeader = req.headers.get("Authorization");if(!authHeader ||!authHeader.startsWith("Bearer ")){returnnewResponse("Unauthorized",{ status:401});}const token = authHeader.slice(7);// Remove "Bearer " prefixtry{const decodedToken =await jwt.decode(token,{ secret });returnnewResponse("Authenticated");}catch(error){returnnewResponse("Invalid token",{ status:401});}};serve(handler);

角色与权限

使用角色和权限进行细粒度控制。

const userRoles ={
  admin:["read","write","delete"],
  user:["read"],};consthandler=async(req: Request)=>{const authHeader = req.headers.get("Authorization");const token = authHeader.slice(7);// Remove "Bearer " prefixconst decodedToken =await jwt.decode(token,{ secret });const role = decodedToken.role;const permissions = userRoles[role];if(!permissions.includes("write")){returnnewResponse("Permission denied",{ status:403});}// Perform write operationreturnnewResponse("Write successful");};serve(handler);

本文转载自: https://blog.csdn.net/A1215383843/article/details/142723862
版权归原作者 天涯学馆 所有, 如有侵权,请联系我们删除。

“Deno与Secure TypeScript:安全的后端开发”的评论:

还没有评论