graphql 服务器电子邮件验证示例
Posted
技术标签:
【中文标题】graphql 服务器电子邮件验证示例【英文标题】:graphql server email verify example 【发布时间】:2018-01-15 19:23:24 【问题描述】:我开始使用带有apollo-server-express
和graphql-tools
的graphql 开发一个express API。我的注册用户流程步骤是:
用户提交用户名、邮箱和密码。
服务器通过 Mailgun 向用户发送一封电子邮件,其中包含由uuid
生成的唯一链接。
用户点击链接验证注册。
但我正在努力解决如何在解析器中绑定突变。见sn-ps:
server.js
const buildOptions = async (req, res, done) =>
const user = await authenticate(req, mongo.Users)
return
schema,
context:
dataloaders: buildDataloaders(mongo),
mongo,
user
,
done()
// JWT setting
app.use('/graphAPI',
jwt(
secret: JWT_SECRET,
credentialsRequired: false,
),
graphqlExpress(buildOptions),
res => data => res.send(JSON.stringify(data))
)
解析器突变
signupUser: async (root, data, mongo: Users ) =>
// Check existed accounts,
// if account is not exist, assign new account
const existed = await Users.findOne(email: data.email)
if (!existed)
// create a token for sending email
const registrationToken =
token: uuid.v4(),
created_at: new Date(),
expireAfterSeconds: 3600000 * 6 // half day
const newUser =
name: data.name,
email: data.email,
password: await bcrypt.hash(data.password, 10),
created_at: new Date(),
verification_token: registrationToken,
is_verified: false,
const response = await Users.insert(newUser)
// send and email to user
await verifyEmail(newUser)
return Object.assign(id: response.insertedIds[0], newUser)
// Throw error when account existed
const error = new Error('Email existed')
error.status = 409
throw error
,
// VERIFY USER
// Set verify to true (after user click on the link)
// Add user to mailist
verifiedUser: async (root, data, mongo: Users ) =>
await Users.updateOne(
email: data.email ,
set: is_verified: true,
unset: verification_token: token: ''
)
,
路由配置
routes.get('/verify?:token', (req, res, next) =>
res.render('verified', title: 'Success')
)
路由配置是我卡住的地方,因为对象通过graphqlExpress
中的上下文传递给所有解析器
任何人帮助我或为我推荐任何相关的文章。非常感谢。
【问题讨论】:
检查this comment 和我在那里提供的链接 是的,阅读这些东西是一条漫长的道路,我从中学到了很多,我被困在这里的问题是如何改变解析器以将is_verified
字段设置为 @987654330 @ 当服务器向用户发送链接 mydomain.com/verify?:token
时,用户单击该链接以确认帐户。
【参考方案1】:
似乎与其使用verifiedUser
端点,不如将该逻辑保留在/verify
路由的控制器中会更简单。比如:
routes.get('/verify?:token', (req, res) =>
Users.updateOne(
verification_token: token ,
$set: is_verified: true,
$unset: verification_token: token: ''
,
(err, data) =>
const status = err ? 'Failure' : 'Success'
res.render('verified', title: status)
)
)
【讨论】:
是的,感谢@Daniel 的帮助,我将verification_token: token: req.params.token
t 更新,(我将 set
和 unset
更改为 $set
和 $unset
作为 mongodb 文档)您将需要 3 个 graphql 端点和 1 个 apollo http 端点才能正常工作。
您可以选择将 3 个 graphql 端点合二为一,但这将是一个具有许多不同职责的大功能。
1# graphql 端点:changepass-request
需要电子邮件参数-
检查是否在 db 中找到具有此类电子邮件的用户:
生成代码
保存在本地账户节点
发送验证码到带有http链接的用户邮箱以确认验证码:
http://yoursite.com/auth/verify?code=1234
返回redirect_uri:http://yoursite.com/auth/confirm-code
用于提示输入确认码的 UI 页面
2# graphql 端点:changepass-confirm
期望代码参数: 如果在 db 中找到具有此类代码的用户,则将 redirect_uri 返回到 UI 页面,并提示新的通过,并在参数中包含确认代码:http://yoursite.com/auth/change-pass?code=12343# graphql 端点:changepass-complete
期待代码和新的通行证:-
哈希新密码
在数据库中搜索具有此类代码的本地帐户
3a。如果没有找到:
使用 redirect_uri 将错误返回到登录页面:
http://yoursite.com/auth?success=false&message="Confirmation 代码不正确,请重试。”
3b。如果找到:
更改新密码,使用 redirect_uri 将成功状态返回到登录页面:
http://yoursite.com/auth?success=true&message="ok"
4# apollo HTTP 端点:http://yoursite.com/auth/verify?code=1234
如果没有提供代码: 重定向到 UI 注册页面,并在参数中显示错误消息: http://yoursite.com/auth?success=false&message="Confirmation 代码不正确,请重试。”
如果提供了代码:在数据库中搜索具有此类代码的本地帐户 1a。如果找不到用户: 重定向到 reg ui,参数中出现错误混乱: http://yoursite.com/auth?success=false&message="Confirmation 代码不正确,请重试。” 1.b 如果用户发现: 使用新密码提示重定向到 ui 页面并将新代码附加到参数
我没有在上面放任何代码,因此您可以在其他身份验证场景中使用此工作流程。
【讨论】:
以上是关于graphql 服务器电子邮件验证示例的主要内容,如果未能解决你的问题,请参考以下文章
如何更改验证邮件中`GRAPHQL_AUTH`中的`frontend_domain`端口?