2017-02-06 5 views
3

У меня есть узловое приложение, использующее токен json web:Где лексен json web сохраняет данные?

var jwt = require ('jsonwebtoken');

Если вход в систему succedes, то эта библиотека создает маркер таким образом:

var payload = {mydata: 'abcd'}; 
var token = jwt.sign(payload, 'secret', { 
    expiresIn: 28800 
}); 

return { 
    success: true, 
    message: 'Success', 
    token: token 
}; 

То, что я не понимаю, где маркер хранится на сервере. Если же пользователь, который получил маркер делает вызов к защищенному ресурсу, то у меня есть эта строка:

jwt.verify(token_sent_by_used, 'secret', function (err, res) { 
    if(!err){ 
     res.json({result: 'success'}); 
    } 
    else{ 
     res.json({result: 'failure'}); 
    } 
} 

Причина Im спрашивая это, что я не мог найти объяснение о том, как обращаться с JWT при запуске приложение на нескольких машинах. Если мой бэкенд помещается на разные машины, и пользователь делает запросы к балансировщику нагрузки, тогда запрос может попасть на любую машину. Если jwt записывает данные о токенах в файловой системе, то, я думаю, может возникнуть проблема, если запрос попадает на машину, которая не была той, которая создала токен. При использовании сеанса вы можете установить обработчик сеанса в базу данных. Как вы решаете это с помощью jwt?

**** EDIT ****

Хорошо, давайте возьмем eaxmple. У меня есть приложение-узел, которое работает на компьютере .10, и одно и то же приложение узла также работает на компьютере .11. Две разные машины.

Я иду на машину .10 и отправляю имя пользователя. Приложение на машине .10 проверяет имя пользователя/пароль. Они в порядке. Машина .10 создает токен jwt и отправляет его мне.

Теперь я делаю запрос на завихрение (ресурсу, который требует действительного jwt-token), на машину .11 и отправляет jwt-токен, который был отправлен мне. Машина .11 не будет жаловаться на jtw-токен? Это будет считаться действительным? Даже если он не был создан на машине .11?

+1

Значок Jwt не хранится на сервере. После создания сервера маркеров jwt отправьте этот токен пользователю/браузеру. Затем вы можете сохранить этот токен либо в состоянии приложения, либо в локальном хранилище браузера, либо в хранилище сеансов браузера. –

+0

Пожалуйста, взгляните на отредактированный вопрос. – oderfla

+1

Значок Jwt не имеет ничего общего с машиной. Вам просто нужен один и тот же секретный ключ на обеих машинах для дешифрования/шифрования токена. –

ответ

3

Оба сервера вашего вопроса должны быть в состоянии проверить токен - они должны иметь возможность генерировать подпись. Если на обоих серверах используется один и тот же секретный ключ (используемый для первоначального создания сигнатуры маркера на .10), то оба они смогут проверить его содержимое.

На скриншоте ниже, как красная часть, так и фиолетовая часть являются открытым текстом - каждый может читать и изменять их. Тем не менее, синяя часть является специальной - она ​​может быть сгенерирована только на сервере, от красных и фиолетовых частей, с использованием секретного ключа. Таким образом, это гарантирует, что красные и фиолетовые части не были подделаны.

enter image description here

Итак, когда вы отправить весь JTW обратно на сервер, он может использовать секретный ключ для генерации синей части и сравнить его с синей частью, что вы представляемой. Если они не совпадают, то кто-то (незаконно) изменил красную или фиолетовую части, поэтому аутентификация запрещена.

2

JWT не хранятся на сервере.

Когда ваш сервер передает JWT, он предоставляет клиенту пропуск посетителя, который может использоваться всякий раз, когда он запрашивает ресурс. Пока клиент сохраняет его, и он остается в силе (т. Е. Не истек), он может отобразить его на сервере с запросом, и сервер ответит соответствующим образом.

Сервер знает, что это действительный проход, потому что он подписал его со своим секретом.

Что касается работы на нескольких машинах, если любой сервер, который должен проверить токен, знает секрет, он может это сделать.

Редактировать, чтобы уточнить выше

Вы спрашиваете, будет ли конкретно машина A. принимает маркер, который был выдан машиной В.

Требование только для приема маркеров, заключается в проверке подписи так что вы можете проверить, откуда оно взялось.

Если машина A и машина B разделяют секрет, их жетоны взаимозаменяемы. В обоих нет разницы, и машина A не сможет определить, выдал ли он токен или машина B.

+0

Пожалуйста, взгляните на отредактированный вопрос. – oderfla

+1

Я прояснил свою последнюю строку немного для вас. если машины .10 и .11 имеют один и тот же ключ, их токены взаимозаменяемы – JamesT

1

Нигде маркер не сохраняется на сервере. В documentation вы можете прочитать

Аутентификация: это наиболее распространенный сценарий использования JWT. После входа пользователя в систему каждый последующий запрос будет включать JWT, позволяя пользователю получать доступ к маршрутам, службам и ресурсам, которые разрешены с помощью этого токена.

Вы должны понять:

  • При получении запроса на вход в систему, вы вернете маркер пользователя (если запрос действителен)
  • На каждом запросе, клиент будет посылать вам верните токен, и вы сможете проверить, соответствует ли этот токен тому, который вы отправили. Большая часть времени, маркер будет предоставлен в заголовке запроса, так и на стороне сервера, вы сможете получить к нему доступ с помощью req.headers[<token_property_here>]

Тогда, чтобы проверить, что вам нужно будет запустить этот вид кода

jwt.verify(req.headers['x-auth-token'], 'secret', function (err, res) { 
    if(err){ 
     return res.json({result: 'failure'}); 
    } 
    // Else do something else 
} 
1

С помощью jwt вы можете сохранить токен на клиенте. Обычно на localStorage или sessionStorage вы отправляете токен каждый раз, когда вы делаете запрос в заголовке авторизации.
Или как рекомендуемый способ stormpath, вы сохраняете jwt на cookie с httpOnly и безопасными флагами (читайте объяснение).
Таким образом, каждый раз, когда ваш пользователь должен получить доступ к ресурсу, вам необходимо проверить cookie.
В экспресс при создании JWT вы сохраните его в печенье с:

res.cookie('token', jwt, { httpOnly: true, secure: true }); 

Затем вы можете создать промежуточное программное обеспечение, что проверки подлинности.

const UserAuthenticated = (req, res, next) => { 

     const token = req.cookies.token; //if cookie not exist, user is not authenticated (httpOnly flag)  

     jwt.verify(token_sent_by_used, 'secret', function (err, res) { 
       if (!err) { 
        req.token = res.validToken; 
        next(); 
       } else { 
        res.send('Not authenticated'); 
       } 
     }); 
}; 

//In your endpoint you use like:<br/> 
router.get('/someEndPoint', userAuthenticated, (req, res) => { 
     // use the token here. 
     const token = req.token; 
    ... 
}); 

Затем, когда сделать запрос на клиенте не забудьте добавить withCredentials, что позволит браузеру отправить печенье.

superagent.post(url) 
    .withCredentials()    
    .send(_msg); 

Это все, что вам нужно.