jwt — это аббревиатура веб-токена json. В этой статье рассказывается о его принципе. Наконец, серверная часть использует nodejs, чтобы понять, как сгенерировать токен токена и проверить токен для клиента.
1. Зачем нужно управление сессиями
Когда мы используем nodejs для предоставления интерфейса с разрешением для внешнего интерфейса или других служб, протокол http является протоколом без сохранения состояния.Иногда нам нужно получить, имеет ли конкретный пользователь разрешение в соответствии с контекстом запроса, и действовать в соответствии с контекстом. пользователя. Таким образом, существует несколько технологий, таких как сеанс cookie и jwt, которые являются дополнением к протоколу HTTP. Это позволяет нам создавать ориентированное на пользователя веб-приложение с протоколом HTTP + управлением состоянием.
2. Сеанс и файлы cookie
Сеанс и файлы cookie связаны между собой. Сеанс — это идентификатор сеанса сервера в файлах cookie на стороне клиента, и сервер сохраняет всю информацию о состоянии текущего пользователя, соответствующую идентификатору сеанса. Каждый раз, когда клиент запрашивает сервер, в куки заносится session_id, и сервер определяет, есть ли конкретная информация о пользователе, и если нет, корректирует логин.
- Безопасность файлов cookie не является хорошей, и злоумышленники могут обмануть, получив локальные файлы cookie или используя файлы cookie для проведения атак CSRF.
- Файлы cookie под несколькими доменными именами будут иметь междоменные проблемы.
- Информация о сеансе хранится на сервере.Когда мы развертываем несколько машин в stke, нам нужно решить общий сеанс, поэтому возникает проблема сохранения сеанса.Поэтому сеанс не поддерживает распределенную архитектуру и не может поддерживать горизонтальное расширение., может только быть разделены через базу данных, чтобы сохранить данные сеанса. Сбой аутентификации происходит, если происходит сбой уровня сохраняемости.
3. Определение jwt
jwt — это полное имя веб-токена json.Решает проблемы над сессией.Преимущество в том, что сервер не сохраняет никаких данных сессии, то есть сервер становится апатридом, что упрощает его расширение.При каких обстоятельствах это более уместно использовать jwt, я думаю, что это авторизация. В этом сценарии jwt широко используется, потому что он прост в использовании, имеет низкие накладные расходы, а серверная часть не имеет состояния.
4. Принцип jwt
Принцип JWT заключается в том, что после аутентификации сервера объект JSON генерируется и отправляется обратно пользователю, как показано ниже.
{
"姓名": "张三",
"角色": "管理员",
"到期时间": "2018年7月1日0点0分"
}
В дальнейшем, когда пользователь будет общаться с сервером, этот объект JSON должен быть отправлен обратно. Сервер полагается исключительно на этот объект для идентификации пользователя. Чтобы пользователи не могли подделывать данные, сервер добавит подпись при создании этого объекта.
5. процесс сертификации jwt
Описание потока:
- Браузер инициирует запрос на вход в систему, содержащий имя пользователя и пароль;
- Сервер аутентифицирует личность в базе данных в соответствии с именем пользователя и прозрачным кодом и упаковывает идентификатор пользователя для создания токена в соответствии с алгоритмом.
- Сервер возвращает информацию JWT в браузер, JWT не должен содержать конфиденциальной информации, это очень важный момент
- Браузер инициирует запрос на получение информации о пользователе, и отправляет только что полученный токен на сервер, обычно в заголовке, а поле авторизация
- Сервер обнаруживает, что в данных есть токен, и расшифровывает информацию о токене, а затем снова подписывает его, чтобы проверить его подлинность;
- Сервер возвращает профиль пользователя;
- Сервер может установить время истечения в полезной нагрузке. Если оно истечет, клиент может повторно инициировать проверку.
6. Структура данных jwt
jwt содержит использование.
три части стиля
Заголовок
{ "alg": "HS256", "typ": "JWT"}
// algorithm => HMAC SHA256
// type => JWT
Это фиксированный способ записи, поверхность alg использует алгоритм HS256.
Полезная нагрузка, полезная нагрузка, JWT указывает 7 официальных полей
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号
В дополнение к этим семи вы можете настроить, например, время истечения срока действия
Подпись
Подпишите первые две части заголовка и полезной нагрузки, чтобы предотвратить подделку данных.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
Секрет представляет собой строку, которая хранится в бэкенде.Следует отметить, что JWT используется как токен (токен), который может быть размещен в URL (например, api.example.com/?token=xxx) в некоторые случаи. В Base64 есть три символа +, / и =, которые имеют особое значение в URL-адресах, поэтому их следует заменить: = опускается, + заменяется на -, а / заменяется на _. Это алгоритм Base64URL.
7. Как использовать jwt
Заголовки HTTP-запросаAuthorization
В поле Bearer также указывается
Authorization: Bearer <token>
передача через URL (не рекомендуется)
http://www.xxx.com/pwa?token=xxxxx
Если это почтовый запрос, его также можно разместить в теле запроса.
8. Использование в коа-проекте
Можно использовать готовые библиотеки,jwt-simple
илиjsonwebtoken
let Koa = require('koa');
let Router = require('koa-router');
let bodyparser = require('koa-bodyparser');
let jwt = require('jwt-simple');
let router = new Router()
let app = new Koa();
app.use(bodyparser());
// 可以自己自定义
let secret = 'zhenglei';
// 验证是否登陆
router.post('/login',async(ctx)=>{
let {username,password} = ctx.request.body;
if(username === 'admin' && password === 'admin'){
// 通常会查数据库,这里简单的演示
let token = jwt.encode(username, secret);
ctx.body = {
code:200,
username,
token,
}
}
});
// 验证是否有权限
router.get('/validate',async(ctx)=>{
let Authorization = ctx.get('authorization')
let [,token] = Authorization.split(' ');
if(token){
try{
let r = jwt.decode(token,secret);
ctx.body = {
code:200,
username:r,
token
}
}catch(e){
ctx.body = {
code:401,
data:'没有登陆'
}
}
}else{
ctx.body = {
code:401,
data:'没有登陆'
}
}
});
app.use(router.routes());
app.listen(4000);
- Реализовать два интерфейса
/login
Проверьте, нужно ли войти в систему.validate
, убедитесь, что у вас есть разрешение - При запросе интерфейса входа клиент вводит имя пользователя и пароль, а серверная часть обычно проверяет базу данных, чтобы проверить, существует ли текущий пользователь.
- Клиент получает маркер токена, предоставленный серверной частью, а затем запрашивает другие интерфейсы, например, в этом примере.
/validate
Когда делается ajax-запрос, его можно указать в заголовкеauthorization
поле, бэкенд получает токен для декодирования, а затем снова подписывает заголовок и полезную нагрузку.Если предыдущая и предыдущая подписи совпадают, это означает, что он не был подделан, и проверка разрешения пройдена. Поскольку это синхронный процесс, вы можете использовать try catch для отлова ошибок.
9. Реализация принципа
-
Для хеш-алгоритма sha256 можно использовать встроенный модуль шифрования crypto of nodejs для генерации строк base64.Следует отметить, что для генерации base64 нужно заменить + - =, = опущено, + заменено на -, / заменяется на _ . Это алгоритм Base64URL.
-
В состав токена токена входит прохождение заголовка, полезной нагрузки и подписи.
.
сочинять -
Декодирование base64urlUnescape является фиксированным способом записи, а содержимое base64 декодируется
let myJwt = {
sign(content,secret){
let r = crypto.createHmac('sha256',secret).update(content).digest('base64');
return this.base64urlEscape(r)
},
base64urlEscape(str){
return str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
},
toBase64(content){
return this.base64urlEscape(Buffer.from(JSON.stringify(content)).toString('base64'))
},
encode(username,secret){
let header = this.toBase64({ typ: 'JWT', alg: 'HS256' });
let content = this.toBase64(username);
let sign = this.sign([header,content].join('.'),secret);
return [header,content,sign].join('.')
},
base64urlUnescape(str) {
str += new Array(5 - str.length % 4).join('=');
return str.replace(/\-/g, '+').replace(/_/g, '/');
},
decode(token,secret){
let [header,content,sign] = token.split('.');
let newSign = this.sign([header,content].join('.'),secret);
if(sign === newSign){
return Buffer.from(this.base64urlUnescape(content),'base64').toString();
}else{
throw new Error('被篡改')
}
}
}
10. Преимущества и недостатки jwt
- JWT по умолчанию не зашифрован, но может быть зашифрован. После создания исходного токена его можно снова зашифровать с помощью модифицированного токена.
- Когда JWT не зашифрован, некоторые частные данные не могут быть переданы через JWT.
- JWT можно использовать не только для аутентификации, но и для обмена информацией. Правильное использование JWT может помочь уменьшить количество запросов сервера к базе данных.
- Самый большой недостаток JWT заключается в том, что сервер не сохраняет состояние сеанса, поэтому невозможно отозвать токен или изменить разрешения токена во время использования. То есть после выдачи JWT он остается действительным в течение всего срока действия.
- Сам JWT содержит информацию об аутентификации, поэтому после утечки информации любой может получить все разрешения токена. Чтобы уменьшить незаконное присвоение, срок действия JWT не должен быть слишком длинным. Для некоторых важных операций пользователь должен проходить аутентификацию каждый раз, когда он его использует.
- Чтобы уменьшить кражу и кражу, JWT не рекомендует использовать протокол HTTP для передачи кода, а зашифрованный протокол HTTPS для передачи.