Крюк, чтобы проверить, если пользователь аутентифицируется в перьях (без отправки неавторизованной ошибки, если нет, просто проверьте)
Я хочу реализовать простое "опубликованное" поле для документов в базе данных.
Например, если пользователь не аутентифицирован, я хочу всегда вставлять {опубликовано: true } в запросе для всех запросов на поиск / получение, поэтому он будет возвращать только опубликованные документы (полезно для внешнего интерфейса)
Но если пользователь прошел проверку подлинности и имеет необходимые роли, я хочу вернуть все документы, не только опубликованные (полезно для администратора).
Итак, я пытаюсь создать перед крючком:
// assignQuery.hook.js
const { some } = require('lodash');
const defaultOptions = {
rolesField: 'roles',
query: {},
allowRoles: []
};
module.exports = function (options) {
return async context => {
options = Object.assign({}, defaultOptions, options);
// If it was an internal call then skip this hook
if (!context.params.provider) {
return context;
}
const { user } = context.params;
// Return unchanged context if user have some "allowRoles"
if (user && options.allowRoles && options.allowRoles.length && some(options.allowRoles, (role) => {
return (user[options.rolesField] || '').includes(role);
})) return context;
// else assign query filter
context.params.query = Object.assign({}, context.params.query, options.query);
return context;
};
};
// service.hooks.js
module.exports = {
before: {
all: [],
find: [
assignQuery({ query: {published:true}, allowRoles: ['admin', 'edit'] }),
],
get: [
assignQuery({ query: {published:true}, allowRoles: ['admin', 'edit'] }),
],
create: [
authenticate('jwt'),
restrictToRoles({ roles: ['admin', 'edit']}),
],
update: [
authenticate('jwt'),
restrictToRoles({ roles: ['admin', 'edit']}),})
],
patch: [
authenticate('jwt'),
restrictToRoles({ roles: ['admin', 'edit']}),
],
remove: [
authenticate('jwt'),
restrictToRoles({ roles: ['admin', 'edit']})
]
},
};
Проблема в том, что я должен аутентифицировать пользователя, чтобы получить его роли, поэтому, если пользователь не аутентифицирован, служба отправит несанкционированную ошибку вместо разрешения ответа с отфильтрованным запросом.
Поэтому я должен вызвать аутентификацию перед assignQuery. В этом случае он будет работать нормально для администратора, но неавторизованные пользователи в front-end не смогут получить опубликованные статьи.
И если я не проверяю подлинность перед assignQuery, он хорошо работает в front-end, неавторизованные пользователи могут видеть только опубликованные статьи, но это больше не работает в админе, администраторы всегда будут получать только опубликованные статьи, потому что в хуке assignQuery, context.params.user не определен (потому что мы не проводим аутентификацию раньше...)
Поэтому мне нужен способ проверить, аутентифицирован ли пользователь, но не отправлять ему несанкционированную ошибку, если он не авторизован, я просто хочу отправить ответ на измененный запрос.
Я думаю, что мне нужно что-то вроде этого:
before: {
all: [],
find: [
unless(isAuthenticateAndHaveRoles({roles:['admin', 'edit']}),
assignQuery({ query: {published:true} })
)
],
...
Но я не знаю, как сделать аутентификацию без блокировки или хук isAuthenticate. Является ли это возможным?
Я надеюсь, что мое объяснение не так запутанно, цель состоит в том, чтобы просто внедрить в мои документы опубликованное / черновое (видимое / скрытое) (онлайн / автономное) поле.
Любая помощь приветствуется. Спасибо вам большое!
1 ответ
authenticate
Крюк в настоящее время не имеет документов allowUnauthenticated
вариант, который, если установлено true
просто реклама params.authenticated
флаг. Так
find: [
authenticate('jwt', {
allowUnauthenticated: true
}),
assignQuery({ query: {published:true}, allowRoles: ['admin', 'edit'] }),
]
Должен сделать это.