背景
我遵循这些指南创建电子邮件验证羽毛。
这个指南似乎被贬低了。
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创建了一个用户
正文
{
"email": "test@gmail.com",
"password": "Test@1234"
}我已经在test@gmail.com成功地收到了验证邮件。
当我发送GET /users时,用户对象如下所示:
{
"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验证用户。
正文
{
"action": "verifySignupLong",
"value": "3555cad67ff8e83d24b4beadcb881e"
}然后出现一个错误:
{
"name": "BadRequest",
"message": "User is already verified & not awaiting changes.",
"code": 400,
"className": "bad-request",
"data": {},
"errors": {
"$className": "nothingToVerify"
}
}但是我以前没有做过任何验证用户的事情,而且user.isVerified仍然是"0"
源代码
代码基本上是按照上面的指南来制作的。
users.model
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
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
const {disallow} = require('feathers-hooks-common');
module.exports = {
before: {
all: [disallow('external')],
}
};mailer.service.js
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
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
'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
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
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
}发布于 2021-06-23 22:57:05
这已经有一段时间了,所以也许你想明白了。但我想我也是。:)
从您的用户响应:
"isVerified": "0",根据您的用户模型:
isVerified: {
type: DataTypes.STRING,
},isVerified是一个布尔值,而字符串"0"是真实的。如果库内部正在检查if (user.isVerified),则"0"将导致该检查返回true。
我建议将用户模型的isVerified数据类型更改为DataTypes.BOOLEAN,删除当前用户,并重新创建用户。他们的isVerified应该以false而不是"0"的形式出现,问题应该得到解决。
发布于 2021-04-09 17:57:47
您的notifier.js没有为操作verifySignupLong实现一个句柄,只是在这里问一个显而易见的问题,您在发送给/authmanagement的请求中使用了以下操作吗?
{
"action": "verifySignup",
"value": "3555cad67ff8e83d24b4beadcb881e"
}https://stackoverflow.com/questions/67018421
复制相似问题