Автор оригинала: Manash Kumar Chakrobortty.
Аутентификация и авторизация пользователя является одной из важных элементов любого веб-приложения. Есть несколько видов способа обработки аутентификации, мы можем полагаться на стороннюю службу, такую как паспорт. Но в этой статье мы будем использовать очень простой и самостоятельный подход, который поможет нам понять основную часть аутентификации.
Технология используется
- База данных: MySQL
- Пароль хэш: bcryptjs
- Токен: jwt.
Базовая структура
Для создания базовой структуры для различных видов конечных точек, таких как регистрация или вход в систему, мы будем использовать экспресс в качестве маршрутизатора. И мы создадим папку для маршрутизаторов.
В папке маршрутов мы создадим файл auth.js для маршрутов, связанных с аутентификацией. Маршруты/auth.js.
const router = require('express').Router(); const userController = require('../controllers/user.controller'); // Register a new User router.post('/register', userController.register); // Login router.post('/login', userController.login); module.exports = router;
index.js.
const express = require('express'); const app = express(); // Import Routes const authRoute = require('./routes/auth'); // Route Middlewares app.use('/api/users', authRoute); app.listen(3005, () => console.log('Server is running'));
Регистрация/регистрация
Мы уже определили маршрут для регистрации. Теперь мы создадим папку контроллеров для папки контроллеров и моделей для моделей. Эта структура не требуется, у вас может быть разная структура или вы можете сделать все в одном файле JS.
Так что в контроллере регистрация должна быть выглядеть так Контроллеры/user.controller.js.
// Register a new User exports.register = async (req, res) => { //Hash password const salt = await bcrypt.genSalt(10); const hasPassword = await bcrypt.hash(req.body.password, salt); // Create an user object const user = new User({ mobile: req.body.mobile, email: req.body.email, name: req.body.name, password: hasPassword, status: req.body.status || 1 }); // Save User in the database try { const id = await User.create(user); user.id = id; delete user.password; res.send(user); } catch (err){ res.status(500).send(err); } };
Здесь мы использовали пакет Bcryptjs для хеш-пароля. И использовал MySQL в качестве базы данных.
Модели/user.model.js.
User.create = async (newUser) => { let insert = await sql.query("INSERT INTO user SET ?", newUser); if( insert.insertId ) { return insert.insertId; } else { return; } };
Авторизоваться
Здесь мы должны проверить адрес электронной почты или мобильный телефон против предоставленного пароля. Если предоставлена информация правильная, то мы должны генерировать токен и вернуться к клиенту. Поэтому изначально мы проверим на наличие электронной почты или мобильного телефона в нашей базе данных, если пользователь существует, то позвонит bcrypt.compare ()
Функция BCRYPTJS. Тогда мы позвоним jsonwybtokok за токен и отправьте обратно к клиенту.
Теперь мы увидим реализацию.
Контроллеры/user.controller.js.
// Login exports.login = async (req, res) => { try { // Check user exist const user = await User.login(req.body.mobile_or_email); if (user) { const validPass = await bcrypt.compare(req.body.password, user.password); if (!validPass) return res.status(400).send("Mobile/Email or Password is wrong"); // Create and assign token const token = jwt.sign({id: user.id, user_type_id: user.user_type_id}, config.TOKEN_SECRET); res.header("auth-token", token).send({"token": token}); // res.send("Logged IN"); } } catch (err) { if( err instanceof NotFoundError ) { res.status(401).send(`Mobile/Email or Password is wrong`); } else { let error_data = { entity: 'User', model_obj: {param: req.params, body: req.body}, error_obj: err, error_msg: err.message }; res.status(500).send("Error retrieving User"); } } };
Модели/user.model.js.
User.login = async (value) => { let row = await sql.query(`SELECT * FROM user WHERE mobile = ? OR email = ?`, [value, value]); if( row.length ) { return row[0]; } else { throw new NotFoundError("User does not exist"); } };
Аутентификация и авторизация
Мы часто используем взаимозаменяемо, аутентификацию и авторизацию, но эти слова представляют принципиально разные функции.
Проще говоря, аутентификация – это процесс проверки того, кто является пользователем, в то время как разрешение – это процесс проверки того, к чему у них есть доступ.
Первоначально мы просто проверим токен в заголовке запроса на ограничениями маршрутов, а затем разрешите или запретить запрос. Тогда мы проверим зарегистрированные разрешенные маршруты пользователя для доступа.
Чтобы удержать это просто, мы сохраняем поле user_type_id и с учетом значения /Нормальный пользователь. Теперь создавая среднюю посуду, чтобы сделать эту работу. помощники/auth.middleware.js.
const config = require("../config/config"); const jwt = require("jsonwebtoken"); exports.loggedIn = function (req, res, next) { let token = req.header('Authorization'); if (!token) return res.status(401).send("Access Denied"); try { if (token.startsWith('Bearer ')) { // Remove Bearer from string token = token.slice(7, token.length).trimLeft(); } const verified = jwt.verify(token, config.TOKEN_SECRET); if( verified.user_type_id === 2 ){ // Check authorization, 2 = Customer, 1 = Admin let req_url = req.baseUrl+req.route.path; if(req_url.includes("users/:id") && parseInt(req.params.id) !== verified.id){ return res.status(401).send("Unauthorized!"); } } req.user = verified; next(); } catch (err) { res.status(400).send("Invalid Token"); } } exports.adminOnly = async function (req, res, next) { if( req.user.user_type_id === 2 ){ return res.status(401).send("Access Denied"); } next(); }
Полный исходный код
https://github.com/manashcse11/express/tree/master/auth