首页 > 解决方案 > 将 CurrentUser (jwt) 设置为 @Post(在事件控制器中)

问题描述

当用户进行事件时,登录的用户 ID 应保存到数据库中

有关系

  @ManyToOne(_ => User, user => user.events, {
    eager: true,
    cascade: true
  })
  users: User;

在事件实体中(许多事件可能针对一个用户)

我的用户实体关系

  @OneToMany(_ => Event, event => event.users, {
    eager: false
  })
  events: Event[];

在数据库中,所有字段(主要 ID、名称、描述、图像、startDate、endDate)都会显示以及 users_id。据说应该包含登录的用户ID

事件控制器有一个

@Post decorator

  @Authorized()
  @Post("/events")
  @HttpCode(201)
  createEvent(@Body() event: Event) {
    return event.save();
  }

在前端,我的操作发送数据库中字段的所有值(当我创建事件时,所有值都被存储)

export const addEvent = event => (dispatch, getState) => {
  const state = getState();
  const jwt = state.currentUser.jwt;

  if (isExpired(jwt)) return dispatch(logout());

  request
    .post(`${baseUrl}/events`)
    .set("Authorization", `Bearer ${jwt}`)
    .send({
      name: event.name,
      description: event.description,
      startDate: event.startDate,
      endDate: event.endDate,
      image: event.image
    })
    .then(response =>
      dispatch({
        type: ADD_EVENT,
        payload: response.body
      })
    );
};

我还为 currentUser 发送了一个 jwt

我有一个来自我们学习使用网络套接字的样板的例子

  @Authorized()
  @Post("/games/:id([0-9]+)/players")
  @HttpCode(201)
  async joinGame(@CurrentUser() user: User, @Param("id") gameId: number) {
    const game = await Game.findOneById(gameId);
    if (!game) throw new BadRequestError(`Game does not exist`);
    if (game.status !== "pending")
      throw new BadRequestError(`Game is already started`);

    game.status = "started";
    await game.save();

    const player = await Player.create({
      game,
      user,
      symbol: "o"
    }).save();

    io.emit("action", {
      type: "UPDATE_GAME",
      payload: await Game.findOneById(game.id)
    });

    return player;
  }

创建新游戏时,它还存储创建游戏的用户

所以我认为它与 @CurrentUser() 用户有关:用户

但我不知道如何在这个项目中实现@Post eventsController

如果有人能告诉我如何以及如何以及为什么会这样,我会继续搜索。

标签: postgresqltypescriptreact-reduxtypeorm

解决方案


我改变了@Post

  @Authorized()
  @Post('/events')
  @HttpCode(201)
  async createEvent(
    @CurrentUser() user: User,
    @Body() event: Event,
  ) {
    if (user instanceof User) event.users = user

    const entity = event.save()
    return { entity }
  }
}

显然它需要一个 currentUserChecker 函数

currentUserChecker: async (action: Action) => {
    const header: string = action.request.headers.authorization
    if (header && header.startsWith('Bearer ')) {
      const [, token] = header.split(' ')

      if (token) {
        const { id } = verify(token)
        return User.findOne(id)
      }
    }
    return undefined
  }

我不得不改变 jwt.ts

import * as jwt from 'jsonwebtoken'

const secret = process.env.JWT_SECRET || '9u8nnjksfdt98*(&*%T$#hsfjk'
const ttl = 3600 * 4 // our JWT tokens are valid for 4 hours

interface JwtPayload {
    id: number
}

export const sign = (data: JwtPayload) =>
    jwt.sign({ data }, secret, { expiresIn: ttl })

export const verify = (token: string): { data: JwtPayload } =>
    jwt.verify(token, secret) as { data: JwtPayload }

import * as jwt from 'jsonwebtoken'

const secret = process.env.JWT_SECRET || '9u8nnjksfdt98*(&*%T$#hsfjk'
const ttl = 3600 * 4 // our JWT tokens are valid for 4 hours

interface JwtPayload {
    id: number
}

export const sign = (data: JwtPayload) =>
    jwt.sign({ data }, secret, { expiresIn: ttl })

export const verify = (token: string):  JwtPayload  =>
    jwt.verify(token, secret) as  JwtPayload 

推荐阅读