Ответы пользователя по тегу Node.js
  • Как передать переменную из одной сцены в другую?

    IgorPI
    @IgorPI
    Сессия и её абстрактное понятие.

    Я недавно написал универсального бота, хотя опыта в строение ботов не было.
    Так вот, как раз там есть сессия.
    Сессия позволяет изменять поведение диалога по ходу пьесы.

    Приведу пример моего велосипеда.

    Интерфейс сессии
    export interface SessionInterface {
        bot: BotInterface;
        state: SessionStateInterface;
        initialState: SessionStateInterface;
        SID: string;
        isNew: boolean;
        inDialog: boolean;
        user: UserInterface;
        send(message: any, options?: any): Promise<any>;
        resetState(): void;
        setState(state: SessionStateInterface): void;
    }


    Интерфейс состояния сессии
    export interface SessionStateInterface {
        [key: string]: any;
    }


    А это реализация описанных интерфейсов
    interface SessionConstructorPropsInterface {
        bot: BotInterface;
        initialState?: SessionStateInterface;
    }
    
    export class Session implements SessionInterface {
        bot: BotInterface;
        user: UserInterface;
        state: SessionStateInterface;
        initialState: SessionStateInterface;
        SID: string;
        isNew: boolean;
        inDialog: boolean;
        constructor({  bot, initialState }: SessionConstructorPropsInterface) {
            this.isNew = true;
            this.bot = bot;
            this.initialState = initialState || {};
            this.state = Object.assign({}, initialState);
        }
    
        send(message: any, options: any): Promise<void> {
            this.isNew = false;
            return this.bot.adapter.send(message, options);
        }
    
        resetState(): void {
            this.state = Object.assign({}, this.initialState);
        }
    
        setState(state: SessionStateInterface): void {
            Object.keys(state).forEach((key) => {
                this.state[key] = state[key];
            });
        }
    }


    Например, в диалоге | обработчике диалога
    main.use(/\/login/i, async ({message, session}: BotContextInterface, next) => {
    
      // Здесь я сохраняю состояние
      session.setState({
        processLogin: true,
        processLoginStep: 'login'
      })
    
      // Если мне нужно получить состояние
      console.log(session.state.processLogin)
    
    });


    Описанный выше код позволяет хранить состояние бота
    Ответ написан
  • Node JS или Python для бэкенда?

    IgorPI
    @IgorPI
    Symfony/rest api
    Одна ORM чего стоит.
    Подумайте о других.

    А нода для фронта, какой-нибудь реакт или vue
    Ответ написан
  • Как реализовать создание пользователей с не базовой ролью в приложении с RBAC?

    IgorPI
    @IgorPI
    Я тоже сейчас работаю с RBAC но только в Symfony
    Все сводится к тому, что в тех или иных методах вызваться некая функция, которая проверяет наличие атрибута разрешающего доступ.

    Только в Symfony есть так называемое голосование. (Voters)

    Приведу пример:
    <?php
    
    
    namespace App\Security\Administrator\Voter;
    
    
    use App\Entity\User;
    use App\Entity\UserGroup;
    use Exception;
    use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
    use Symfony\Component\Security\Core\Authorization\Voter\Voter;
    
    /**
     * Class UserVoter
     * @package App\Security\Administrator\Voters
     */
    class UserVoter extends Voter implements IVoter
    {
    
        public const CREATE_USERS = 'create_users';
        public const EDIT_USERS = 'edit_users';
        public const DELETE_USERS = 'delete_users';
        public const VIEW_USERS = 'view_users';
        public const VIEW_CONTACTS = 'view_contacts';
        public const SET_PRIVILEGES_USERS = 'set_privileges_users';
    
    
        /**
         * @param string $attribute
         * @param mixed $subject
         * @return bool
         */
        protected function supports($attribute, $subject)
        {
            if (!in_array($attribute, $this->getAttributes())) {
                return false;
            }
    
            return true;
        }
    
    
        /**
         * @param string $attribute
         * @param mixed $subject
         * @param TokenInterface $token
         * @return bool
         */
        protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
        {
            $user = $token->getUser();
    
            if (!$user instanceof User) {
                return false;
            }
    
            $permissions = [];
            try {
                if (is_a($user->getGroup(), UserGroup::class)) {
                    $permissions = $user->getGroup()->getPermissions();
                }
    
                foreach ($permissions as $permission) {
                    if (in_array($permission, $this->getAttributes())) {
                        return true;
                    }
                }
    
                return false;
            }catch (Exception $exception) {
                return false;
            }
        }
    
    
        /**
         * @return string[]
         */
        public function getAttributes()
        {
            return [
                self::CREATE_USERS,
                self::EDIT_USERS,
                self::DELETE_USERS,
                self::VIEW_USERS,
                self::VIEW_CONTACTS,
                self::SET_PRIVILEGES_USERS
            ];
        }
    }


    В контроллере
    ...
    $this->denyAccessUnlessGranted(UserVoter::CREATE_USERS, null, "Вам запрещено создавать пользователей.");
    ...


    У каждого юзера должны быть те самые атрибуты разрешающие доступ, если у юзера нет аттрибутов то и доступа нет.

    Базовый атрибут это например строка в базе "user"
    У каждого юзера гарантировано должен быть базовый аттрибут иначе доступа не будет.

    Это не ответ, я делюсь своим опытом.
    Ответ написан
  • Какой метод использовать для проверки жизни jwt токена?

    IgorPI
    @IgorPI
    В ручную.

    Когда вы получили токен, вам нужно извлечь полезную нагрузку, в ней должны быть: информация о времени выдачи и когда истекает.

    Вот и проверяйте.
    Ответ написан
    Комментировать
  • Как разграничить окружение для 2х приложений на nodejs на одном сервере?

    IgorPI
    @IgorPI
    Запустите ваши приложения в двух разных контейнерах docker с помощью docker-compose
    Ответ написан
  • Как запушить массив в объект по условию?

    IgorPI
    @IgorPI
    Коллега, ваша ошибка заключается в том, что внутри цикла, код асинхронный.
    Вывод в консоль произойдёт раньше чем вы ожидаете.

    Вот тут я неаккуратно изобразил анимацию, но суть верна и явно отражает вашу проблему.
    Курсором я показываю очерёдность выполнения кода.
    Следите за курсором.

    5e0045b9d103a652034367.gif
    Итог:
    На момент вывода в консоль menuOtd пуст
    Тип ошибки: логическая
    Ответ написан
    Комментировать
  • Как использовать Nuxt в Docker?

    IgorPI
    @IgorPI
    Я так понимаю, что нужно использовать два конфига: docker-dev/docker-prod и nginx/dev nginx/prod
    Но я не могу понять как и тот и другой настроить правильно для двух режимов? Можете помочь?


    Привожу пример

    Development configuration
    # Development configuration
    version: "3.1"
    
    services:
    
      # Php application
      app:
        container_name: cc.app
        build:
          context: .
          dockerfile: ./docker/php/Dockerfile-dev
        restart: on-failure
        volumes:
          - .:/www
          - ./docker/php/log:/var/log
          - ./docker/php/usr/local/etc/php/conf.d:/usr/local/etc/php/conf.d
        depends_on:
          - db
        links:
          - db
        expose:
          - 9000
        environment:
          PHP_INI_SCAN_DIR: ":/usr/local/etc/php/conf.d"
    
    
      # Database
      db:
        image: percona:latest
        container_name: cc.db
        restart: on-failure
        ports:
          - 127.0.0.160:3306:3306
        expose:
          - 3306
        environment:
          - MYSQL_ROOT_PASSWORD=rk3kw1UDdqOEF4L1pmNkcyQ2oL
          - MYSQL_DATABASE=cc
          - MYSQL_ROOT_HOST=%
    
    
    
      # Nginx api server
      nginx-api:
        container_name: cc.nginx-api
        image: nginx:latest
        restart: on-failure
        volumes:
          - ./docker/nginx/dev/nginx.conf:/etc/nginx/nginx.conf
          - ./docker/nginx/dev/sites-enabled/vhost-api.conf:/etc/nginx/sites-enabled/vhost-api.conf
        ports:
          - 127.0.0.160:8090:80
        depends_on:
          - app
        expose:
          - 80
        command: ["nginx", "-g", "daemon off;"]
    
    
    
      # Nginx admin server
      nginx-admin:
        container_name: cc.nginx-admin
        image: nginx:latest
        restart: on-failure
        volumes:
          - ./docker/nginx/dev/nginx.conf:/etc/nginx/nginx.conf
          - ./docker/nginx/dev/sites-enabled/vhost-admin.conf:/etc/nginx/sites-enabled/vhost-admin.conf
        ports:
          - 127.0.0.160:8091:80
        depends_on:
          - app
        expose:
          - 80
        command: ["nginx", "-g", "daemon off;"]
    
    
      # Nginx secure server
      nginx-secure:
        container_name: cc.nginx-secure
        image: nginx:latest
        restart: on-failure
        volumes:
          - ./docker/nginx/dev/nginx.conf:/etc/nginx/nginx.conf
          - ./docker/nginx/dev/sites-enabled/vhost-secure.conf:/etc/nginx/sites-enabled/vhost-secure.conf
        ports:
          - 127.0.0.160:8092:80
        depends_on:
          - app
        expose:
          - 80
        command: ["nginx", "-g", "daemon off;"]


    Production configuration
    # Production configuration
    version: "3.1"
    
    services:
    
      # Php application
      app:
        container_name: ruintouch.app
        restart: always
        build:
          context: .
          dockerfile: ./docker/php/Dockerfile-prod
        expose:
          - 9000
    
    
    
      # Nginx api server
      nginx-api:
        container_name: ruintouch.nginx-api
        image: nginx:latest
        restart: always
        volumes:
          - ./docker/nginx/prod/nginx.conf:/etc/nginx/nginx.conf
          - ./docker/nginx/prod/sites-enabled/vhost-api.conf:/etc/nginx/sites-enabled/vhost-api.conf
        ports:
          - 8095:80
        expose:
          - 80
        command: ["nginx", "-g", "daemon off;"]
    
    
    
      # Nginx admin server
      nginx-admin:
        container_name: ruintouch.nginx-admin
        image: nginx:latest
        restart: always
        volumes:
          - ./docker/nginx/prod/nginx.conf:/etc/nginx/nginx.conf
          - ./docker/nginx/prod/sites-enabled/vhost-admin.conf:/etc/nginx/sites-enabled/vhost-admin.conf
        ports:
          - 8096:80
        expose:
          - 80
        command: ["nginx", "-g", "daemon off;"]
    
    
    
          #Nuxt publication
      nuxt-public:
        container_name: ruintouch.nuxt_public
        restart: always
        build:
          context: ./nuxt_public
          dockerfile: Dockerfile-prod
        ports:
          - "3001:3000"
        expose:
          - "3000"


    С "vue hot reload in docker" увы ((
    Ответ написан
  • Nuxt.js - Как перенаправить с localhost на домен сайта?

    IgorPI
    @IgorPI
    Как минимум выкинуть Apache.

    Использовать Nginx в режиме прокси.

    Пример базовой конфигурации nginx
    server {
        listen      			<ip>:<port>;
        server_name 			<ваш домен>;
    
        location / {
    	proxy_pass  		http://127.0.0.1:3000;	
    	#proxy_read_timeout	2s
            proxy_set_header	Host $host;
            proxy_set_header	X-Real-IP $remote_addr;
            proxy_set_header	X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header	X-Forwarded-Host $server_name;
        }
    }
    Ответ написан
    Комментировать