graphql server email验证示例

时间:2017-08-08 09:32:48

标签: express graphql apollo-server

我开始使用带有apollo-server-expressgraphql-tools的graphql来处理快速API。我的注册用户流程步骤是:

  1. 用户提交用户名,电子邮件和密码。

  2. 服务器通过Mailgun向用户发送一封电子邮件,其中包含由uuid生成的唯一链接。

  3. 用户点击链接验证注册。

  4. 但我正在努力解决如何在解析器中绑定突变的问题。请参阅片段:

    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内的上下文传递给所有解析器

    任何人帮助我或建议任何相关的文章。非常感谢。

2 个答案:

答案 0 :(得分: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})
    }    
  )
})

答案 1 :(得分:0)

您需要 3 个 graphql 端点和 1 个 apollo http 端点才能正常工作。

或者,您可以将 3 个 graphql 端点合并为一个,但这将是一个具有许多不同职责的大功能。

1# graphql 端点:changepass-request

  • 需要电子邮件参数
  1. 检查是否在数据库中找到了具有此类电子邮件的用户:
  2. 生成代码
  3. 保存在本地账户节点
  4. 使用http链接将代码发送到用户电子邮件以确认代码: http://yoursite.com/auth/verify?code=1234
  5. 返回redirect_uri:http://yoursite.com/auth/confirm-code 用于提示输入确认码的 UI 页面

2# graphql 端点:changepass-confirm

3# graphql 端点:changepass-complete

  • 期待代码和新通行证:
  1. 哈希新密码
  2. 用这样的代码在数据库中搜索本地帐户 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

我没有在上面放任何代码,因此您可以在其他身份验证场景中使用此工作流程。