NodeJS + Postgres DB + Passport JWT + Passport Local Login and Authentication

Здравствуйте,

Вот я пишу свой первый блог 😇 о том, как нам подключить простое [NodeJS приложение] 😎(https://www.npmjs.com/package/express) к Postgres и использовать PassportJS для аутентификации и авторизации.

Итак, базовая настройка машины будет выглядеть следующим образом:

Node JS - v12 or above

Шаг 1:

Давайте создадим простой модуль npm с помощью npm init в директории, в которой вы хотите создать свое приложение.

> npm init

Он задаст вам следующие вопросы для конфигурации

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

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

Вот как выглядит мой package.json:

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

npm i --save bcrypt-nodejs cors express jsonwebtoken nodemon passport passport-jwt passport-local pg pg-hstore sequelize

Давайте поймаем все зависимости и их работу для нас:

  • bcrypt-nodejs: Он поможет нам зашифровать и расшифровать пароль при создании нового пользователя.

  • cors: Для разрешения CROSS ORIGIN REQUESTS установите, если хотите или нужно.

  • express: Он создаст сервер, чтобы мы могли использовать его маршруты.

  • jsonwebtoken: Для создания JWT-токена для авторизации API.

  • passport: Для простой аутентификации пользователя.

  • passport-jwt: Для JWT-авторизации.

  • passport-local: Для LocalStrategy аутентификации входа в систему.

  • pg pg-hstore sequelize: Для доступа к БД Postgres

Шаг 3:

Давайте создадим простой сервер для запуска нашего проекта:

вот что у меня есть в моем файле index.js:

// project/index.js 


const express = require('express')
const db = require('./models')
var cors = require('cors')
const app = express()
const port = 3000
app.use(express.json());
app.use(cors())

db.sequelize.sync().then(() => {
    console.log("Synced")
}).catch(err => console.err(err))

app.get('/', (req, res) => {
    res.send('Hello World!')
})

require('./routes/user.route')(app)

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`)
})
Вход в полноэкранный режим Выйти из полноэкранного режима

Это утверждение делает следующее:

db.sequelize.sync().then(() => {
    console.log("Synced")
}).catch(err => console.err(err))
Войти в полноэкранный режим Выйти из полноэкранного режима

проверить, была ли подключена БД Postgres DB и продолжить ее.

И затем маршруты, которые мы создадим на следующем шаге.

И запуск нашего сервера:

Закомментируйте эту строку

require('./routes/user.route')(app)

и запустите npm run dev и посмотрите, является ли приложение Synced и работает ли оно на порту 3000.

если он отображается ниже:

YAYYYY….!!! Теперь вы создали экспресс-сервер.

Шаг 4:

Здесь начинается самое интересное:

  • Давайте создадим маршруты
// project/routes/user.route.js


module.exports = app => {

    // Import of the controller
    const user = require('../controller/user.controller')

    // Creating the router instance
    const router = require('express').Router();

    // TO create the user
    router.post('/user', user.create)

    // To Login the user using Passport Local Strategy
    router.post('/user-passport-login', user.loginWithPassport)

    // Pass the router instance to the App.
    app.use('/api/v1', router)
}
Войдите в полноэкранный режим Выход из полноэкранного режима

Каждый маршрут имеет свое собственное определение, давайте создадим наш самый первый контроллер:

// project/controller/user.controller.js

const db = require("../models");
const User = db.user;
const passportLocal = require('../config/passportLocal')

// To create a new user in the DB

function create(req, res) {
    const userdata = {
        username: req.body.username,
        password: req.body.password
    }
    User.create(userdata).then(data => {
        return res.send(data)
    }).catch(err => {
        console.warn(err)
    })
}


// To Login the user using Passport

async function loginWithPassport(req, res) {
    return await passportLocal.authenticate('local', function (err, response) {
        if (response) {
            return res.send({
                msg: "Login Success",
            })
        }
        if (!response) {
            return res.send({
                msg: "Failed"
            })
        }
    })(req, res)
}

Войти в полноэкранный режим Выход из полноэкранного режима

подождите…!!!

почему эта строка:

    })(req, res)
Войти в полноэкранный режим Выход из полноэкранного режима

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

Шаг 5:

Давайте теперь создадим наши Models:

// project/models/user.model.js

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

module.exports = (sequelize, DataTypes) => {

    // To get the feasiblity of the Sequelize ORM
    const User = sequelize.define("user", {
        username: {
            type: DataTypes.STRING,
            primaryKey: true
        },
        password: {
            type: DataTypes.STRING
        },
    });

    // It will convert each password into the Hashed String for maintaining the security
    User.beforeSave((user) => {
        if (user.changed('password')) {
            user.password = bcrypt.hashSync(user.password, bcrypt.genSaltSync(10), null)
        }
    })

    // It will compare the password to the passed string using the bcrypt algo, and will return the result
    User.prototype.comparePassowrd = function (pass, cb) {
        bcrypt.compare(pass, this.password, function (err, isMatch) {
            if (err) {
                return cb(err)
            }
            cb(null, isMatch)
        })
    }
    return User;
};
Войдите в полноэкранный режим Выход из полноэкранного режима

Мы создали модель, но сейчас она не используется, это просто схема, теперь давайте сделаем самую сложную часть, создадим таблицу БД в pgAdmin, используя следующий код:

// project/models/index.js

const dbConfig = require('../db.config')
const Sequelize = require('sequelize')

const sequelize = new Sequelize(dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD, {
    host: dbConfig.HOST,
    operatorAliases: false,
    dialect: dbConfig.dialect,
    pool: dbConfig.pool
})

const db = {}

db.Sequelize = Sequelize
db.sequelize = sequelize
db.user = require('./user.model.js')(sequelize, Sequelize)

module.exports = db;
Войти в полноэкранный режим Выйти из полноэкранного режима

dbConfig.js

// project/dbConfig.js

module.exports = {
    HOST: "localhost",
    USER: "harishsoni",
    PASSWORD: "admin",
    DB: "testDB",
    dialect: "postgres",
    pool: {
        max: 5,
        min: 0,
        acquire: 30000,
        idle: 10000
    }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Вот строка из index.js, которая использует вышеуказанную секвелизацию и синхронизацию БД:

const db = require('./models')
Войти в полноэкранный режим Выйти из полноэкранного режима

Шаг 3:

Теперь заключительная часть — создадим файл passportLocal.js, который будет содержать основную бизнес-логику для проверки аутентификации при использовании.

// project/config/passportLocal.js

const passport = require('passport')
const LocalStratery = require('passport-local').Strategy
const db = require('../models')

// Creating the passport instance to be used from the controller.

passport.use(new LocalStratery({

    // if you use any different name for the username field, you can pass the key here
    usernameField: 'username'
}, async function (username, password, done) {
    // findByPk is a Sequelize function which returns the data if it finds the primary key with the value passed
    return await db.user.findByPk(username).then(async data => {

        // Check if the user is there in the DB:
        if (!data) {
            return done(null, null)
        }

        // If the user is correct, then let's see if he has entered the correct password.
        await data.comparePassowrd(password, (err, userData) => {
            return done(null, userData)
        })
    }).catch(err => { throw err })
}))


// For Storing the user id in the session {req.session.passport.user = {id: '..'}}
passport.serializeUser(function (user, cb) {
    cb(null, user)
})

// For checking if the user has an active session.
passport.deserializeUser(function (obj, cb) {
    cb(null, obj)
})

module.exports = passport
Вход в полноэкранный режим Выход из полноэкранного режима

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

В итоге мы получим что-то вроде этого:

project
│   index.js
│   db.config.js
│   package.json
│
└───models
│    user.model.js
│    index.js
│   
└───config
│    passportLocal.js
│   
└───controller
│    user.controller.js
│   
└───routes
      user.route.js


Вход в полноэкранный режим Выход из полноэкранного режима

🥳🥳🥳 Мы закончили с настройкой, теперь время запустить и посмотреть, работает ли код (если работает, то бог знает как, а если нет, то нам нужно знать почему 😂 😂 😂 😂 😂 😂 😂).

🤞🤞 Here we gooooooooo…..!!!!

🧐🧐🧐 Это сработало::::::::::::

Давайте проверим API СЕЙЧАС:

🤞🤞🤞🤞🤞🤞🤞🤞🤞🤞

Да, это сработало: 😎😎😇😇😇

Any suggestion are welcome:
Вход в полноэкранный режим Выйти из полноэкранного режима

Ссылка на репо: https://github.com/harish9312/passport-auth-node

Оцените статью
devanswers.ru
Добавить комментарий