• Как реализовать авторизацию пользователя на стеке React Redux Node?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Пригодится jwt. (гугл)

    В общих словах: вам нужно выдать юзеру токен. С этим токеном юзер будет выполнять запросы к вашим защищенным методам api (вы можете оставить какие-то методы "без токена").

    Node.js часть
    Пример роута на логин (сделано не лучшим образом, в плане коллбэков, но что нашлось под рукой...):

    auth.js
    ...
    const v4 = require('node-uuid').v4
    const jwt = require('jsonwebtoken')
    ...
    router.post('/signin', (req, res, next) => {
    
      // валидация, например... 
    
      if (errors) {
        return res.status(400).json({ errors })
      } else {
        // поиск юзера в базе, сравнение хэша и прочие необходимые операции
        ...
       // допустим все ок, нужно ответить токеном
      // генерируем необходимые опции и сам токен
    
            const payload = {
              _id: user._id,
              iss: 'http://localhost:3000',
              permissions: 'poll',
            }
            const options = {
              expiresIn: '7d',
              jwtid: v4(),
            }
            const secret = new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64')
            jwt.sign(payload, secret, options, (err, token) => {
              // отвечаем токеном, для будущих запросов с клиента
              return res.json({ data: token })
            })
         ...
    })
    
    module.exports = router;


    Пример защищенного роута (метода, который требует токен):
    ...
    const jwt = require('jsonwebtoken')
    const Poll = require('../models/poll')
    ...
    
    const requireToken = (req,res,next) => {
      const token = req.headers['x-api-key']
      const secret = new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64')
    
      jwt.verify(token, secret, (err, decoded) => {
        if (err) {
          return res.status(401).json({ error: err.message })
        }
        req.params.userId = decoded._id
        next()
      })
    }
    ...
    
    // обратите внимание на requireToken - функция вызывается при каждом обращении к роуту
    // то есть при каждом PUT запросе по адресу (например: PUT api/v1/products/1238914)
    // будет вызываться requireToken
    
    router.put('/:id', requireToken, (req, res, next) => {
      const { productId } = req.body
      const userId = req.params.userId
    
      Poll.findById(req.params.id)
        .populate({ path: 'products' })
        .exec((err, poll) => {
            // ... необходимые действия в базе, в процессе успешного зачтения голоса...
        }
    })


    Клиентское приложение:

    Типичный ActionCreator (в качестве библиотеки для запросов можно взять bluebird, isomorphic-fetch, да хоть нативный xhr)
    actions/LoginActions.js

    export function login(data) {
      return dispatch => {
        dispatch({ type: LOGIN_REQUEST })
    
        // request в данном случае - https://github.com/KyleAMathews/superagent-bluebird-promise
        return request.post(`${API_ROOT_V1}/auth/signin`)
          .send(data)
          .then(res => {
            if (!res.ok) {
              dispatch({ type: LOGIN_FAILURE })
            } else {
              dispatch({
                type: LOGIN_SUCCESS,
                data: res.body.data,
              })
              //сохранение токена в localStorage
              localStorage.setItem('cks_token', res.body.data)
            }
          }, err => {
            dispatch({ type: LOGIN_FAILURE })
          })
      }
    }


    Пример голосования с токеном (выше, в node.js части был метод апи, а это PUT запрос с клиента)

    export function vote(productId, voteId) {
      return dispatch => {
        dispatch({ type: POLL_VOTE_REQUEST })
    
        return request.put(`${API_ROOT_V1}/api/v1/vote/${voteId}`)
          .set('X-API-Key', localStorage.getItem('cks_token')) // установка ТОКЕНА в заголовок 'X-API-Key'
          .send({ productId })
          .then(res => {
            if (!res.ok) {
              dispatch({ type: POLL_VOTE_FAILURE })
            } else {
              dispatch({
                type: POLL_VOTE_SUCCESS,
                data: normalize(res.body.data, schema.poll),
              })
            }
          }, err => {
            dispatch({ type: POLL_VOTE_FAILURE })
          })
      }
    }


    Надеюсь код формы с кнопкой "голосовать" не трубется.
    ====

    Все это можно организовать удобнее, например, выставлять токен всем запросам автоматически (речь про клиентскую часть):
    import fetch from 'isomorphic-fetch'
    ...
    const defaultHeaders = {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    }
    
    function buildHeaders() {
      const authToken = localStorage.getItem('TOKEN')
      return { ...defaultHeaders, Authorization: authToken }
    }
    ...
    export function httpPost(url, data) {
      const body = JSON.stringify(data)
    
      return fetch(url, {
        method: 'post',
        headers: buildHeaders(),
        body: body,
      })
      .then(... код оработки запроса ...)
    }


    ===

    Проверить наличие токена, можно с в роутере, с помощью хука на onEnter.

    root.js
    ...
    <Provider store={store}>
          <Router history={routerHistory}>
            {configRoutes(store)} // Роуты создаются функцией, чтобы можно было использовать внутри нее store.getState()
          </Router>
        </Provider>
    ...


    routes.js
    export default function configRoutes(store) {
      function _ensureAuthenticated(nextState, replace, callback) {
        const { dispatch } = store
        const { session } = store.getState()
        const { currentUser } = session
        let nextUrl
    
        if (!currentUser && localStorage.getItem('cks.token')) {
          dispatch(getCurrentAccount())
        } else if (!localStorage.getItem('cks.token')) {
          replace('/signin')
        }
        callback()
      }
    
      return (
        <Route path='/' component={App}>
          <Route path='/signin' component={SigninContainer} />
          <Route path='/signup' component={SignupContainer} />
    
          <Route path='/locked' component={AuthenticatedContainer} onEnter={_ensureAuthenticated}>
            <Route component={LockedArea}>
              <Route path='/locked/a' component={A} />
              <Route path='/locked/b/:id' component={B} />
              <Route path='/locked/c' component={C} />
            </Route>
          </Route>
        </Route>
      )


    Остается только создать AuthenticatedContainer в котором проверять: есть ли currentUser (в рамках этого примера) и если нет - возвращать false. А если есть - this.props.children (в которых будут дальнейшие роуты..)
    ===

    Итого:
    1) у вас есть API написанное на node.js.
    2) У этого API есть защищенные методы, которые проверяют наличия токена в http-запросе. Токен выдается при запросе на логин. Само собой, операция логина (то есть POST запрос на your-api/login) не требует токена.
    3) После удачного логина, вы получаете в ответе на свой запрос токен (это уже внутри клиентского кода, и если мы говорим о redux - то внутри асинхронного вызова в actions)
    4) Сохраняете токен (например, в localStorage)
    5) Во все необходимые http-запросы устанавливаете заголовок с токеном
    Ответ написан
    15 комментариев
  • Can't set headers after they are sent?

    MarcusAurelius
    @MarcusAurelius
    автор Impress Application Server для Node.js
    Если делаете redirect, то next уже не нужен. Цепочки мидлверов на том и стоят, что передавать дальше нужно только в том случае, если запрос еще не обработан.
    Ответ написан
    Комментировать
  • Пишут ли проекты на чистом JS?

    BuriK666
    @BuriK666
    Компьютерный псих
    Пишут, если производительность важна, а скорость разработки - нет.
    шутка на тему
    ssRUr.gif
    Ответ написан
    3 комментария
  • Возможно ли выжать все соки из vue.js без webpack?

    dosya97
    @dosya97 Автор вопроса
    Fullstack web-developer
    А webpack то оказался совсем легким! Один единственный файл генерит. Его просто нужно правильно вызвать. В статик пихнуть)))) Все теперь мы программируем на новом уровне мазафак)))
    Ответ написан
    1 комментарий
  • Как сверстать данную часть?

    @deworkers
    Middle front-end, UI designer
    есть. Называется
    position: absolute;
    Ответ написан
    2 комментария
  • Как заставить бота не отправлять сообщение?

    @nllm
    нет
    Ответ написан
    Комментировать
  • Почему, когда видеокарта без нагрузки, может зависать система?

    @generalx
    Системный администратор
    и дрова, обязательно актуальные дрова
    Ответ написан
    2 комментария
  • Почему, когда видеокарта без нагрузки, может зависать система?

    nazarpc
    @nazarpc
    Open Source enthusiast
    Можно попробовать исправить проблему разгоном:)
    Повысьте минимальную частоту работы видеоядра в простое/2D, может помочь.
    Ответ написан
    1 комментарий
  • Кто что может посоветовать по воркфлоу в верстке?

    matroskin13
    @matroskin13
    JavaScript developer, GO developer
    gulp - найс
    git - его надо юзать всегда, это как зубы с утра почистить.
    vendor - для этого используйте bower, и собирайте их в один файл для минификации
    к слову о минификации - это относится ко всему вашему js и css коду
    я юзаю не лайврелоад, а browsersync

    P.S yeoman гляньте
    Ответ написан
    Комментировать
  • Кто такие Rockstar/Ninja/Guru/Wizard/Jedi developer?

    vvpoloskin
    @vvpoloskin
    Инженер связи
    Станешь Ninja, узнаешь.

    А вообще если нет нужного скила, не нужно откликаться на работу. Если им нужен джедай или волшебник с навыками программирования, а ты не умеешь махать лазерным мечом, ты явно не подходишь.
    Ответ написан
    Комментировать
  • Кто такие Rockstar/Ninja/Guru/Wizard/Jedi developer?

    IonDen
    @IonDen
    JavaScript developer. IonDen.com
    Термины равнозначны, используются для обозначения очень крутых профи.
    Каждый использует тот термин, который ему больше нравится. Вроде того что если вы фанат Звездных войн, то теперь вы джедай)
    Ответ написан
    Комментировать
  • Из математика в front-end разработчика. С чего начать?

    globuzer
    @globuzer
    gezgrouvingus progreszive ombusgrander greyderzux
    мне кажется вам прямая дорога в data-science, data mining, machine learning, neuro-technology, и подобные околонаучные и основанные на математике вещи, притом не фриланс, а нормальные штатные конторы, занимающиеся серьезными вещами, притом не только в РФ, но и за рубежом, возможно удаленная работа. и интересно, и близко к вам по направлению и высокооплачиваемо.
    а зачем вам веб? менять шило на мыло, притом с этим мылом вы будете отстовать от других специалистов, кто в этой области уже давно. зато с математикой в области обработки данных вы будете на равне, а то и может быть впереди остальных, у кого мало математического опыта. единственное вам нужно поднатаскаться в программировании, алгоритмах, языках Python, C, C++, C#, R, Statistica, Wolfram, параллельным вычислениям, все что наукоемкое....
    Ответ написан
    3 комментария
  • Из математика в front-end разработчика. С чего начать?

    @Espleth
    И вот скажите, нафига вам фронт-энд? Вы бросаете математику потому что она вам надоела, или потому что вы не можете ей зарабатывать нормально? Судя по посту - второе, а значит С++ в руки и идите пилить алгоритмы, где нужна математика. Всякие Яндексы и Гуглы таких любят, и платить будут хорошо.
    Ответ написан
    4 комментария
  • Верстка как профессия скоро умрет?

    @suslik2015
    Пока будешь мучиться с графическим интерфейсом, верстальщик-профессионал сверстает в 2-3 раза больше. Единственно - снижение уровня входа в профессию, но он и так в верстке не высок.
    Разработчики сервисов всяких могут обещать все, что угодно - это их работа.
    Ответ написан
    Комментировать
  • Может ли NodeJS работать как PHP?

    zBit
    @zBit
    Full stack web developer
    Запускайте Node приложения через grunt с настроенным autoreload'ом. В итоге получите то что хотели: изменили файл, и сервак перезапустится, вы сразу увидите изменения.
    Ответ написан
    Комментировать
  • Может ли NodeJS работать как PHP?

    nowfine
    @nowfine
    сисадмин 30+ левел
    эй эй, @anonrab, полегче.

    если непредвзято взглянуть, то php скрипт тоже надо запускать. Раньше ручками, а потом научили делать это вебсервер.
    Так и для ноды лишь надо найти крайнего и перепоручить ему запуск ноды.
    в этом крон не прихотлив.
    cgi с апачи или ынджайникса - тоже.
    Есть еще init скрипты при старте системы, там можно даже обработчика своего сделать который будет перезапускать твою ноду. А можно даже ноду написать которая сама себя перезапустит, обновит строчку или отправит письмо.

    ps. ссылка битая на script.js
    pps. А php всем плох, кроме того, что, черт возьми, все еще работает, "пока работает сервер".

    и да, самое главное забыл - thatextramile.be/blog/2012/01/hosting-a-node-js-si...
    Ответ написан
    1 комментарий
  • Может ли NodeJS работать как PHP?

    k12th
    @k12th
    console.log(`You're pulling my leg, right?`);
    Конечно. Все, что вам нужно -- http-сервер с поддержкой CGI (тот же апач) и пишите скрипты c заголовком #!/usr/bin/env node. Вот что-то такое уже даже сделали: larsjung.de/node-cgi/.

    Не совсем как PHP, потому что mod_php работает несколько по другому, но эффект тот же: медленно, каждый раз запускается интерпретатор с нуля и прочие прелести устаревших решений:)
    Ответ написан
    6 комментариев
  • Может ли NodeJS работать как PHP?

    Может. Только не стоит - теряются все плюсы и Node.js превращается в такое же унылое говно, как и PHP - слишком большое время инициализации скрипта. Программа на Node точно такая же, как и на PHP и любом другом языке. Вот только обычно программы на PHP взаимодействуют с web-сервером через cgi протокол, а программы на Node запускают собственный web-сервер и получают либо запросы напрямую, либо от основного web-сервера. Никто не мешает положить скрипт в папку, первой строчкой скрипта прописать интерпретатор, прописать возможность запуска в каком-нибудь Apache и выводить данные через console.log вместо echo.
    Ответ написан
    Комментировать
  • Как отследить изменение URL адреса js скриптом?

    Taraflex
    @Taraflex
    Ищу работу. Контакты в профиле.
    Ответ написан
    Комментировать