Статьи

Использование паспорта с Sequelize и MySQL

Sequelize — это ORM Node.js, основанный на обещаниях. Он может использоваться с PostgreSQL, MySQL, MariaDB, SQLite и MSSQL. В этом руководстве мы будем реализовывать аутентификацию для пользователей веб-приложения. И мы будем использовать Passport, популярное промежуточное программное обеспечение для аутентификации для Node, вместе с Sequelize и MySQL для реализации регистрации пользователей и входа в систему.

Убедитесь, что на вашем компьютере установлено следующее:

  • Узел
  • MySQL

Для этого урока мы будем использовать Node.js вместе с Express, поэтому мы начнем устанавливать то, что нам нужно.

Создайте каталог для вашего приложения. Внутри этого каталога запустите его из своего терминала или командной строки:

1
npm init

Это инициализирует менеджер зависимостей npm. Это представит серию подсказок, которые мы быстро пройдем.

  • Введите имя вашего приложения без пробелов и нажмите Enter для «name».
  • Нажмите Enter для «версии».
  • Для «описания» в этом руководстве мы введем «Использование паспорта с Sequelize и MySQL» в качестве описания и нажмите Enter. Это тоже может быть пустым.
  • Для «точки входа (index.js)» введите server.js и нажмите Enter.
  • Для «тестовой команды» нажмите Enter.
  • Для git-репозитория вы можете ввести git-репозиторий, в котором находится ваше приложение, если оно у вас есть, или просто нажать Enter, чтобы оставить это поле пустым.
  • Для «Ключевые слова» нажмите Enter.
  • Для «автора» нажмите Enter или введите свое имя, прежде чем сделать это.
  • Для «лицензии» нажмите Enter.
  • Для ‘(Это нормально)’ это показывает, как будет выглядеть ваш package.json. Введите Да и нажмите Enter.

Основные зависимости для этого урока:

  • Экспресс
  • Sequelize
  • MySQL
  • Паспорт
  • Паспорт локальной стратегии
  • Body Parser
  • Экспресс сессия
  • Bcrypt Nodejs
  • Экспресс рули для просмотров

Чтобы установить их, из своего терминала или командной строки запустите следующую одну за другой.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
npm install express —save
 
npm install sequelize —save
 
npm install mysql —save
 
npm install passport —save
 
npm install passport-local —save
 
npm install body-parser —save
 
npm install express-session —save
 
npm install bcrypt-nodejs —save
 
npm install express-handlebars —save

Если вы используете Git для этого проекта:

В папке вашего проекта создайте файл .gitignore.

Добавьте эту строку в файл .gitignore.

node_modules

Теперь мы создаем файл сервера. Это будет основной файл, вызываемый при вводе следующего:

1
npm start

Это запускает приложение. Вы также можете запустить приложение, набрав node server.js.

1
node server.js

Затем в папке нашего проекта мы создаем новый файл и назовем этот файл server.js .

Внутри файла server.js мы вставляем следующее:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
var express = require(‘express’);
var app = express();
 
 
app.get(‘/’, function(req, res) {
 
    res.send(‘Welcome to Passport with Sequelize’);
 
});
 
 
app.listen(5000, function(err) {
 
    if (!err)
        console.log(«Site is live»);
    else console.log(err)
 
});

Первая строка присваивает экспресс-модуль переменной express. Затем мы инициализируем express и называем его переменной: app.

Затем мы заставляем приложение прослушивать порт 5000 . Вы можете выбрать любой свободный номер порта на вашем компьютере.

Затем мы вызываем app.get() экспресс-маршрутизации app.get() чтобы ответить «Добро пожаловать в Passport с Sequelize», когда GET-запрос сделан на «/».

Чтобы проверить на своем компьютере, запустите это из папки вашего проекта:

1
node server.js

Если вы видите текст «Добро пожаловать в паспорт с Sequelize» при посещении http: // localhost: 5000 /, поздравляю! В противном случае убедитесь, что вы сделали все именно так, как написано выше.

Далее мы импортируем некоторые нужные нам модули, такие как passport, express-session и body-parser.

После var app = express() мы добавляем следующие строки:

1
2
3
var passport = require(‘passport’)
var session = require(‘express-session’)
var bodyParser = require(‘body-parser’)

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

Затем мы импортируем модуль body-parser. Это извлекает всю часть тела входящего запроса и предоставляет его в формате, с которым легче работать. В этом случае мы будем использовать формат JSON.

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

1
2
3
//For BodyParser
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

Затем мы инициализируем паспорт и экспресс-сеанс и сеанс паспорта и добавляем их как промежуточное программное обеспечение. Мы делаем это, добавляя эти строки через пробел после строки импорта bodyParser.

1
2
3
4
5
6
7
// For Passport
 
app.use(session({ secret: ‘keyboard cat’,resave: true, saveUninitialized:true}));
 
app.use(passport.initialize());
 
app.use(passport.session());

Мы начнем работать над фактической аутентификацией сейчас.

Мы сделаем это в четыре этапа:

  • Настройте Sequelize с MySQL.
  • Создайте модель пользователя.
  • Настройте виды.
  • Напишите паспортную стратегию.

Сначала мы создаем базу данных в MySQL. Дайте ему ваше предпочтительное имя. Ради этого руководства давайте создадим базу данных с именем sequelize_passport в MySQL.

Затем мы настраиваем конфигурацию для обработки деталей БД.

Во-первых, давайте импортируем модуль dot-env для обработки переменных среды.

Запустите это в корневой папке проекта:

1
npm install —save dotenv

Затем мы импортируем его в основной файл сервера, server.js, чуть ниже других импортов.

1
var env = require(‘dotenv’).load();

Затем мы создаем файл в папке нашего проекта и назовем его .env.

Следующий шаг необязателен, если вы не используете Git:

Мы добавим файл .env в ваш файл .gitignore.

Ваш файл .gitignore должен выглядеть так:

1
2
node_modules
.env

После этого мы добавляем нашу среду в файл .env, добавив следующую строку:

NODE_ENV='development'

Затем мы создаем файл config.json, который будет использоваться Sequelize для управления различными средами.

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

config/config.json

Затем мы вставляем следующий код в наш файл config.json.

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
{
 
    «development»: {
 
        «username»: «root»,
 
        «password»: null,
 
        «database»: «sequelize_passport»,
 
        «host»: «127.0.0.1»,
 
        «dialect»: «mysql»
 
    },
 
    «test»: {
 
        «username»: «»,
 
        «password»: null,
 
        «database»: «»,
 
        «host»: «»,
 
        «dialect»: «mysql»
 
    },
 
    «production»: {
 
        «username»: «»,
 
        «password»: null,
 
        «database»: «»,
 
        «host»: «127.0.0.1»,
 
        «dialect»: «mysql»
 
    }
 
}

Не забудьте заменить значения в блоке разработки выше данными вашей аутентификации базы данных.

Далее мы устанавливаем sequelize с помощью npm. Для этого выполните следующую команду в корневой папке проекта:

1
npm install —save sequelize

Теперь пришло время создать папку моделей .

Сначала мы создаем каталог с именем app в папке нашего проекта.

Внутри папки приложения мы создаем новую папку с именем models и создаем новый файл с именем index.js в папке models .

Внутри файла index.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
27
28
29
30
31
32
«use strict»;
 
var fs = require(«fs»);
var path = require(«path»);
var Sequelize = require(«sequelize»);
var env = process.env.NODE_ENV ||
var config = require(path.join(__dirname, ‘..’, ‘config’, ‘config.json’))[env];
var sequelize = new Sequelize(config.database, config.username, config.password, config);
var db = {};
 
 
fs
    .readdirSync(__dirname)
    .filter(function(file) {
        return (file.indexOf(«.») !== 0) && (file !== «index.js»);
    })
    .forEach(function(file) {
        var model = sequelize.import(path.join(__dirname, file));
        db[model.name] = model;
    });
 
Object.keys(db).forEach(function(modelName) {
    if («associate» in db[modelName]) {
        db[modelName].associate(db);
    }
});
 
 
db.sequelize = sequelize;
db.Sequelize = Sequelize;
 
module.exports = db;

Этот файл используется для импорта всех моделей, которые мы помещаем в папку моделей , и их экспорта.

Чтобы проверить, что все хорошо, мы добавляем это в наш файл server.js.

01
02
03
04
05
06
07
08
09
10
11
12
13
//Models
var models = require(«./app/models»);
 
//Sync Database
models.sequelize.sync().then(function() {
 
    console.log(‘Nice! Database looks fine’)
 
}).catch(function(err) {
 
    console.log(err, «Something went wrong with the Database Update!»)
 
});

Здесь мы импортируем модели, а затем вызываем функцию синхронизации Sequelize.

Запустите это, чтобы увидеть, все ли хорошо:

1
node server.js

Если вы получите сообщение «Сайт работает хорошо! База данных выглядит хорошо», значит, вы успешно настроили Sequelize.

Если нет, пожалуйста, внимательно пройдите описанные выше шаги и попробуйте отладить проблему с помощью.

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

В нашей папке моделей мы создаем файл и называем его user.js. Полный путь к этому файлу должен быть app / models / user.js.

Откройте файл user.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
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
module.exports = function(sequelize, Sequelize) {
 
    var User = sequelize.define(‘user’, {
 
        id: {
            autoIncrement: true,
            primaryKey: true,
            type: Sequelize.INTEGER
        },
 
        firstname: {
            type: Sequelize.STRING,
            notEmpty: true
        },
 
        lastname: {
            type: Sequelize.STRING,
            notEmpty: true
        },
 
        username: {
            type: Sequelize.TEXT
        },
 
        about: {
            type: Sequelize.TEXT
        },
 
        email: {
            type: Sequelize.STRING,
            validate: {
                isEmail: true
            }
        },
 
        password: {
            type: Sequelize.STRING,
            allowNull: false
        },
 
        last_login: {
            type: Sequelize.DATE
        },
 
        status: {
            type: Sequelize.ENUM(‘active’, ‘inactive’),
            defaultValue: ‘active’
        }
 
 
    });
 
    return User;
 
}

Теперь запустите:

1
node server.js

Вы должны увидеть знакомое сообщение « Сайт работает. Отлично! База данных выглядит хорошо ». Это означает, что наши модели Sequelize были успешно синхронизированы, и если вы проверите свою базу данных, вы увидите таблицу пользователей с указанными столбцами.

Сначала давайте создадим представление для регистрации и подключим его.

Первое, что нужно сделать, это импортировать модуль экспресс-руля, который мы используем для представлений в этом руководстве.

Добавьте эту строку в основной стартовый файл server.js.

var exphbs = require('express-handlebars')

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

1
2
3
4
5
6
7
var express = require(‘express’)
var app = express()
var passport = require(‘passport’)
var session = require(‘express-session’)
var bodyParser = require(‘body-parser’)
var env = require(‘dotenv’).load()
var exphbs = require(‘express-handlebars’)

Затем мы добавляем следующие строки в наш файл server.js.

1
2
3
4
5
6
//For Handlebars
app.set(‘views’, ‘./app/views’)
app.engine(‘hbs’, exphbs({
    extname: ‘.hbs’
}));
app.set(‘view engine’, ‘.hbs’);

Теперь в нашей папке приложения мы создаем три папки с именами views, контроллеры и маршруты .

В папке views мы создаем файл с именем signup. HBS и вставьте код ниже в нем.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html>
 
<head>
    <title></title>
</head>
 
<body>
    <form id=»signup» name=»signup» method=»post» action=»/signup»>
        <label for=»email»>Email Address</label>
        <input class=»text» name=»email» type=»email» />
        <label for=»firstname»>Firstname</label>
        <input name=»firstname» type=»text» />
        <label for=»lastname»>Lastname</label>
        <input name=»lastname» type=»text» />
        <label for=»password»>Password</label>
        <input name=»password» type=»password» />
        <input class=»btn» type=»submit» value=»Sign Up» />
    </form>
 
</body>
 
</html>

Затем в нашей папке контроллеров мы создаем новый файл и называем его authcontroller.js.

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

1
2
3
4
5
6
7
var exports = module.exports = {}
 
exports.signup = function(req, res) {
 
    res.render(‘signup’);
 
}

Далее мы создаем маршрут для регистрации. В папке маршрутов мы создаем новый файл с именем auth.js, а затем в этом файле мы импортируем контроллер авторизации и определяем маршрут регистрации.

1
2
3
4
5
6
7
var authController = require(‘../controllers/authcontroller.js’);
 
module.exports = function(app) {
 
    app.get(‘/signup’, authController.signup);
 
}

Теперь мы импортируем этот маршрут в наш server.js и передадим app в качестве аргумента.

На сервере после импорта моделей добавьте следующие строки:

1
2
//Routes
var authRoute = require(‘./app/routes/auth.js’)(app);

Запустите это:

1
node server.js

Теперь зайдите на http: // localhost: 5000 / signup, и вы увидите форму регистрации.

Давайте повторим шаги для формы входа. Как и прежде, мы создадим файл с именем signin.hbs в нашей папке представлений и вставим в него следующий HTML-код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>
 
<head>
    <title></title>
</head>
 
<body>
    <form id=»signin» name=»signin» method=»post» action=»signin»>
        <label for=»email»>Email Address</label>
        <input class=»text» name=»email» type=»text» />
        <label for=»password»>Password</label>
        <input name=»password» type=»password» />
        <input class=»btn» type=»submit» value=»Sign In» />
    </form>
 
</body>
 
</html>

Затем добавьте контроллер для входа в app / controllers / authcontroller.js.

1
2
3
4
5
exports.signin = function(req, res) {
 
    res.render(‘signin’);
 
}

Затем в app / routs / auth.js мы добавляем маршрут для входа в систему следующим образом:

app.get('/signin', authController.signin);

Теперь, когда вы бежите:

1
node server.js

и посетите http: // localhost: 5000 / signin / , вы должны увидеть форму входа.

Последний и важный шаг — написание наших паспортных стратегий.

В app / config мы создаем новую папку с именем passport.

Затем в нашей новой папке app / config / passport мы создаем новый файл и назовем его passport.js . Этот файл будет содержать наши паспортные стратегии.

В passport.js мы будем использовать пользовательскую модель и паспорт.

Сначала мы импортируем bcrypt, который нам нужен для защиты паролей.

var bCrypt = require('bcrypt-nodejs');

Затем мы добавляем блок module.exports следующим образом:

1
2
3
module.exports = function(passport, user) {
 
}

Внутри этого блока мы инициализируем стратегию passport-local и модель пользователя, которая будет передана в качестве аргумента. Вот как мы это делаем:

1
2
3
4
5
6
module.exports = function(passport, user) {
 
    var User = user;
    var LocalStrategy = require(‘passport-local’).Strategy;
 
}

Затем мы определяем нашу собственную стратегию с нашим экземпляром LocalStrategy следующим образом:

01
02
03
04
05
06
07
08
09
10
passport.use(‘local-signup’, new LocalStrategy(
 
    {
        usernameField: ’email’,
        passwordField: ‘password’,
        passReqToCallback: true // allows us to pass back the entire request to the callback
 
    },
 
));

Теперь мы объявили, какие поля запроса ( req ) имеют наши usernameField и passwordField (переменные паспорта).

Последняя переменная passReqToCallback позволяет нам передать весь запрос обратному вызову, что особенно полезно для регистрации.

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

1
2
3
function(req, email, password, done) {
 
 }

В этой функции мы будем хранить данные пользователя.

Сначала мы добавляем нашу функцию генерации хешированного пароля в функцию обратного вызова.

1
2
3
4
5
var generateHash = function(password) {
 
    return bCrypt.hashSync(password, bCrypt.genSaltSync(8), null);
 
};

Затем, используя пользовательскую модель Sequelize, которую мы инициализировали ранее как Пользователь , мы проверяем, существует ли пользователь, и если нет, то добавляем его.

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
User.findOne({
    where: {
        email: email
    }
}).then(function(user) {
 
    if (user)
 
    {
 
        return done(null, false, {
            message: ‘That email is already taken’
        });
 
    } else
 
    {
 
        var userPassword = generateHash(password);
 
        var data =
 
            {
                email: email,
 
                password: userPassword,
 
                firstname: req.body.firstname,
 
                lastname: req.body.lastname
 
            };
 
 
        User.create(data).then(function(newUser, created) {
 
            if (!newUser) {
 
                return done(null, false);
 
            }
 
            if (newUser) {
 
                return done(null, newUser);
 
            }
 
        });
 
    }
 
});

User.create() — это метод Sequelize для добавления новых записей в базу данных. Обратите внимание, что значения в объекте данных получены из объекта req.body, который содержит входные данные из нашей формы регистрации.

Ваш passport.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
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//load bcrypt
var bCrypt = require(‘bcrypt-nodejs’);
 
 
module.exports = function(passport, user) {
 
 
    var User = user;
 
    var LocalStrategy = require(‘passport-local’).Strategy;
 
 
    passport.use(‘local-signup’, new LocalStrategy(
 
        {
 
            usernameField: ’email’,
 
            passwordField: ‘password’,
 
            passReqToCallback: true // allows us to pass back the entire request to the callback
 
        },
 
 
 
        function(req, email, password, done) {
 
            var generateHash = function(password) {
 
                return bCrypt.hashSync(password, bCrypt.genSaltSync(8), null);
 
            };
 
 
 
            User.findOne({
                where: {
                    email: email
                }
            }).then(function(user) {
 
                if (user)
 
                {
 
                    return done(null, false, {
                        message: ‘That email is already taken’
                    });
 
                } else
 
                {
 
                    var userPassword = generateHash(password);
 
                    var data =
 
                        {
                            email: email,
 
                            password: userPassword,
 
                            firstname: req.body.firstname,
 
                            lastname: req.body.lastname
 
                        };
 
                    User.create(data).then(function(newUser, created) {
 
                        if (!newUser) {
 
                            return done(null, false);
 
                        }
 
                        if (newUser) {
 
                            return done(null, newUser);
 
                        }
 
                    });
 
                }
 
            });
 
        }
 
    ));
 
}

Теперь мы импортируем стратегию в server.js.

Для этого мы добавляем эти строки ниже импорта маршрутов в server.js.

1
2
//load passport strategies
require(‘./app/config/passport/passport.js’)(passport, models.user);

Ваш server.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
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
var express = require(‘express’)
var app = express()
var passport = require(‘passport’)
var session = require(‘express-session’)
var bodyParser = require(‘body-parser’)
var env = require(‘dotenv’).load()
var exphbs = require(‘express-handlebars’)
 
 
//For BodyParser
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());
 
 
// For Passport
app.use(session({
    secret: ‘keyboard cat’,
    resave: true,
    saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
 
 
//For Handlebars
app.set(‘views’, ‘./app/views’)
app.engine(‘hbs’, exphbs({
    extname: ‘.hbs’
}));
app.set(‘view engine’, ‘.hbs’);
 
 
 
app.get(‘/’, function(req, res) {
 
    res.send(‘Welcome to Passport with Sequelize’);
 
});
 
//Models
var models = require(«./app/models»);
 
//Routes
 
var authRoute = require(‘./app/routes/auth.js’)(app);
 
 
//load passport strategies
 
require(‘./app/config/passport/passport.js’)(passport, models.user);
 
 
//Sync Database
 
models.sequelize.sync().then(function() {
 
    console.log(‘Nice! Database looks fine’)
 
 
}).catch(function(err) {
 
    console.log(err, «Something went wrong with the Database Update!»)
 
});
 
 
app.listen(5000, function(err) {
 
    if (!err)
 
        console.log(«Site is live»);
         
    else console.log(err)
 
});

Теперь мы фактически применим стратегию к нашему маршруту / регистрации .

Вот как мы это делаем:

Во-первых, мы идем в app / routs / auth.js и добавляем маршрут для публикации в систему, как это.

1
2
3
4
5
6
7
app.post(‘/signup’, passport.authenticate(‘local-signup’, {
        successRedirect: ‘/dashboard’,
 
        failureRedirect: ‘/signup’
    }
 
));

Поскольку нам нужен паспорт, нам нужно передать его этому методу. Мы можем импортировать паспорт в этом скрипте или передать его из server.js. Давайте сделаем последнее.

Измените функцию, экспортированную в этот файл app / routs / auth.js, чтобы в качестве параметра использовался паспорт. Код в app / route / auth.js должен выглядеть следующим образом после вашей модификации.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
var authController = require(‘../controllers/authcontroller.js’);
 
 
module.exports = function(app, passport) {
 
    app.get(‘/signup’, authController.signup);
 
 
    app.get(‘/signin’, authController.signin);
 
 
    app.post(‘/signup’, passport.authenticate(‘local-signup’, {
            successRedirect: ‘/dashboard’,
 
            failureRedirect: ‘/signup’
        }
 
    ));
 
 
 
}

Затем в server.js мы модифицируем импорт маршрутов и добавляем паспорт в качестве аргумента, например так:

var authRoute = require('./app/routes/auth.js')(app,passport);

Теперь перейдите по адресу регистрации http: // localhost: 5000 / signup / и попробуйте зарегистрироваться.

При попытке зарегистрироваться вы получите сообщение об ошибке « Не удалось сериализовать пользователя в сеанс ». Это связано с тем, что паспорт должен сохранять идентификатор пользователя в сеансе, и он использует его для управления получением сведений о пользователе при необходимости.

Чтобы решить эту проблему, мы собираемся реализовать как функции сериализации, так и десериализации паспорта в нашем файле app / config / passport / passport.js .

Сначала мы добавляем функцию сериализации. В этой функции мы будем сохранять идентификатор пользователя в сеансе.

Для этого добавляем следующие строки под инициализацией локальной стратегии.

1
2
3
4
5
6
//serialize
passport.serializeUser(function(user, done) {
 
    done(null, user.id);
 
});

Далее мы реализуем функцию десериализации. Добавьте функцию чуть ниже функции сериализации.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
// deserialize user
passport.deserializeUser(function(id, done) {
 
    User.findById(id).then(function(user) {
 
        if (user) {
 
            done(null, user.get());
 
        } else {
 
            done(user.errors, null);
 
        }
 
    });
 
});

В приведенной выше функции десериализации мы используем обещание Sequelize findById чтобы получить пользователя, и в случае успеха возвращается экземпляр модели Sequelize. Чтобы получить объект User из этого экземпляра, мы используем функцию получения Sequelize следующим образом: user.get() .

Теперь запустите снова:

1
node server.js

И попытаться зарегистрироваться. Ура, если вы получили «Cannot GET / dashboard»! Это означает, что наша аутентификация прошла успешно. Помните, что мы перенаправлены на / dashboard в нашем методе passport.authenticate в routs / auth.js

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

В нашей папке app / views мы создаем новый файл с именем dashboard.hbs и добавляем в него следующий HTML-код.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
<!DOCTYPE html>
<html>
 
<head>
    <title>Passport with Sequelize</title>
</head>
 
<body>
    <h2>Dashboard</h2>
    <h5>Hurray!
 
</body>
 
</html>

В маршрутах / auth.js мы добавляем эту строку в блок module.exports :

app.get('/dashboard',authController.dashboard);

Далее мы идем в app / controllers / authController.js и добавляем контроллер панели мониторинга.

1
2
3
4
5
exports.dashboard = function(req, res) {
 
    res.render(‘dashboard’);
 
}

Ваш AuthController.js должен выглядеть так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
var exports = module.exports = {}
 
 
exports.signup = function(req, res) {
 
    res.render(‘signup’);
 
}
 
exports.signin = function(req, res) {
 
    res.render(‘signin’);
 
}
 
 
exports.dashboard = function(req, res) {
 
    res.render(‘dashboard’);
 
}

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

Но / dashboard не является защищенным маршрутом, что означает, что даже если пользователь не вошел в систему, он может его увидеть. Мы не хотим этого, поэтому мы добавим маршрут / logout, чтобы выйти из системы, а затем защитим маршрут и протестируем то, что мы сделали.

Давай сделаем это:

В маршрутах / auth.js мы добавляем эту строку:

app.get('/logout',authController.logout);

Затем мы добавляем контроллер в app / controllers / authController.js.

1
2
3
4
5
6
7
8
9
exports.logout = function(req, res) {
 
    req.session.destroy(function(err) {
 
        res.redirect(‘/’);
 
    });
 
}

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

После этого зайдите на http: // localhost: 5000 / logout, чтобы выйти из системы. Теперь посетите http: // localhost: 5000 / dashboard .

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

Для этого мы открываем app / routs / auth.js и добавляем эту функцию в блок module.exports под всеми остальными строками кода.

1
2
3
4
5
6
7
8
9
function isLoggedIn(req, res, next) {
 
    if (req.isAuthenticated())
     
        return next();
         
    res.redirect(‘/signin’);
 
}

Затем мы модифицируем обработчик маршрута сводной панели, чтобы он выглядел так:

app.get('/dashboard',isLoggedIn, authController.dashboard);

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

Уф! Настало время реализовать заключительную часть: вход в систему.

Сначала мы добавим новую локальную стратегию входа в app / config / passport / passport.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
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
61
62
63
64
65
66
67
//LOCAL SIGNIN
passport.use(‘local-signin’, new LocalStrategy(
 
    {
 
        // by default, local strategy uses username and password, we will override with email
 
        usernameField: ’email’,
 
        passwordField: ‘password’,
 
        passReqToCallback: true // allows us to pass back the entire request to the callback
 
    },
 
 
    function(req, email, password, done) {
 
        var User = user;
 
        var isValidPassword = function(userpass, password) {
 
            return bCrypt.compareSync(password, userpass);
 
        }
 
        User.findOne({
            where: {
                email: email
            }
        }).then(function(user) {
 
            if (!user) {
 
                return done(null, false, {
                    message: ‘Email does not exist’
                });
 
            }
 
            if (!isValidPassword(user.password, password)) {
 
                return done(null, false, {
                    message: ‘Incorrect password.’
                });
 
            }
 
 
            var userinfo = user.get();
            return done(null, userinfo);
 
 
        }).catch(function(err) {
 
            console.log(«Error:», err);
 
            return done(null, false, {
                message: ‘Something went wrong with your Signin’
            });
 
        });
 
 
    }
 
));

В этой стратегии isValidPassword Функция сравнивает пароль, введенный с помощью метода сравнения bCrypt, так как мы сохранили наш пароль с помощью bcrypt .

Если данные верны, наш пользователь войдет в систему.

Теперь перейдите к route / auth.js и добавьте маршрут для публикации в / signin.

1
2
3
4
5
6
7
app.post(‘/signin’, passport.authenticate(‘local-signin’, {
        successRedirect: ‘/dashboard’,
 
        failureRedirect: ‘/signin’
    }
 
));

Ваши маршруты / auth.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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
var authController = require(‘../controllers/authcontroller.js’);
 
 
module.exports = function(app, passport) {
 
 
    app.get(‘/signup’, authController.signup);
 
 
    app.get(‘/signin’, authController.signin);
 
 
    app.post(‘/signup’, passport.authenticate(‘local-signup’, {
            successRedirect: ‘/dashboard’,
 
            failureRedirect: ‘/signup’
        }
 
    ));
 
 
    app.get(‘/dashboard’, isLoggedIn, authController.dashboard);
 
 
 
    app.get(‘/logout’, authController.logout);
 
 
    app.post(‘/signin’, passport.authenticate(‘local-signin’, {
            successRedirect: ‘/dashboard’,
 
            failureRedirect: ‘/signin’
        }
 
    ));
 
 
    function isLoggedIn(req, res, next) {
 
        if (req.isAuthenticated())
 
            return next();
 
        res.redirect(‘/signin’);
 
    }
 
}

Теперь запустите приложение и попробуйте войти в систему. У вас должна быть возможность войти в систему с любыми данными, которые вы использовали при регистрации, и вы будете перенаправлены на http : // localhost: 5000 / dashboard /.

Поздравляем, если вы сделали это до конца этого урока! Мы успешно использовали Sequelize и Passport с базой данных MySQL.

Полный код этого руководства можно найти на GitHub .

На этом мы завершаем наше руководство по использованию Passport для аутентификации пользователей с Sequelize и MySQL. Sequelize — это действительно полезный ORM для работы с MySQL при использовании Node. Я лично нашел, что это очень полезно, и вам определенно стоит подумать об использовании его в вашем следующем приложении Node-MySQL.