【问题标题】:[uncaught application error]: TypeError - Cannot read properties of undefined (reading 'name')[未捕获的应用程序错误]:TypeError - 无法读取未定义的属性(读取“名称”)
【发布时间】:2021-11-30 13:58:08
【问题描述】:

当我尝试使用 Postman 测试 /api/register 端点并遵循 POST 请求时收到此错误消息:

{
    "name" : "first",
    "email" : "first@one.com",
    "password" : "123"
}
[uncaught application error]: TypeError - Cannot read properties of undefined (reading 'name')

    request: { url: "http://0.0.0.0:8000/api/register", method: "POST", hasBody: true }
    response: { status: 404, type: undefined, hasBody: false, writable: true }
    
        at register (file:///C:/Users/m/app_back/controllers/auth_controller.ts:9:22)
        at async dispatch (https://deno.land/x/oak@v9.0.1/middleware.ts:41:7)
        at async dispatch (https://deno.land/x/oak@v9.0.1/middleware.ts:41:7)
        at async dispatch (https://deno.land/x/oak@v9.0.1/middleware.ts:41:7)
        at async EventTarget.#handleRequest (https://deno.land/x/oak@v9.0.1/application.ts:379:9)
    TypeError: Cannot read properties of undefined (reading 'name')
        at register (file:///C:/Users/m/app_back/controllers/auth_controller.ts:9:22)
        at async dispatch (https://deno.land/x/oak@v9.0.1/middleware.ts:41:7)
        at async dispatch (https://deno.land/x/oak@v9.0.1/middleware.ts:41:7)
        at async dispatch (https://deno.land/x/oak@v9.0.1/middleware.ts:41:7)
        at async EventTarget.#handleRequest (https://deno.land/x/oak@v9.0.1/application.ts:379:9)

这是我的auth_controller.ts 文件:

import {
      create, verify, decode, getNumericDate, RouterContext, hashSync, compareSync
    } from "../deps.ts";
    import { userCollection } from "../mongo.ts";
    import User from "../models/user.ts";
    
    export class AuthController {
      async register(ctx: RouterContext) {
        const { value: { name, email, password } } = await ctx.request.body().value;
    
        let user = await User.findOne({ email });
        if (user) {
          ctx.response.status = 422;
          ctx.response.body = { message: "Email is already used" };
          return;
        }
        const hashedPassword = hashSync(password);
        user = new User({ name, email, password: hashedPassword });
        await user.save();
        ctx.response.status = 201;
        ctx.response.body = {
          id: user.id,
          name: user.name,
          email: user.email
        };
      }
      async login(ctx: RouterContext) {
        const { value: { email, password } } = await ctx.request.body().value;
        if (!email || !password) {
          ctx.response.status = 422;
          ctx.response.body = { message: "Please provide email and password" };
          return;
        }
        let user = await User.findOne({ email });
        if (!user) {
          ctx.response.status = 422;
          ctx.response.body = { message: "Incorrect email" };
          return;
        }
        if (!compareSync(password, user.password)) {
          ctx.response.status = 422;
          ctx.response.body = { message: "Incorrect password" };
          return;
        }
    
        const key = await crypto.subtle.generateKey(
          { name: "HMAC", hash: "SHA-512" },
          true,
          ["sign", "verify"],
        );
    
        const jwt = create( { 
          alg: "HS256",
          typ: "JWT",
        }, {
          iss: user.email,
          exp: getNumericDate(
            Date.now() + parseInt(Deno.env.get("JWT_EXP_DURATION") || "0"))
        },
        key
        );
    
        ctx.response.body = {
          id: user.id,
          name: user.name,
          email: user.email,
          jwt,
        };
      }
    }
    
    export default new AuthController();

问题是什么,我该如何解决?

编辑:我在代码中添加了这一行:

console.log(await ctx.request.body().value);

结果如下:

{ name: "first", email: "first@one.com", password: "123" }

【问题讨论】:

    标签: dispatch deno


    【解决方案1】:

    您正面临此问题,因为您尝试访问 ctx.request.body().value.value.name(注意多个 value 端口)。您可以将auth_controller.ts 的第 9 行更改为此进行修复:

    const { name, email, password } = await ctx.request.body().value;
    

    顺便说一句,我还注意到您当前的代码还有一些问题。

    您的 JWT 算法和生成的密钥加密算法应该匹配

    因此,要么将 line 47 上的哈希加密更改为 SHA-256,要么将 line 53 上的 JWT 算法更改为 HS512

    您不需要将当前日期传递给getNumericDate 函数

    这个帮助函数已经为你完成了这项工作,你需要在这里传递的是你希望你的令牌过期的时间段(以秒为单位)。在您的情况下,它将是:

    getNumericDate(Deno.env.get("JWT_EXP_DURATION") || 0)}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-17
      • 2021-11-13
      • 2022-01-14
      • 2022-06-22
      • 2019-12-22
      • 2023-01-14
      • 2022-12-21
      • 2020-12-26
      相关资源
      最近更新 更多