首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >羽毛.认证-管理-用户已经被验证-没有等待更改

羽毛.认证-管理-用户已经被验证-没有等待更改
EN

Stack Overflow用户
提问于 2021-04-09 09:20:14
回答 2查看 596关注 0票数 1

背景

我遵循这些指南创建电子邮件验证羽毛。

这个指南似乎被贬低了。

https://blog.feathersjs.com/how-to-setup-email-verification-in-feathersjs-72ce9882e744#.4ebe36eqp

本指南似乎较新,但步骤不完整。

https://hackernoon.com/setting-up-email-verification-in-feathersjs-ce764907e4f2

问题

我已经通过POST /users创建了一个用户

正文

代码语言:javascript
复制
{
    "email": "test@gmail.com",
    "password": "Test@1234"
}

我已经在test@gmail.com成功地收到了验证邮件。

当我发送GET /users时,用户对象如下所示:

代码语言:javascript
复制
        {
            "id": "76a47d8f-0e8d-4844-a8db-eb77e45ac947",
            "email": "test@gmail.com",
            "isVerified": "0",
            "verifyToken": "3555cad67ff8e83d24b4beadcb881e",
            "verifyExpires": "2021-04-14T09:00:07.000Z",
            "verifyChanges": {},
            "resetToken": null,
            "resetExpires": null
        },

之后,我希望通过verifyToken使用POST /authmanagement验证用户。

正文

代码语言:javascript
复制
{
      "action": "verifySignupLong",
      "value": "3555cad67ff8e83d24b4beadcb881e"
}

然后出现一个错误:

代码语言:javascript
复制
{
    "name": "BadRequest",
    "message": "User is already verified & not awaiting changes.",
    "code": 400,
    "className": "bad-request",
    "data": {},
    "errors": {
        "$className": "nothingToVerify"
    }
}

但是我以前没有做过任何验证用户的事情,而且user.isVerified仍然是"0"

源代码

代码基本上是按照上面的指南来制作的。

users.model

代码语言:javascript
复制
const Sequelize = require('sequelize');
const DataTypes = Sequelize.DataTypes;

module.exports = function (app) {
  const sequelizeClient = app.get('sequelizeClient');
  const users = sequelizeClient.define('users', {
    id: {
      allowNull: false,
      primaryKey: true,
      type: DataTypes.UUID,
      defaultValue: Sequelize.UUIDV4,
    },
    email: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: 'email'
    },
    password: {
      type: DataTypes.STRING,
      allowNull: false
    },
    isVerified: {
      type: DataTypes.STRING,
    },
    verifyToken: {
      type: DataTypes.STRING,
    },
    verifyExpires: {
      type: DataTypes.DATE,
    },
    verifyChanges: {
      type: DataTypes.JSON
    },
    resetToken: {
      type: DataTypes.STRING,
    },
    resetExpires: {
      type: DataTypes.DATE,
    },
  }, {
    hooks: {
      beforeCount(options) {
        options.raw = true;
      }
    }
  });

  users.associate = function (models) {};

  return users;
};

users.hook.js

代码语言:javascript
复制
const { iff, isProvider, keep, required, disallow, disablePagination, preventChanges} = require('feathers-hooks-common');
const { authenticate } = require('@feathersjs/authentication').hooks;
const errors = require('@feathersjs/errors');

const verifyHooks = require('feathers-authentication-management').hooks;
const accountService = require('../auth-management/notifier');

const sendVerificationEmail = require('../../hooks/sendVerificationEmail');

const {
  hashPassword, protect
} = require('@feathersjs/authentication-local').hooks;

module.exports = {
  before: {
    all: [      
      authenticate('jwt')
    ],
    find: [],
    get: [],
    create: [
      hashPassword('password'),
      required('password'),
      sendVerificationEmail(),
      verifyHooks.addVerification(),
    ],
    update: [disallow()],
    patch: [
      iff(
        isProvider('external'),
        preventChanges('email','verifyToken')
      )
    ],
    remove: [
      context => {
        if(context.params.user && context.id === context.params.user.id){
          throw new errors.Conflict('You cannot delete yourself.'); 
        }
      },
    ]
  },

  after: {
    all: [ 
      protect('password')
    ],
    find: [],
    get: [],
    create: [
      context => {
        accountService(context.app).notifier('resendVerifySignup', context.result)
      },
      verifyHooks.removeVerification()
    ],
    update: [disallow('external')],
    patch: [
      iff(
        isProvider('external'),    
        preventChanges(
          'email',
          'isVerified',
          'verifyToken',
          'verifyShortToken',
          'verifyExpires',
          'verifyChanges',
          'resetToken',
          'resetShortToken',
          'resetExpires'
        )
      )
    ],
    remove: []
  },
};

mailer.hook.js

代码语言:javascript
复制
const {disallow} = require('feathers-hooks-common');

module.exports = {
  before: {
    all: [disallow('external')],
  }
};

mailer.service.js

代码语言:javascript
复制
const hooks = require('./mailer.hooks');
const Mailer = require('feathers-mailer');
const smtpTransport = require('nodemailer-smtp-transport');

module.exports = function (app) {
  app.use('/mailer', Mailer(smtpTransport({
    service: 'gmail',
    auth: {
      user: "test@gmail.com",
      pass: "test@1234"
    }
  })));
  
  const service = app.service('mailer');
  service.hooks(hooks);
};

auth-management.hook.js

代码语言:javascript
复制
const { iff} = require('feathers-hooks-common');
const isAction = (...args) => hook => args.includes(hook.data.action);
const { authenticate } = require('@feathersjs/authentication').hooks;

module.exports = {
  before: {
    create: [
      iff(
        isAction("passwordChange", "identityChange"),
        authenticate("jwt"),
      ),
    ]
  },
};

auth-management.service.js

代码语言:javascript
复制
'use strict';
const hooks = require('./auth-management.hooks');

const authManagement = require('feathers-authentication-management');
const notifier = require('./notifier');

module.exports = function (app) {
  app.configure(authManagement(notifier(app)));
  const service = app.service('authManagement');

  service.hooks(hooks);
};

notifier.js

代码语言:javascript
复制
module.exports = function(app) {

  console.log("notifier")
  let host = app.get('host')
    function getLink(type, hash) {
      const url = 'http://localhost:3030/' + type + '?token=' + hash
      return url
    }
  
    function sendEmail(email) {
      return app.service('mailer').create(email).then(function (result) {
        console.log('Sent email', result)
      }).catch(err => {
        console.log('Error sending email', err)
      })
    }
  
    return {
      notifier: function(type, user, notifierOptions) {
        let tokenLink
        let email
        switch (type) {
          case 'resendVerifySignup': //sending the user the verification email
            tokenLink = getLink('verify', user.verifyToken)
            email = {
               from: process.env.FROM_EMAIL,
               to: user.email,
               subject: 'Verify Signup',
               html: tokenLink
            }
            return sendEmail(email)
            break
  
          case 'verifySignup': // confirming verification
            tokenLink = getLink('verify', user.verifyToken)
            email = {
               from: "test@gmail.com",
               to: user.email,
               subject: 'Confirm Signup',
               html: 'Thanks for verifying your email'
            }
            return sendEmail(email)
            break
  
          case 'sendResetPwd':
            tokenLink = getLink('reset', user.resetToken)
            email = {}
            return sendEmail(email)
            break
  
          case 'resetPwd':
            tokenLink = getLink('reset', user.resetToken)
            email = {}
            return sendEmail(email)
            break
  
          case 'passwordChange':
            email = {}
            return sendEmail(email)
            break
  
          case 'identityChange':
            tokenLink = getLink('verifyChanges', user.verifyToken)
            email = {}
            return sendEmail(email)
            break
  
          default:
            break
        }
      }
    }
  }

hooks/sendVerificationEmail.js

代码语言:javascript
复制
const accountService = '../services/auth-management/notifier'

module.exports =  options => hook => {
    if (!hook.params.provider) { return hook; }
    const user = hook.result
    if(hook.data && hook.data.email && user) {
      accountService(hook.app).notifier('resendVerifySignup', user)
      return hook
    }
    return hook
  }
EN

回答 2

Stack Overflow用户

发布于 2021-06-23 22:57:05

这已经有一段时间了,所以也许你想明白了。但我想我也是。:)

从您的用户响应:

代码语言:javascript
复制
"isVerified": "0",

根据您的用户模型:

代码语言:javascript
复制
    isVerified: {
      type: DataTypes.STRING,
    },

isVerified是一个布尔值,而字符串"0"是真实的。如果库内部正在检查if (user.isVerified),则"0"将导致该检查返回true。

我建议将用户模型的isVerified数据类型更改为DataTypes.BOOLEAN,删除当前用户,并重新创建用户。他们的isVerified应该以false而不是"0"的形式出现,问题应该得到解决。

票数 1
EN

Stack Overflow用户

发布于 2021-04-09 17:57:47

您的notifier.js没有为操作verifySignupLong实现一个句柄,只是在这里问一个显而易见的问题,您在发送给/authmanagement的请求中使用了以下操作吗?

代码语言:javascript
复制
{
      "action": "verifySignup",
      "value": "3555cad67ff8e83d24b4beadcb881e"
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67018421

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档