Аутентификация Node.js с использованием Passportjs и паспорта-локального-мангуста

Опубликовано: 27 Августа, 2022

Passport — это промежуточное ПО аутентификации для Node. Он предназначен для единственной цели — аутентификации запросов. Нецелесообразно хранить пароль пользователя в виде исходной строки в базе данных, но рекомендуется хэшировать пароль, а затем сохранять его в базе данных. Но с паспортом-местным-мангустом вам не нужно хешировать пароль с помощью модуля шифрования, паспорт-местный-мангуст сделает все за вас. Если вы используете паспорт-локальный-мангуст, этот модуль автоматически сгенерирует поля соли и хэша в БД. У вас не будет поля для пароля, вместо этого у вас будет соль и хэш.

Зачем нужна соление пароля

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

Шаги для выполнения операции

Сначала создадим экспресс-приложение, затем установим необходимые модули

> npm install passport passport-local mongoose passport-local-mongoose --save

1. Сначала создайте структуру каталогов, как показано ниже:

--model
----user.js
--route
----user.js
--app.js

2. Создайте файл model/user.js, который определяет схему пользователя.




// importing modules
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var passportLocalMongoose = require("passport-local-mongoose");
  
  
var UserSchema = new Schema({   
    email: {type: String, required:true, unique:true},
    username : {type: String, unique: true, required:true},
});
  
// plugin for passport-local-mongoose
UserSchema.plugin(passportLocalMongoose);
  
// export userschema
 module.exports = mongoose.model("User", UserSchema);

Обратите внимание, что здесь, в этой схеме, мы не добавили поля для пароля, как обычно. Это потому, что паспорт-местный-мангуст в этом не нуждается. Здесь мы не добавляли какие-либо методы для хэширования нашего пароля или сравнения наших паролей, как мы обычно делаем для аутентификации, потому что pass-local-mongoose сделает все это за нас.

3. Настройте Passport/Passport-Local в app.js:

В app.js сначала нужно инициализировать паспорт




app.use(passport.initialize());
app.use(passport.session());

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




passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

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

Теперь нам нужно определить стратегии для паспорта. Для паспорта местного мангуста код




const User = require("./models/user");
  
const LocalStrategy = require("passport-local").Strategy;
passport.use(new LocalStrategy(User.authenticate()));

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

4. Создайте файл route/user.js:

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




// importing modules 
const express = require("express"); 
const router = express.Router(); 
    
// importing User Schema 
const User = require("../model/user");

5.Для регистрации:

Теперь для регистрации код должен быть




router.post("/login", function(req, res) {
      
    Users=new User({email: req.body.email, username : req.body.username});
  
          User.register(Users, req.body.password, function(err, user) {
            if (err) {
              res.json({success:false, message:"Your account could 
              not be saved. Error: ", err}) 
            }else{
              res.json({success: true, message: "Your account has 
               been saved"})
            }
          });
});

Посмотрите в приведенном выше коде, мы не определили наш пароль в новом пользователе. Вместо этого мы используем пароль с функцией User.Register(), которая является функцией паспорта-локала-мангуста. Теперь, если вы проверите свою базу данных для сохраненного пользователя, это будет выглядеть так, как показано ниже.

{
    "_id" : ObjectId("5ca8b66535947f4c1e93c4f1"),
    "username" : "username you gave",
    "email" : "email you gave",
    "salt" : "4c8f6e009c4523b23553d9479e25254b266c3b7dd2dbc6d4aaace01851c9687c",
    "hash" : "337de0df58406b25499b18f54229b9dd595b70e998fd02c7866d06d2a6b25870d23650
cdda829974a46e3166e535f1aeb6bc7ef182565009b1dcf57a64205b5548f6974b77c2e3a3c6aec5360d
55f9fcd3ffd6fb99dce21aab021aced72881d3720f6a0975bfece4922282bb748e0412955e0afa2fb8c9
f5055cac0fb01a4a2288af2ce2a6563ed9b47852727749c7fe031b6b7fbb726196dbdfeeb6766d5cba6a
055f66eeacce685daef8b6c1aed0108df511c92d49150efb6473ee71c5149dd06bfb4f73cb60f9815af0
1e02fde8d8ed822bb3a55f040237cf80de0b1534de6bbafcb53f882c6eb03de4b4aa307828974eb51261
661efb5155e68ad0e593c0f5fab7d690c2257df4369e9d5ac7e2fc93b5b014260c6f8fbb01034b3f85ec
f11e086e9bf860f959d0e2104a1f825d286c99d3fc6f62505d1fde8601345c699ea08dcc071e5547835c
16957d3830998a10762ebd143dc557d6a96e4b88312e1e4c51622fef3939656c992508e47ddc148696df
3152af76286d636d4814a0dc608f72cd507c617feb77cbba36c5b017492df5f28a7a3f3b7881caf6fb4a
9d6231eca6edbeec4eb1436f1e45c27b9c2bfceccf3a9b42840f40c65fe499091ba6ebeb764b5d815a43
d73a888fdb58f821fbe5f7d92e20ff8d7c98e8164b4f10d5528fddbcc7737fd21b12d571355cc605eb36
21f5f266f8e38683deb05a6de43114",
    "__v" : 0
}

Вы можете заметить, что поля для пароля вообще нет, вместо этого паспорт-локальный-мангуст создал для вас соль и хеш, и вам также не нужно было определять поля соли и хэша в вашей схеме. Passport-local-mongoose сохранит ваше имя пользователя уникальным, т. е. если имя пользователя уже существует, оно выдаст «UserExistsError».

5.Для входа:

Теперь для входа




userController.doLogin = function(req, res) {
  if(!req.body.username){
    res.json({success: false, message: "Username was not given"})
  } else {
    if(!req.body.password){
      res.json({success: false, message: "Password was not given"})
    }else{
      passport.authenticate("local", function (err, user, info) { 
         if(err){
           res.json({success: false, message: err})
         } else{
          if (! user) {
            res.json({success: false, message: "username or password incorrect"})
          } else{
            req.login(user, function(err){
              if(err){
                res.json({success: false, message: err})
              }else{
                const token =  jwt.sign({userId : user._id, 
                   username:user.username}, secretkey, 
                      {expiresIn: "24h"})
                res.json({success:true, message:"Authentication 
                    successful", token: token });
              }
            })
          }
         }
      })(req, res);
    }
  }
};

6. Сброс или изменение паролей:

Вы можете сбросить или изменить пароли, используя 2 простые функции в файлеpassword-local-mongoose. Это функция setPassword и функция changePassword . Обычно setPassword используется, когда пользователь забыл пароль, а changePassword используется, когда пользователь хочет сменить пароль.

для setPassword код

// user is your result from userschema using mongoose id
 user.setPassword(req.body.password, function(err, user){ ..

Для смены пароля

// user is your result from userschema using mongoose id
  user.changePassword(req.body.oldpassword, req.body.newpassword, function(err) ...

Вы можете напрямую вызывать их в файлах маршрутизатора.