Статьи

Аутентификация на основе токенов с AngularJS & NodeJS

Конечный продукт
Что вы будете создавать

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

Вы также можете найти широкий выбор готовых скриптов аутентификации и приложений на Envato Market, таких как:

Или, если вы боретесь с ошибкой в ​​коде AngularJS, вы можете отправить ее в araneux на Envato Studio, чтобы исправить ее.

Прежде чем перейти к системе аутентификации на основе токенов, давайте сначала посмотрим на традиционную систему аутентификации.

  1. Пользователь вводит имя пользователя и пароль в форме входа и нажимает кнопку « Вход» .
  2. После того, как запрос сделан, проверьте пользователя в бэкэнде, сделав запрос в базе данных. Если запрос действителен, создайте сеанс с использованием информации о пользователе, выбранной из базы данных, а затем верните информацию о сеансе в заголовок ответа, чтобы сохранить идентификатор сеанса в браузере.
  3. Предоставьте информацию о сеансе для доступа к ограниченным конечным точкам в приложении.
  4. Если информация о сеансе действительна, предоставьте пользователю доступ к указанным конечным точкам и ответьте отображаемым содержимым HTML.

Все хорошо до этого момента. Веб-приложение работает хорошо, и оно может аутентифицировать пользователей, чтобы они могли иметь доступ к ограниченным конечным точкам; однако что произойдет, если вы захотите разработать другой клиент, например для Android, для своего приложения? Сможете ли вы использовать текущее приложение для аутентификации мобильных клиентов и для обслуживания контента с ограниченным доступом? В настоящее время нет. Для этого есть две основные причины:

  1. Сессии и куки не имеют смысла для мобильных приложений. Вы не можете делиться сессиями или файлами cookie, созданными на стороне сервера, с мобильными клиентами.
  2. В текущем приложении возвращается HTML-код. В мобильном клиенте в ответ необходимо включить что-то вроде JSON или XML.

В этом случае вам необходимо независимое от клиента приложение.

При аутентификации на основе токенов файлы cookie и сеансы не будут использоваться. Токен будет использоваться для аутентификации пользователя при каждом запросе к серверу. Давайте перепроектируем первый сценарий с аутентификацией на основе токенов.

Он будет использовать следующий поток управления:

  1. Пользователь вводит имя пользователя и пароль в форме входа и нажимает кнопку « Вход» .
  2. После того, как запрос сделан, проверьте пользователя в бэкэнде, сделав запрос в базе данных. Если запрос действителен, создайте токен, используя информацию о пользователе, извлеченную из базы данных, а затем верните эту информацию в заголовок ответа, чтобы мы могли сохранить браузер токенов в локальном хранилище.
  3. Предоставьте информацию о токене в каждом заголовке запроса для доступа к ограниченным конечным точкам в приложении.
  4. Если токен, полученный из информации заголовка запроса, действителен, предоставьте пользователю доступ к указанной конечной точке и ответьте JSON или XML.

В этом случае у нас нет возвращенного сеанса или файла cookie, и мы не вернули никакого HTML-контента. Это означает, что мы можем использовать эту архитектуру для любого клиента для конкретного приложения. Вы можете увидеть схему архитектуры ниже:

Итак, что это за JWT?

JWT расшифровывается как JSON Web Token и является форматом токена, который используется в заголовках авторизации. Этот токен помогает вам спроектировать связь между двумя системами безопасным способом. Давайте перефразируем JWT как «токен на предъявителя» для целей этого урока. Маркер-носитель состоит из трех частей: заголовок, полезная нагрузка и подпись.

  • Заголовок является частью токена, который содержит тип токена и метод шифрования, который также зашифрован с помощью base-64.
  • Полезная нагрузка включает в себя информацию. Вы можете поместить любые данные, такие как информация о пользователе, информация о продукте и т. Д., Все они хранятся с шифрованием base-64.
  • Подпись состоит из комбинаций заголовка, полезной нагрузки и секретного ключа. Секретный ключ должен надежно храниться на стороне сервера.

Вы можете увидеть схему JWT и пример токена ниже;

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

язык URL библиотеки
NodeJS http://github.com/auth0/node-jsonwebtoken
PHP http://github.com/firebase/php-jwt
Джава http://github.com/auth0/java-jwt
Рубин http://github.com/progrium/ruby-jwt
.СЕТЬ http://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet
питон http://github.com/progrium/pyjwt/

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

  1. Запросы от нескольких клиентов, таких как веб-приложение, мобильный клиент и т. Д., Направляются в API для конкретной цели.
  2. Запросы направляются в службу, такую ​​как https://api.yourexampleapp.com . Если приложением пользуется множество людей, для выполнения запрошенной операции может потребоваться несколько серверов.
  3. Здесь балансировщик нагрузки используется для балансировки запросов, чтобы наилучшим образом удовлетворить серверы приложений на бэкэнде. Когда вы отправляете запрос на https://api.yourexampleapp.com , сначала балансировщик нагрузки обработает запрос, а затем перенаправит клиента на определенный сервер.
  4. Существует одно приложение, и это приложение развернуто на нескольких серверах (сервер-1, сервер-2, …, сервер-n). Всякий раз, когда делается запрос на https://api.yourexampleapp.com , фоновое приложение перехватывает заголовок запроса и извлекает информацию о токене из заголовка авторизации. Запрос к базе данных будет сделан с использованием этого токена. Если этот токен действителен и имеет необходимые разрешения для доступа к запрошенной конечной точке, он будет продолжен. Если нет, он вернет код ответа 403 (который указывает на запрещенный статус).

Аутентификация на основе токенов имеет ряд преимуществ, которые решают серьезные проблемы. Вот некоторые из них:

  • Клиент независимые услуги. При аутентификации на основе токенов токен передается через заголовки запросов вместо хранения информации аутентификации в сеансах или файлах cookie. Это означает, что нет государства. Вы можете отправить запрос на сервер от любого типа клиента, который может делать HTTP-запросы.
  • CDN. В большинстве современных веб-приложений представления отображаются на серверной части, а HTML-содержимое возвращается в браузер. Логика внешнего интерфейса зависит от внутреннего кода. Нет необходимости делать такую ​​зависимость. Это связано с несколькими проблемами. Например, если вы работаете с дизайнерским агентством, которое реализует ваш внешний интерфейс HTML, CSS и JavaScript, вам нужно взять этот внешний код и перенести его в свой внутренний код, чтобы выполнить рендеринг или заполнение операции. Через некоторое время ваш визуализированный HTML-контент будет сильно отличаться от того, что реализовало агентство кода. В аутентификации на основе токенов вы можете разработать внешний проект отдельно от внутреннего кода. Ваш внутренний код возвратит ответ JSON вместо отрисованного HTML, и вы можете поместить сжатую версию внешнего кода в CDN. Когда вы переходите на свою веб-страницу, контент HTML будет обслуживаться из CDN, а контент страницы будет заполняться службами API с использованием токена в заголовках авторизации.
  • Нет Cookie-сессии (или нет CSRF). CSRF является серьезной проблемой в современной веб-безопасности, потому что он не проверяет, является ли источник запроса доверенным или нет. Чтобы решить эту проблему, пул токенов используется для отправки этого токена на каждое сообщение формы. При аутентификации на основе токенов токен используется в заголовках авторизации, и CSRF не включает эту информацию.
  • Магазин постоянных токенов. Когда в приложении выполняется операция чтения, записи или удаления сеанса, она выполняет файловую операцию во temp папке операционной системы, по крайней мере, в первый раз. Допустим, у вас есть несколько серверов, и на первом сервере создается сеанс. Когда вы делаете другой запрос и ваш запрос сбрасывается на другом сервере, информация о сеансе не будет существовать и получит «неавторизованный» ответ. Я знаю, вы можете решить это с помощью липкой сессии. Однако в аутентификации на основе токенов этот случай решается естественным путем. Отсутствует проблема слипания сеанса, поскольку маркер запроса перехватывается при каждом запросе на любом сервере.

Это наиболее распространенные преимущества аутентификации и связи на основе токенов. Это конец теоретического и архитектурного разговора об аутентификации на основе токенов. Время для практического примера.

Вы увидите два приложения для демонстрации аутентификации на основе токенов:

  1. на основе маркеров-аутентификации-бэкенд
  2. на основе маркеров-аутентификации-интерфейс

В серверном проекте будут реализованы службы, а результаты службы будут представлены в формате JSON. В сервисах нет просмотра. В проекте переднего плана будет проект AngularJS для внешнего HTML, а затем приложение AngularJS будет заполняться внешним приложением для выполнения запросов к внутренним службам.

В фоновом проекте есть три основных файла:

  • package.json для управления зависимостями.
  • models\User.js содержит модель User, которая будет использоваться для выполнения операций базы данных с пользователями.
  • server.js предназначен для начальной загрузки проекта и обработки запросов.

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
{
    «name»: «angular-restful-auth»,
    «version»: «0.0.1»,
    «dependencies»: {
        «express»: «4.x»,
        «body-parser»: «~1.0.0»,
        «morgan»: «latest»,
        «mongoose»: «3.8.8»,
        «jsonwebtoken»: «0.4.0»
    },
    «engines»: {
        «node»: «>=0.10.0»
    }
}

package.json содержит зависимости для проекта: express для MVC, body-parser   для имитации обработки почтовых запросов в NodeJS, morgan   для регистрации запросов, mongoose для нашей среды ORM для подключения к MongoDB и jsonwebtoken для создания токенов JWT с использованием нашей модели User. Существует также атрибут, называемый engine, который говорит, что этот проект сделан с использованием версии NodeJS> = 0.10.0. Это полезно для PaaS-сервисов, таких как Heroku. Мы также рассмотрим эту тему в другом разделе.

01
02
03
04
05
06
07
08
09
10
var mongoose = require(‘mongoose’);
var Schema = mongoose.Scema;
 
var UserSchema = new Schema({
    email: String,
    password: String,
    token: String
});
 
module.exports = mongoose.model(‘User’, UserSchema);

Мы сказали, что сгенерируем токен, используя полезную нагрузку пользовательской модели. Эта модель помогает нам выполнять пользовательские операции на MongoDB. В User.js определяется пользовательская схема, а модель User создается с использованием модели mongoose. Эта модель готова к работе с базой данных.

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

1
2
3
4
5
6
7
// Required Modules
var express = require(«express»);
var morgan = require(«morgan»);
var bodyParser = require(«body-parser»);
var jwt = require(«jsonwebtoken»);
var mongoose = require(«mongoose»);
var app = express();

В NodeJS вы можете включить модуль в свой проект, используя require . Для начала нам нужно импортировать необходимые модули в проект:

1
2
3
4
5
var port = process.env.PORT ||
var User = require(‘./models/User’);
 
// Connect to DB
mongoose.connect(process.env.MONGO_URL);

Наш сервис будет обслуживаться через определенный порт. Если какая-либо переменная порта определена в системных переменных среды, вы можете использовать это, или мы определили порт 3001 . После этого включается модель User и устанавливается соединение с базой данных для выполнения некоторых пользовательских операций. Не забудьте определить переменную MONGO_URLMONGO_URL — для URL соединения с базой данных.

1
2
3
4
5
6
7
8
9
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(morgan(«dev»));
app.use(function(req, res, next) {
    res.setHeader(‘Access-Control-Allow-Origin’, ‘*’);
    res.setHeader(‘Access-Control-Allow-Methods’, ‘GET, POST’);
    res.setHeader(‘Access-Control-Allow-Headers’, ‘X-Requested-With,content-type, Authorization’);
    next();
});

В приведенном выше разделе мы сделали несколько конфигураций для имитации обработки HTTP-запросов в NodeJS с помощью Express. Мы разрешаем поступать запросы из разных доменов для разработки независимой от клиента системы. Если вы не разрешите это, вы вызовете в браузере ошибку CORS (Cross Origin Request Sharing).

  • Access-Control-Allow-Origin разрешен для всех доменов.
  • Вы можете отправлять POST и GET запросы на эту услугу.
  • Разрешены X-Requested-With и заголовки content-type .
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
app.post(‘/authenticate’, function(req, res) {
    User.findOne({email: req.body.email, password: req.body.password}, function(err, user) {
        if (err) {
            res.json({
                type: false,
                data: «Error occured: » + err
            });
        } else {
            if (user) {
               res.json({
                    type: true,
                    data: user,
                    token: user.token
                });
            } else {
                res.json({
                    type: false,
                    data: «Incorrect email/password»
                });
            }
        }
    });
});

Мы импортировали все необходимые модули и определили нашу конфигурацию, так что теперь пришло время определить обработчики запросов. В приведенном выше коде, когда вы делаете POST   запрос /authenticate с именем пользователя и паролем, вы получите токен JWT . Сначала запрос к базе данных обрабатывается с использованием имени пользователя и пароля. Если пользователь существует, данные пользователя будут возвращены с его токеном. Но что, если нет такого пользователя, соответствующего имени пользователя и / или паролю?

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
app.post(‘/signin’, function(req, res) {
    User.findOne({email: req.body.email, password: req.body.password}, function(err, user) {
        if (err) {
            res.json({
                type: false,
                data: «Error occured: » + err
            });
        } else {
            if (user) {
                res.json({
                    type: false,
                    data: «User already exists!»
                });
            } else {
                var userModel = new User();
                userModel.email = req.body.email;
                userModel.password = req.body.password;
                userModel.save(function(err, user) {
                    user.token = jwt.sign(user, process.env.JWT_SECRET);
                    user.save(function(err, user1) {
                        res.json({
                            type: true,
                            data: user1,
                            token: user1.token
                        });
                    });
                })
            }
        }
    });
});

Когда вы делаете запрос POST для /signin с именем пользователя и паролем, новый пользователь будет создан с использованием опубликованной информации о пользователе. В 19th строке вы видите, что новый токен JSON генерируется с помощью модуля jsonwebtoken , который был назначен переменной jwt . Часть аутентификации в порядке. Что если мы попытаемся получить доступ к ограниченной конечной точке? Как мы можем получить доступ к этой конечной точке?

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
app.get(‘/me’, ensureAuthorized, function(req, res) {
    User.findOne({token: req.token}, function(err, user) {
        if (err) {
            res.json({
                type: false,
                data: «Error occured: » + err
            });
        } else {
            res.json({
                type: true,
                data: user
            });
        }
    });
});

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

01
02
03
04
05
06
07
08
09
10
11
12
function ensureAuthorized(req, res, next) {
    var bearerToken;
    var bearerHeader = req.headers[«authorization»];
    if (typeof bearerHeader !== ‘undefined’) {
        var bearer = bearerHeader.split(» «);
        bearerToken = bearer[1];
        req.token = bearerToken;
        next();
    } else {
        res.send(403);
    }
}

В этой функции заголовки запроса перехватываются, а заголовок authorization извлекается. Если токен-носитель существует в этом заголовке, этот токен присваивается req.token для использования в запросе, и запрос может быть продолжен с помощью next() . Если токен не существует, вы получите ответ 403 (Запрещено). Давайте вернемся к handler /me и используем req.token для получения пользовательских данных с этим токеном. Каждый раз, когда вы создаете нового пользователя, токен генерируется и сохраняется в пользовательской модели в БД. Эти токены уникальны.

У нас есть только три обработчика для этого простого проекта. После этого вы увидите;

1
2
3
process.on(‘uncaughtException’, function(err) {
    console.log(err);
});

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

1
2
3
4
// Start Server
app.listen(port, function () {
    console.log( «Express server listening on port » + port);
});

Подводить итоги:

  • Модули импортированы.
  • Конфигурации сделаны.
  • Обработчики запросов определены.
  • Промежуточное программное обеспечение определено для перехвата ограниченных конечных точек.
  • Сервер запущен.

Мы сделали с серверной службой. Чтобы его могли использовать несколько клиентов, вы можете развернуть это простое серверное приложение на своих серверах или, возможно, вы можете развернуть его в Heroku. В корневой папке проекта есть файл с именем Procfile . Давайте развернем наш сервис в Heroku.

Вы можете клонировать внутренний проект из этого репозитория GitHub .

Я не буду обсуждать, как создать приложение в Heroku; Вы можете обратиться к этой статье для создания приложения Heroku, если вы не сделали этого раньше. После создания приложения Heroku вы можете добавить пункт назначения в текущий проект, используя следующую команду:

1
git remote add heroku <your_heroku_git_url>

Теперь вы клонировали проект и добавили пункт назначения. После git add и git commit вы можете git push heroku master свой код в Heroku, выполнив git push heroku master . Когда вы успешно отправите проект, Heroku выполнит команду npm install чтобы загрузить зависимости во temp папку Heroku. После этого приложение запустится, и вы сможете получить доступ к своему сервису по протоколу HTTP.

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

Вы можете клонировать проект из этого репозитория GitHub . В этом проекте вы увидите следующую структуру папок:

Структура папок

ngStorage.js — это библиотека для AngularJS для управления локальными операциями хранения. Кроме того, есть основной макет index.html и partials, которые расширяют основной макет в папке partials . controllers.js предназначен для определения действий нашего контроллера во внешнем интерфейсе. services.js предназначен для отправки запросов на обслуживание к нашему сервису, о котором я упоминал в предыдущем проекте. У нас есть загрузочный файл, который называется app.js и в этом файле применяются конфигурации и импорт модулей. Наконец, client.js предназначен для обслуживания статических файлов HTML (или просто index.html , в данном случае); это помогает нам обслуживать статические HTML-файлы при развертывании на сервере без использования Apache или любых других веб-серверов.

01
02
03
04
05
06
07
08
09
10
11
<script src=»//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js»></script>
<script src=»//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js»></script>
<script src=»//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.min.js»></script>
<script src=»//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular-route.min.js»></script>
<script src=»/lib/ngStorage.js»></script>
<script src=»/lib/loading-bar.js»></script>
<script src=»/scripts/app.js»></script>
<script src=»/scripts/controllers.js»></script>
<script src=»/scripts/services.js»></script>
</body>

В основной HTML-файл макета все необходимые файлы JavaScript включены для библиотек, связанных с AngularJS, а также для нашего пользовательского контроллера, службы и файла приложения.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
‘use strict’;
 
/* Controllers */
 
angular.module(‘angularRestfulAuth’)
    .controller(‘HomeCtrl’, [‘$rootScope’, ‘$scope’, ‘$location’, ‘$localStorage’, ‘Main’, function($rootScope, $scope, $location, $localStorage, Main) {
 
        $scope.signin = function() {
            var formData = {
                email: $scope.email,
                password: $scope.password
            }
 
            Main.signin(formData, function(res) {
                if (res.type == false) {
                    alert(res.data)
                } else {
                    $localStorage.token = res.data.token;
                    window.location = «/»;
                }
            }, function() {
                $rootScope.error = ‘Failed to signin’;
            })
        };
 
        $scope.signup = function() {
            var formData = {
                email: $scope.email,
                password: $scope.password
            }
 
            Main.save(formData, function(res) {
                if (res.type == false) {
                    alert(res.data)
                } else {
                    $localStorage.token = res.data.token;
                    window.location = «/»
                }
            }, function() {
                $rootScope.error = ‘Failed to signup’;
            })
        };
 
        $scope.me = function() {
            Main.me(function(res) {
                $scope.myDetails = res;
            }, function() {
                $rootScope.error = ‘Failed to fetch details’;
            })
        };
 
        $scope.logout = function() {
            Main.logout(function() {
                window.location = «/»
            }, function() {
                alert(«Failed to logout!»);
            });
        };
        $scope.token = $localStorage.token;
    }])

В приведенном выше коде HomeCtrl контроллер HomeCtrl , и HomeCtrl некоторые необходимые модули, такие как $rootScope и $scope . Внедрение зависимостей — одно из самых сильных свойств AngularJS. $scope — это переменная моста между контроллерами и представлениями в AngularJS, что означает, что вы можете использовать test in view, если вы определили его в указанном контроллере, таком как $scope.test=....

В этом контроллере определены некоторые служебные функции, такие как:

  • signin чтобы настроить кнопку входа в форму входа
  • signup для обработки формы регистрации
  • me за назначение кнопки «Я» в макете

В основном макете в списке главного меню вы можете увидеть атрибут data-ng-controller со значением HomeCtrl . Это означает, что этот элемент меню dom может иметь общий вид с HomeCtrl . Когда вы нажимаете кнопку регистрации в форме, будет выполняться функция регистрации в файле контроллера, и в этой функции служба регистрации используется из Main службы, которая уже внедрена в этот контроллер.

Основная структура — это view -> controller -> service . Этот сервис делает простые запросы Ajax к бэкэнду, чтобы получить конкретные данные.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
‘use strict’;
 
angular.module(‘angularRestfulAuth’)
    .factory(‘Main’, [‘$http’, ‘$localStorage’, function($http, $localStorage){
        var baseUrl = «your_service_url»;
        function changeUser(user) {
            angular.extend(currentUser, user);
        }
 
        function urlBase64Decode(str) {
            var output = str.replace(‘-‘, ‘+’).replace(‘_’, ‘/’);
            switch (output.length % 4) {
                case 0:
                    break;
                case 2:
                    output += ‘==’;
                    break;
                case 3:
                    output += ‘=’;
                    break;
                default:
                    throw ‘Illegal base64url string!’;
            }
            return window.atob(output);
        }
 
        function getUserFromToken() {
            var token = $localStorage.token;
            var user = {};
            if (typeof token !== ‘undefined’) {
                var encoded = token.split(‘.’)[1];
                user = JSON.parse(urlBase64Decode(encoded));
            }
            return user;
        }
 
        var currentUser = getUserFromToken();
 
        return {
            save: function(data, success, error) {
                $http.post(baseUrl + ‘/signin’, data).success(success).error(error)
            },
            signin: function(data, success, error) {
                $http.post(baseUrl + ‘/authenticate’, data).success(success).error(error)
            },
            me: function(success, error) {
                $http.get(baseUrl + ‘/me’).success(success).error(error)
            },
            logout: function(success) {
                changeUser({});
                delete $localStorage.token;
                success();
            }
        };
    }
]);

В приведенном выше коде вы можете увидеть сервисные функции, такие как отправка запросов на аутентификацию. В controller.js вы, возможно, уже поняли, что есть такие функции, как Main.me Эта Main служба была введена в контроллер, а в контроллере службы, принадлежащие этой службе, вызываются напрямую.

Эти функции — просто запросы Ajax к нашему сервису, которые мы развернули вместе. Не забудьте baseUrl URL службы в baseUrl в приведенном выше коде. При развертывании службы в Heroku вы получите URL службы, например appname.herokuapp.com . В приведенном выше коде вы установите var baseUrl = "appname.herokuapp.com" .

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
$httpProvider.interceptors.push([‘$q’, ‘$location’, ‘$localStorage’, function($q, $location, $localStorage) {
           return {
               ‘request’: function (config) {
                   config.headers = config.headers ||
                   if ($localStorage.token) {
                       config.headers.Authorization = ‘Bearer ‘ + $localStorage.token;
                   }
                   return config;
               },
               ‘responseError’: function(response) {
                   if(response.status === 401 || response.status === 403) {
                       $location.path(‘/signin’);
                   }
                   return $q.reject(response);
               }
           };
       }]);

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

В проекте переднего signin у нас есть несколько частичных страниц, таких как signin , signup , profile details и vb . Эти частичные страницы связаны с конкретными контроллерами. Вы можете увидеть это отношение в app.js :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
angular.module(‘angularRestfulAuth’, [
    ‘ngStorage’,
    ‘ngRoute’
])
.config([‘$routeProvider’, ‘$httpProvider’, function ($routeProvider, $httpProvider) {
 
    $routeProvider.
        when(‘/’, {
            templateUrl: ‘partials/home.html’,
            controller: ‘HomeCtrl’
        }).
        when(‘/signin’, {
            templateUrl: ‘partials/signin.html’,
            controller: ‘HomeCtrl’
        }).
        when(‘/signup’, {
            templateUrl: ‘partials/signup.html’,
            controller: ‘HomeCtrl’
        }).
        when(‘/me’, {
            templateUrl: ‘partials/me.html’,
            controller: ‘HomeCtrl’
        }).
        otherwise({
            redirectTo: ‘/’
        });

Как вы можете легко понять из приведенного выше кода, при home.html к / будет отображаться страница home.html . Другой пример: если вы перейдете в /signup , будет отображен signup.html . Эта операция рендеринга будет выполняться в браузере, а не на стороне сервера.

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

Системы аутентификации на основе токенов помогают вам создать систему аутентификации / авторизации при разработке независимых от клиента сервисов. Используя эту технологию, вы просто сосредоточитесь на своих сервисах (или API).

Часть аутентификации / авторизации будет обрабатываться системой аутентификации на основе токенов как слой перед вашими сервисами. Вы можете получать доступ к службам и использовать их из любого клиента, например веб-браузера, Android, iOS или настольного клиента.

А если вы ищете готовые решения, проверьте скрипты аутентификации и приложения на Envato Market.