prisma orm_Prisma中的身份验证-第3部分:验证

prisma orm

In Part 2 of this series we covered how to generate a temporary token for our user whenever they login or create an account. Now we’re going to wrap it up by restricting our data to only certain authorized users.

本系列的第2部分中,我们介绍了如何在用户登录或创建帐户时为用户生成临时令牌。 现在,我们通过将数据限制为仅某些授权用户来进行包装。

获取我们的用户 (Getting our User)

When we create a token, we’re going to be giving it our user’s id and then use that id and jwt.verify to return data pertaining to that user if the verification was successful.

创建令牌时,如果验证成功,我们将为其提供用户ID,然后使用该ID和jwt.verify返回与该用户有关的数据。

The first step is to setup our context to handle the headers from the user’s request. If we change our context parameter to a function it will automatically have access to our request as an argument.

第一步是设置上下文,以处理来自用户请求的标头。 如果我们将context参数更改为函数,它将作为参数自动访问我们的请求。

file-name.js
文件名.js
const server = new GraphQLServer({
  typeDefs: './schema.graphql',
  resolvers,
  context(req) { return { prisma, req } }
});

Now we should be able to destructure the req object out of our context. If you try logging req you’ll see that there is a request.headers which will contain the authorization we passed into the GraphQL Playground. This is what we’ll give to jwt.verify with our secret to check if that user is valid. Since we’ll be doing this for every resolver we want to secure, let’s make it a function.

现在,我们应该能够从上下文中解构req对象。 如果您尝试记录req您将看到有一个request.headers ,其中将包含我们传递给GraphQL Playground的authorization 。 这就是我们将提供给jwt.verify的秘密信息,以检查该用户是否有效。 由于我们将对要保护的每个解析器执行此操作,因此,使其成为一个函数。

It’s pretty straightforward, we’re just getting our token from the header, removing Bearer so only the token is left, verify it, and return our user’s id.

这非常简单,我们只是从标头中获取令牌,删除Bearer ,只剩下令牌,验证令牌,然后返回用户的ID。

resolvers.js
resolvers.js
const getUser = req => {
  const authorization = req.request.headers.authorization;

  if (!authorization) throw new Error('Authentication Required');
  else {
    const token = authorization.replace('Bearer ', '');
    const user = jwt.verify(token, process.env.TOKEN_SECRET);

    return user.userId;
  }
};

架构图 (Schema)

Let’s add a few new resolvers into our schema first. We’re just going to practice with a currentUser query, deleteAccount and updateUser mutations, and a myAccount subscription.

首先让我们在架构中添加一些新的解析器。 我们只是一个练习currentUser查询, deleteAccountupdateUser突变,和myAccount订阅。

schema.graphql
schema.graphql
type Query {
  users: [User!]!
  currentUser: User!
}

type Mutation {
  createUser(data: CreateUserInput): User!
  loginUser(email: String!, password: String!): User!
  deleteAccount: User!
  updateUser(data: UpdateUserInput): User!
}

type Subscription {
  myAccount: AccountSubscription!
}

type User {
  id: ID!
  name: String!
  email: String!
  password: String! 
  token: String
}

input CreateUserInput {
  name: String! 
  email: String!
  password: String!
}

input UpdateUserInput {
  name: String 
  email: String
  password: String
}

enum MutationType {
  CREATED
  UPDATED 
  DELETED
}

type AccountSubscription {
  mutation: MutationType!
  node: User
}

查询 (Queries)

Authentication is now going to be incredibly simple, just get our user’s id with getUser and pass that to where. Now it will return data for the user that’s logged in and only that user.

身份验证现在变得非常简单,只需使用getUser获取我们的用户ID并将其传递给where 。 现在它将返回已登录用户的数据,并且仅返回该用户的数据。

resolvers.js
resolvers.js
const Query = {
  users(parent, args, { prisma }, info) { ... },
  currentUser(parent, args, { req, prisma }, info) {
    const userID = getUser(req);

    return prisma.query.user({ where: { id: userID } }, info);
  }
};

变异 (Mutations)

Mutations are just as easy, except with updates we’ll want to check if they’re changing their password first, since we’ll need to rehash it first.

变异同样容易,除了更新外,我们将要检查它们是否先更改了密码,因为我们需要先重新哈希它。

resolvers.js
resolvers.js
const Mutation = {
  async createUser(parent, { data }, { prisma }, info) { ... },
  async loginUser(parent, { email, password }, { prisma }, info) { ... },

  async deleteAccount(parent, args, { prisma, req }, info) {
    const userID = getUser(req);

    return prisma.mutation.deleteUser({ where: { id: userID } }, info);
  },
  async updateUser(parent, args, { prisma, req }, info) {
    const userID = getUser(req);

    if (typeof args.data.password === 'string') args.data.password = await bcrypt.hash(args.data.password, 10);

    return prisma.mutation.updateUser({
      where: { id: userID },
      data: args.data
    }, info);
  },
};

订阅内容 (Subscriptions)

Subscriptions are just as self-explanatory once again, just remember to add Subscription to your resolvers in index.js.

订阅再次是不言自明的,只记得在index.js中将Subscription添加到您的解析器中。

resolvers.js
resolvers.js
const Subscription = {
  myAccount: {
    subscribe(parent, args, { prisma, req }, info) {
      const userID = getUser(req);

      return prisma.subscription.user({ where: { node: { id: userID } } }, info);
    }
  }
}

总结思想 (Closing Thoughts)

That may have seemed like a lot of work, but actually using authentication is by far the easiest part of the process. The important thing is to understand how it works even though you’ll most likely be utilizing a starter boilerplate for most of your real projects.

这似乎是一项艰巨的工作,但实际上使用身份验证是该过程中最容易的部分。 重要的是要了解它是如何工作的,即使您很可能在大多数实际项目中都使用入门样板。

翻译自: https://www.digitalocean.com/community/tutorials/graphql-prisma-authentication-validation

prisma orm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值