nexus9跳过验证
This tutorial requires that you have a knowledge of GraphQL queries, mutation and context.
本教程要求您具有GraphQL查询,变异和上下文的知识。
本教程包括以下内容: (This tutorial covers the following:)
- Signup User 注册用户
- Account Activation 帐号激活
- Login User 登录用户
- Password Reset 重设密码
- Facebook Login Facebook登入
- Google Login 谷歌登录
- Admin Role (Deleting Users, Get All Users) 管理员角色(删除用户,获取所有用户)
- Get Current User 获取当前用户
这些是身份验证和授权所需的以下程序包: (These are the following packages required for authentication and authorization:)
- bcrypt: This package use to hash our passwords bcrypt:此软件包用于哈希我们的密码
- jsonwebtoken: This package use encrypt the payload, returns the token which use for authentication and we can also configure how much time this token last. jsonwebtoken:此包使用加密有效负载,返回用于身份验证的令牌,我们还可以配置此令牌的持续时间。
- node-fetch: This package use to make a fetch request node-fetch:此包用于发出提取请求
- nodemailer: This package use to send a email nodemailer:此软件包用于发送电子邮件
- graphql-middleware: This package use to apply middlewares to manage additional functionality on multiple resolvers. graphql-middleware:该软件包用于应用中间件来管理多个解析器上的其他功能。
- graphql-shield: This package helps to create a permission middleware for your application. graphql-shield:该软件包有助于为您的应用程序创建权限中间件。
安装这些软件包 (Install these packages)
yarn add bcrypt jsonwebtoken node-fetch nodemailer graphql-middleware graphql-shield google-auth-library
在此用户架构中 (In this user schema)
- id and email is unique ID和电子邮件是唯一的
- Password is not required for every user like facebook and google. 像Facebook和google这样的每个用户都不需要密码。
- ResetPasswordToken is used to check the token is not expired when resetting password ResetPasswordToken用于在重置密码时检查令牌是否未过期
- isAdmin is set to false by default 默认情况下,isAdmin设置为false
type User {
id: ID! @id
name: String!
email: String! @unique
password: String
isAdmin: Boolean @default(value: false)
resetPasswordToken: String @default(value: "")
createdAt: DateTime! @createdAt
updatedAt: DateTime! @updatedAt
}
在GraphQL服务器中定义上下文 (Define the context in the GraphQL Server)
We have to create a context type for it
我们必须为其创建上下文类型
import { Prisma } from "./generated/prisma-client";
export interface Context {
prisma: Prisma;
request: {
request: {
headers: {
authorization: string;
};
};
connection: {
context: {
Authorization: string;
};
};
};
}
After defining the context type set global context to prisma and request so we can use prisma methods and request object for getting authorization token.
定义上下文类型后,将全局上下文设置为pyramida和request,以便我们可以使用pyramida方法和request对象获取授权令牌。
const server = new GraphQLServer({
context: (req) => {
return {
request: req,
prisma,
};
},
});
创建用于注册的消息有效负载和注册输入 (Creating the Message Payload and Signup Input for Signup)
To define the mutation we need to provide the resolver return payload and the argument type ,For signup we have to define the messagePayload as our payload and signupInput as our input argument.
要定义突变,我们需要提供解析程序返回有效负载和参数类型,对于注册,我们必须将messagePayload定义为有效负载,将signupInput定义为输入参数。
import { inputObjectType, objectType } from "nexus";
export const signupInput = inputObjectType({
name: "signupInput",
definition(t) {
t.string("name", { nullable: false });
t.string("email", { nullable: false });
t.string("password", { nullable: false });
},
});
export const messagePayload = objectType({
name: "MessagePayload",
definition(t) {
t.string("message", { nullable: false });
},
});
As the message payload returns only a successful message in string and signpInput takes 3 arguments which provided by the user name, email and password.
由于消息有效负载仅返回成功的字符串消息,因此signpInput接受3个参数,这些参数由用户名,电子邮件和密码提供。
使用nodemailer创建电子邮件服务 (Creating a email service using nodemailer)
You can define any provider you want, I use gmail as a provider for sending email. It just requires email, password for a gmail account and provider name for creating a transport layer.
您可以定义任何所需的提供商,我使用gmail作为发送电子邮件的提供商。 它只需要电子邮件,gmail帐户的密码和提供者名称即可创建传输层。
If you use gmail enable less secure apps in your gmail settings. For activationEmail it requires a token and a html, so it can be look good when users can get email for activation. ResetPassword is also requires the same but it uses for forgot password functionality. SendEmail is used for actually send an email.
如果您使用gmail,请在gmail设置中启用安全性较低的应用。 对于ActivationEmail,它需要一个令牌和一个html,因此当用户可以获取用于激活的电子邮件时,它看起来会很好。 ResetPassword也需要相同,但它用于忘记密码功能。 SendEmail用于实际发送电子邮件。
import { createTransport } from "nodemailer";
type Token = string;
const transport = createTransport({
service: "gmail",
auth: {
user: process.env.GMAIL_USER,
pass: process.env.GMAIL_PASSWORD,
},
});
export default {
activationEmail(token: Token) {
// Compose email
const html = `Hi there,
<br/>
Thank you for registering!
<br/><br/>
Please verify your email by clicking the following link:
<br/>
On the following page:
<a target="_blank" href="${
process.env.CLIENT_URL
}/auth/activate/${token}">${
process.env.CLIENT_URL
}/auth/activate/${token}</a>
<br/><br/>
Have a pleasant day.`;
return html;
},
resetPassword(token: Token) {
const html = `
<h1>Please use the following link to reset your password</h1>
<a arget="_blank" href="${
process.env.CLIENT_URL
}/auth/password/reset/${token}">${
process.env.CLIENT_URL
}/auth/pas