Крюк, чтобы проверить, если пользователь аутентифицируется в перьях (без отправки неавторизованной ошибки, если нет, просто проверьте)

Я хочу реализовать простое "опубликованное" поле для документов в базе данных.

Например, если пользователь не аутентифицирован, я хочу всегда вставлять {опубликовано: 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'] }),
]

Должен сделать это.

Другие вопросы по тегам