Несколько распространенных методов аутентификации на переднем и заднем концах

внешний интерфейс HTTP

Недавно, при рефакторинге внешнего кода предыдущих продуктов компании, от прежнего метода аутентификации session-cookie отказались, и была принята аутентификация по токену, я счел необходимым разобраться с несколькими распространенными методами аутентификации.

В настоящее время мы обычно используем четыре типа аутентификации:

  1. HTTP Basic Authentication
  2. session-cookie
  3. Проверка токена
  4. OAuth (открытая авторизация)

1. Базовая HTTP-аутентификация

Этот метод авторизации является основным методом авторизации, реализуемым браузером в соответствии с протоколом http.Во время процесса связи по протоколу HTTP протокол HTTP определяет основной метод аутентификации, позволяющий HTTP-серверу выполнять идентификационную карту пользователя на клиенте. .

Процесс сертификации:

1. Клиент запрашивает данные с сервера. Запрашиваемый контент может быть веб-страницей или асинхронным запросом ajax. В это время, предполагая, что клиент не прошел аутентификацию, клиент отправляет на сервер следующий запрос:

  Get /index.html HTTP/1.0   Host:www.google.com

2 Сервер отправляет код запроса на аутентификацию на клиенту, (Word www-atugetical: basic realm = "google.com" является ключом, если нет клиента, имя пользователя и пароль ввода пароля не появится вверх) Данные, возвращенные сервером, примерно такетеруются следующим образом:

  HTTP/1.0 401 Unauthorised
  Server: SokEvo/1.0
WWW-аутентификация: Basic realm=”google.com”
  Content-Type: text/html
  Content-Length: xxx

3. Когда клиент (например, IE, FIREFOX), соответствующий спецификации http1.0 или 1.1, получает возвращаемое значение 401, автоматически открывается окно входа в систему, требующее от пользователя ввода имени пользователя и пароля.

4. После того, как пользователь вводит имя пользователя и пароль, шифрует имя пользователя и пароль с помощью шифрования BASE64 и помещает зашифрованный текст в предыдущее сообщение запроса, первое сообщение запроса, отправленное клиентом, становится следующим:

  Get /index.html HTTP/1.0
  Host:www.google.com
  Authorization: Basic d2FuZzp3YW5n

Примечание: d2FuZzp3YW5n представляет зашифрованные имя пользователя и пароль (имя пользователя: пароль, а затем зашифрованное с помощью base64, процесс шифрования — это поведение браузера по умолчанию, нам не нужно искусственное шифрование, нам нужно только ввести имя пользователя и пароль)

5. После получения вышеуказанной информации запроса сервер извлекает и расшифровывает информацию о пользователе в поле Авторизация и сравнивает расшифрованные имя пользователя и пароль с базой данных пользователей для проверки.Если имя пользователя и пароль верны, сервер отправляет запрошенный ресурс в соответствии с запросом, отправленным клиенту

Эффект: когда клиент не аутентифицирован, появится окно ввода имени пользователя и пароля.В это время запрос находится в состоянии ожидания.В это время, когда пользователь вводит имя пользователя и пароль, клиент отправит запрос с заголовком Authentication еще раз.

这里写图片描述

Аутентификация прошла успешно:

这里写图片描述

server.js

let express = require("express");
let app = express();

    app.use(express.static(__dirname+'/public'));

    app.get("/Authentication_base",function(req,res){
        console.log('req.headers.authorization:',req.headers)
        if(!req.headers.authorization){
            res.set({
               'WWW-Authenticate':'Basic realm="wang"'
            });
            res.status(401).end();
        }else{
            let base64 = req.headers.authorization.split(" ")[1];
            let userPass = new Buffer(base64, 'base64').toString().split(":");
            let user = userPass[0];
            let pass = userPass[1];
            if(user=="wang"&&pass="wang"){
                res.end("OK");
            }else{
                res.status(401).end();
            }

        }

    })

    app.listen(9090)

index.html:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>HTTP Basic Authentication</title>
    </head>
    <body>
        <div></div>
        <script src="js/jquery-3.2.1.js"></script>
        <script>
            $(function(){
              send('./Authentication_base');
            })
            var send = function(url){
                        $.ajax({  
                        url : url,  
                        method : 'GET',  
                    });
           }
        </script>
    </body>
</html>

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

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

Благодаря приведенному выше простому объяснению мы действительно можем вернуть дефекты этого метода проверки.Метод шифрования прост, только шифрование base64, и этот метод шифрования является обратимым. При этом информация об имени пользователя и пароле будет прикреплена к заголовку каждого запроса, чтобы его легко обнаружить сниффером во внешней сети.

Суммировать:

Формально из-за этого этот метод шифрования в основном используется на системах с низкими требованиями к внутренней безопасности, но их относительно много.Вообще говоря, этот вид аутентификации сейчас используется меньше. Если проект нужно развернуть в публичной сети, то этот метод не рекомендуется.Конечно, можно и зашифровать передачу с помощью SSL, что будет лучше.Если у меня будет время изучить это позже.

2.сессионный файл cookie

Второй метод заключается в использовании сеанса (сеанса) на стороне сервера и файла cookie на стороне браузера для обеспечения внешней и внутренней аутентификации.Поскольку HTTP-запрос не имеет состояния, сервер обычно не знает, пришел ли текущий запрос. раньше. В это время, если мы хотим записать статус, нам нужно создать сеанс (сеанс) на стороне сервера и поддерживать запросы одного и того же клиента в соответствующих сеансах. Всякий раз, когда запрос достигает стороны сервера, сначала проверьте есть ли у клиента какие-либо Create seesion на стороне сервера, если есть, то аутентификация прошла успешно, иначе аутентификации нет.
Аутентификация сеансовых файлов cookie в основном делится на четыре этапа:
1. Сервер создает сессию на стороне сервера, когда принимает первый доступ от клиента, а затем сохраняет сессию (мы можем сохранить сессию в памяти или в redis, рекомендуется последнее), а затем генерировать уникальную сессию для этого сеанса. Идентификационная строка, а затем введите эту уникальную идентификационную строку в заголовок ответа.
2. Подпись. Этот шаг предназначен только для шифрования sid, а сервер расшифрует его в соответствии с секретным ключом. (необязательный шаг)
3. Когда браузер получает ответ на запрос, он анализирует заголовок ответа, а затем сохраняет sid в локальном файле cookie.Браузер перенесет информацию о файле cookie под доменным именем в заголовок запроса следующего http-запроса.
4. Когда сервер примет запрос клиента, он проанализирует sid в файле cookie заголовка запроса, а затем найдет сохраненную сервером сессию клиента в соответствии с sid, а затем решит, является ли запрос законным.

这里写图片描述

server.js(nodejs+express+seesion+redis)

var express = require('express');
var RedisStore = require('connect-redis')(express.session);
var app = express();
var secret  = "wang839305939"
// 设置 Cookie
app.use(express.cookieParser(secret));

// 设置 Session
app.use(express.session({
  store: new RedisStore({
    host: "127.0.0.1",
    port: 6379,
    db: "session_db"
  }),
  secret: secret
}))

app.get("/", function(req, res) {
  var session = req.session;
  session.time= session.time|| 0;
  var n = session.time++;
  res.send('hello, session id:' + session.id + ' count:' + n);
});

app.listen(9080);

3. Верификация токена

При использовании метода аутентификации на основе токенов примерный процесс выглядит следующим образом:

1. Клиент использует имя пользователя и пароль для запроса входа
2. Сервер получает запрос на проверку имени пользователя и пароля.
3. После успешной проверки сервер выдаст Токен, а затем отправит Токен клиенту.
4. После того, как клиент получит токен, его можно сохранить, например, в файле cookie или локальном хранилище.
5. Каждый раз, когда клиент запрашивает ресурсы у сервера, ему необходимо приносить с собой сертификат, выданный сервером. Токен
6. Сервер получает запрос, а затем проверяет токен, переданный в клиентском запросе.Если проверка прошла успешно, он возвращает запрошенные данные клиенту.

В общем, после первого входа клиента, когда сервер снова получает http-запрос, он распознает только токен.Запросу нужно только приносить токен каждый раз.Сервер будет перехватывать все запросы, а затем проверять токен , Если это законно, оно будет выпущено, а если незаконно, то будет возвращено 401 (ошибка аутентификации).

На первый взгляд, кажется, немного похоже на предыдущую SeiSion-cookie. Seesion-cookie используется в качестве моста ссылок между браузером и сервером через SeesionID, а метод проверки токена, похоже, является токеном для воспроизведения роли Seesionid. На самом деле, существует большая разница между ними.
1. Идентификатор сеанса — это просто уникально идентифицируемая строка.Сервер использует эту строку для запроса сеанса, поддерживаемого на сервере, в котором хранится статус входа пользователя. Но сам токен является своего рода сертификатом успешного входа в систему, своего рода информационным сертификатом, который генерируется по определенным правилам после успешного входа в систему и сам сохраняет статус входа пользователя. Серверу нужно только проверить, является ли токен законным в соответствии с определенными правилами.
2. Сеанс-куки требует сотрудничества с куки, но куки нужны, тогда только браузер является выбором прокси-клиента http, потому что только браузер будет анализировать куки в заголовке ответа на запрос, а затем по умолчанию для каждого запроса. cookie под этим доменным именем. Но мы то знаем, что http прокси-клиент - это не только браузер, но и родной APP и т.д. В это время куки не работают, либо браузер может запретить куки (хотя это возможно, но это в принципе еда Человек, который это сделал)..., но токен другой. Это информация, возвращаемая в теле ответа после успешного входа в систему. Когда клиент получает ответ, он может сохранить его в локальном файле cookie. и хранилище. , или в памяти, а затем повторно включить этот токен в заголовке запроса следующего запроса. Проще говоря, механизм сеанса cookie ограничивает типы клиентов, а механизм проверки токена обогащает типы клиентов.
3. Своевременность. Идентификатор сеанса cookie сеанса фактически генерируется при входе в систему и остается неизменным при выходе из системы, поэтому безопасность будет в определенной степени низкой, а токен может динамически изменяться в течение определенного периода времени.
4. Масштабируемость. Сама по себе верификация токенов относительно гибка: во-первых, существует множество решений для токенов, широко используется JWT, во-вторых, мы можем сделать сервис аутентификации на основе механизма верификации токенов и использовать его для выполнения унифицированной аутентификации по запросам от нескольких сервисов. .

В качестве примера возьмем наиболее часто используемый JWT (JSON WEB TOKEN):

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

  1. Заголовки: включая категорию (тип), алгоритм шифрования (алг.)
    {
      "alg": "HS256",
      "typ": "JWT"
    }
  1. Утверждения: включая информацию о пользователе, которую необходимо передать
    {
      "sub": "1234567890",
      "name": "John Doe",
      "admin": true
    }
  1. Подпись: строка подписи, зашифрованная алгоритмом alg и закрытым ключом, этот раздел является наиболее важной конфиденциальной информацией и может быть расшифрован только на стороне сервера;
HMACSHA256(  
    base64UrlEncode(Headers) + "." +
    base64UrlEncode(Claims),
    SECREATE_KEY
)

Закодированный JWT выглядит как эта строка символов:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

nodejs+express+jwt-simple
auth.js

let jwt = require('jwt-simple');
let secret = "wangyy";
let time = 10;
 module.exports = { 
 /*
  *检验token合法性
 */ 
 validate:function(req,res,next){ 
      let token = req.body.token||req.headers["xssToken"];
        if(token){ 
          let decodeToken = null;
          try { //防止假冒token解析報錯 
             decodeToken = jwt.decode(token,secret,'HS256'); 
          } catch (err) { 
            res.status(401).send("非法访问"); return; 
          } 
        let exp = decodeToken.exp; if(!exp){
        res.status(401).send("非法访问");
     }
     let now = new Date().getTime();
     if(exp>(now+time*60*1000)){
        res.send({code:'002',"errorMsg":"授权超时"})
      }
      next();
    }else{ 
       res.status(401).send("非法访问");
    }
  },
  /* 生成token*/ 
  makeToken(){ 
      let Token = null; 
      let payload = { 
              time:new Date().getTime(), 
              exp:this.makeExp(time) 
              } 
      Token = jwt.encode(payload,secret,HS256) return Token; 
 }, 
 /*生成token过期时间*/ 
 makeExp:function(time){
      let stam = time601000; 
   } 
 }

server.js

let express = require("express"); 
let app = express(); 
let bodyParser = require('body-parser'); 
let auth = require('./lib/auth.js'); 
let chalk = require('chalk'); app.use(bodyParser.json()); app.post('/login',function(req,res,next){ 
            let Token = auth.makeToken(); 
            res.json({result:"success",token:Token},200)
   });
app.use('*',[auth.validate],function(req,res,next){ 
     res.send('success'); 
  }); 
app.listen('9999')

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

4. OAuth (открытая авторизация)

OAuth (открытая авторизация) — это открытый стандарт, который позволяет пользователям разрешать сторонним веб-сайтам доступ к информации, которую они хранят у другого поставщика услуг, без необходимости предоставлять имена пользователей и пароли сторонним веб-сайтам или делиться всеми своими данными, чтобы защищать безопасность и конфиденциальность пользовательских данных, сторонние веб-сайты должны явно запрашивать у пользователей авторизацию перед доступом к пользовательским данным. Среди наших общих поставщиков, предоставляющих услуги аутентификации OAuth, Alipay, QQ и WeChat.
Протокол OAuth имеет две версии: 1.0 и 2.0. По сравнению с версией 1.0 весь процесс проверки авторизации версии 2.0 проще и безопаснее, а также является наиболее важным методом аутентификации и авторизации пользователей в настоящее время.
Ниже представлена ​​блок-схема auth2.0:
这里写图片描述

Из рисунка видно, что процесс auth2.0 разбит на шесть дистрибутивов (в качестве примера мы берем csdn login):

Первый шаг.Запрос авторизации у пользователя.Сейчас на многих сайтах есть сторонние порталы входа при входе в систему.Когда мы нажимаем и ждем сторонний портал, сторонняя служба авторизации направляет нас к стороннему входу страница авторизации.

这里写图片描述

Видно из адресной строки браузера адрес страницы авторизации стороннего запроса,

https://graph.qq.com/oauth2.0/show?which=Login&display=pc&response_type=code&client_id=100270989&redirect_uri=https%3A%2F%2Fpassport.csdn.net%2Faccount%2Flogin%3Foauth_provider%3DQQProvider&state=test

% в адресе здесь - это отображение после принудительного кодирования браузером. Мы можем использовать decodeURIComponent для его декодирования. После декодирования это выглядит так:

https://graph.qq.com/oauth2.0/show?which=Login&display=pc&response_type=code&client_id=100270989&redirect_uri=https://passport.csdn.net/account/login?oauth_provider=QQProvider&state=test

По этому URL-адресу мы можем увидеть несколько параметров Auth2.0:
response_type, возвращаемый тип
client_id, идентификатор стороннего приложения, выдается стороннему приложению сервером авторизации (qq) при отправке стороннего приложения.
redirect_uri, страница перенаправления успешного входа
oauth_provider, сторонний поставщик авторизации
состояние, случайный код, заданный сторонним приложением
Шаг 2. Верните учетные данные пользователя (код) и верните учетные данные (код). Когда пользователь нажмет кнопку авторизации и войдет в систему, сервер авторизации сгенерирует учетные данные пользователя (код). Учетные данные пользователя будут добавлены к перенаправленному адресу redirect_uri.

https://passport.csdn.net/account/login?code=9e3efa6cea739f9aaab2&state=XXX

Шаг 3. Запрос авторизации сервера авторизации:

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

  • client_id определяет идентификатор стороннего приложения, который выдается сервером авторизации (Github) стороннему приложению при отправке стороннего приложения.
  • client_secret Учетные данные безопасности между сторонним приложением и сервером авторизации, выданные сервером авторизации (Github) стороннему приложению, когда стороннее приложение отправляет его
  • code Учетные данные пользователя, возвращенные на первом этапе. redirect_uri Адрес для перехода ко второму этапу после создания учетных данных пользователя на первом этапе.
  • состояние — это случайный код, заданный сторонним приложением

Шаг 4. После того, как сервер авторизации соглашается на авторизацию, он возвращает учетные данные доступа к ресурсу (Access Token).

Шаг 5. Стороннее приложение запрашивает соответствующие ресурсы с сервера ресурсов с помощью учетных данных (токен доступа) на шаге 4.

Шаг 6. После того, как сервер ресурсов аутентифицирует учетные данные (токен доступа), он возвращает ресурсы, запрошенные сторонним приложением.

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

Суммировать:

Существуют различные способы авторизации, которые в основном зависят от нашего позиционирования продукта. Если наш продукт используется только внутри предприятия, токен и сеанс могут удовлетворить наши потребности.Если это массовый пользователь, ориентированный на Интернет, то сторонняя авторизация значительно улучшит взаимодействие с пользователем.

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