Hướng dẫn api login nodejs - api đăng nhập nodejs

Hôm nay mình sẽ hướng dẫn các bạn xây dựng API để đăng ký đăng nhập với nodejs, express, mongodb và jwt.

2021-07-24 2039 lượt xem 2039 lượt xem

  1. Trang Chủ
  2. [NODEJS CƠ BẢN] platform nodejs - V8 JavaScript Runtime
  3. Xây dựng api login register với nodejs xác thực Với JWT 2021

bài viết được viết bởi trương thanh hùng https://ebudezain.com/

hùng đẹp trai

tôi thích vậy đó

JWT Là Gì?

hùng đẹp trai

tôi thích vậy đó

JWT Là Gì?

tôi thích vậy đó

hùng đẹp trai

tôi thích vậy đó

bài viết được viết bởi trương thanh hùng https://ebudezain.com/

tôi thích vậy đó

tôi thích vậy đó

JWT Là Gì?

tôi thích vậy đó

JWT Là Gì?

hùng đẹp trai

tôi thích vậy đó

JWT Là Gì?

tôi thích vậy đó

hùng đẹp trai

tôi thích vậy đó

JWT Là Gì?

hùng đẹp trai

tôi thích vậy đó

tôi thích vậy đó

tôi thích vậy đó

JWT Là Gì?

hùng ebudezain

tôi thích vậy đó

hùng đẹp trai

hùng đẹp trai

tôi thích vậy đó

npm i node-input-validator

JWT Là Gì?

tôi thích vậy đó

tôi thích vậy đó

hùng đẹp trai

JWT Là Gì?

JWT Là Gì?

tôi thích vậy đó

JWT Là Gì?

JWT Là Gì?

hùng ebudezain

JWT Là Gì?

hùng ebudezain

JWT Là Gì?

JWT Là Gì?

JWT Là Gì?

tôi thích vậy đó

bài viết được viết bởi trương thanh hùng https://ebudezain.com/

JWT Là Gì?

tôi thích vậy đó

tôi thích vậy đó

hùng đẹp trai

bài viết được viết bởi trương thanh hùng https://ebudezain.com/

tôi thích vậy đó

JWT Là Gì?

bài viết được viết bởi trương thanh hùng https://ebudezain.com/

|- PROJECT/
|     |- controller/
|     |-    |- Api/
|     |-    |-    |- user.controller.js
|     |- middleware/
|     |-    |- general.middleware.js
|     |-    |- jwt.middleware.js
|     |-    |- user.middleware.js
|     |- helper/
|     |-    |- auth.helper.js 
|     |-    |- error.helper.js
|     |- models/
|     |-    |- user.model.js
|     |- routes/
|     |-    |- api.js
|     |- .env
|     |- app.js
|     |- package.json

bài viết được viết bởi trương thanh hùng https://ebudezain.com/

tôi thích vậy đó

JWT Là Gì?

JWT Là Gì?

bài viết được viết bởi trương thanh hùng https://ebudezain.com/

tôi thích vậy đó

tôi thích vậy đó

JWT Là Gì?

hùng đẹp trai

tôi thích vậy đó

require('dotenv').config()
const jwt    = require('jsonwebtoken')
const secret = process.env.JWT_SECRET || 'jsonwebtoken-secret' // mình có dùng dotenv 
// vào file .env tạo 1 chuỗi JWT_SECRET bất kỳ
let hashTokenAccess = async user => {

    return jwt.sign(user, secret, { expiresIn: '1800s' })
}
module.exports = {
    hashTokenAccess
}

JWT Là Gì?

tôi thích vậy đó

JWT Là Gì?

bài viết được viết bởi trương thanh hùng https://ebudezain.com/

tôi thích vậy đó

tôi thích vậy đó

tôi thích vậy đó

tôi thích vậy đó

|- PROJECT/
|     |- controller/
|     |-    |- Api/
|     |-    |-    |- user.controller.js
|     |- middleware/
|     |-    |- general.middleware.js
|     |-    |- jwt.middleware.js
|     |-    |- user.middleware.js
|     |- helper/
|     |-    |- auth.helper.js 
|     |-    |- error.helper.js
|     |- models/
|     |-    |- user.model.js
|     |- routes/
|     |-    |- api.js
|     |- .env
|     |- app.js
|     |- package.json
2

JWT Là Gì?

hùng đẹp trai

hùng đẹp trai

tôi thích vậy đó

module.exports.apiResponseErrorResource = function( req, res ){
    let response = {}
    if(req.errors){
        let errors = Object.keys(req.errors).map( objKey => {
            let error = req.errors[objKey];
            return { error: objKey, ...error }
        })
        response.code             = 422,
        response.message          = "đã có lỗi xảy ra"
        response.internal_message = "đã có lỗi xảy ra"
        response.errors           = errors
        return res.status(response.code).json(response)
    }
}

hùng đẹp trai

tôi thích vậy đó

hùng đẹp trai

hùng đẹp trai

tôi thích vậy đó

JWT Là Gì?

user.model.js: 

hùng đẹp trai

tôi thích vậy đó

'use strict'

const bcrypt           = require('bcrypt'),
      SALT_WORK_FACTOR = 12,
      mongoose         = require('mongoose'),
      Schema           = mongoose.Schema
      
const UserSchema = new Schema(
    {
        username: {
            type: String,
            required: true,
            minlength: 1,
            maxlength: 3000
        },
        email: {
            type: String,
            required: true,
            unique: true,
            lowercase: true,
            trim: true,
            minlength: 1,
            maxlength: 500
        },
        password: {
            type: String,
            required: true,
            maxlength: 100000,
        }
    }, {
        timestamps: true
    }
)

/**
 * Là function để so sánh chuỗi hash password đã gửi vào có đúng với trên hệ thống không? 
 * @param { String } _password là password đang được hash 
 * @version 0.0.1
 */
UserSchema.methods.comparePassword = function(_password) {
    return bcrypt.compareSync(_password, this.password);
}

/**
 * Là function để trước khi lưu mới hoặc update mới password thì sẽ modify nó trước khi lưu
 * @async
 * @version 0.0.1
 */
UserSchema.pre('save', async function(next) {
    if (!this.isModified('password')) return next()
    /// nếu là thêm mới hoặc update password thì băm trước
    try {
        const salt    = await bcrypt.genSalt(SALT_WORK_FACTOR)
        this.password = await bcrypt.hash(this.password, salt)
        return next()
    } catch (err) {
        return next(err)
    }
})
UserSchema.methods.toResources = function() {   
    return {
        _id      : this._id,
        username : this.username,
        email    : this.email,
        createdAt: this.createdAt,
        updatedAt: this.updatedAt,
    }
}
module.exports = mongoose.model("users", UserSchema)
 

tôi thích vậy đó

tôi thích vậy đó

JWT Là Gì?

hùng đẹp trai

tôi thích vậy đó

bài viết được viết bởi trương thanh hùng https://ebudezain.com/

tôi thích vậy đó

JWT Là Gì?

JWT Là Gì?

tôi thích vậy đó

const User       = require("../../models/user.model"),
      authHelper = require("../../helpers/auth.helper")

/**
 * Là function với method post để đăng ký 1 user vào hệ thống
 * @async
 * @method POST
 * @param {{ body: Object }} req 
 * @param { Object } res 
 * @returns { Promise } là 1 json object trả về đối tượng user vừa đăng ký
 * @version 0.0.1
 * @see https://... đường đẫn đến swagger
 */
module.exports.register = async ( req, res ) => {

    let code     = 500,
        response = {}
    /// giả sử khúc này  tới đây bạn đã sử dụng middleware ở ngoài để validate dữ liệu đầu vào
    try {
        const { username, email, password } = req.body
        /// check email tồn tại
        const isExist = await User.findOne({ email })
        if( isExist ){
            code = 409 /// 409 Conflict
            throw new Error("email đã tồn tại!!")
        }
        /// lưu vào db mongo
        const user = await new User({ username, email, password }).save()
        /// khúc này nếu bạn kỹ tính hãy tạo 1 phương thức chung để format dữ liệu 
        /// còn mình làm nhanh thì trả ra dữ liệu luôn
        response.code             = 200
        response.data             = user.toResources()
        response.message          = "tạo user thành công"
        response.internal_message = `Bạn đã tạo thành công mới 1 user với email là ${email}`

        return res.status(response.code).json(response)

    } catch (error) {
        
        let err                       = { error: 'error', message: error.message }
            response.code             = code || 500
            response.message          = error.message
            response.internal_message = error.message
            response.errors           = [ err ]

        return res.status(response.code).json(response)
    }
}

/**
 * Là function với method post để login 1 user vào hệ thống
 * @async
 * @method POST
 * @param {{ body: Object }} req 
 * @param { Object } res 
 * @returns { Promise< JSON > } là 1 json object trả về jwt
 * @version 0.0.1
 * @see https://... đường đẫn đến swagger
 */
 module.exports.login = async ( req, res ) => {

    let code     = 500,
        response = {}
    /// giả sử khúc này  tới đây bạn đã sử dụng middleware ở ngoài để validate dữ liệu đầu vào
    try {
        const { email, password } = req.body
        /// check email tồn tại
        const user = await User.findOne({ email }) /// vì email duy nhất nên findOne
        if( !user ){
            code = 401 /// 401 Unauthorized
            throw new Error("Email hoặc password không đúng!!")
        }
        /// nếu có email cần check xem password có match đúng với db không? 
        const isMatch = await user.comparePassword(password)
        if( !isMatch ){
            /// nếu password không chính xác thì trả ra lỗi
            code = 401 /// 401 Unauthorized
            throw new Error("Email hoặc password không đúng!!")
        }
        /// nếu email và password chính xác thì tạo 1 mã jwt quăng ra cho ngừoi dùng
        const strJWT = await authHelper.hashTokenAccess(user.toResources())
        
        /// khúc này nếu bạn kỹ tính hãy tạo 1 phương thức chung để format dữ liệu 
        /// còn mình làm nhanh thì trả ra dữ liệu luôn
        response.code             = 200
        response.data             = strJWT
        response.message          = "User login thành công"
        response.internal_message = `Bạn đã login thành công mới 1 user với email là ${email}`

        return res.status(response.code).json(response)

    } catch (error) {
        
        let err                       = { error: 'error', message: error.message }
            response.code             = code || 500
            response.message          = error.message
            response.internal_message = error.message
            response.errors           = [ err ]
            
        return res.status(response.code).json(response)
    }
} 
module.exports.getUser = async (req, res) => {

    let response = {},
        code = 500
    try {
        const { user } = req
        /// response 
        response.code             = 200
        response.data             = user
        response.message          = "buộc phải login nè"
        response.internal_message = "buộc phải login nè"
        return res.status(response.code).json(response)

    } catch (error) {

        let err                       = { error: 'error', message: error.message }
            response.code             = code || 500
            response.message          = error.message
            response.internal_message = error.message
            response.errors           = [err]
        return res.status(response.code).json(response)
    }
}
//

JWT Là Gì?

JWT Là Gì?

tôi thích vậy đó

JWT Là Gì?

JWT Là Gì?

hùng đẹp trai

JWT Là Gì?

hùng ebudezain

tôi thích vậy đó

tôi thích vậy đó

tôi thích vậy đó

tôi thích vậy đó

hùng đẹp trai

tôi thích vậy đó

hùng đẹp trai

hùng đẹp trai

general.middleware.js

JWT Là Gì?

tôi thích vậy đó

tôi thích vậy đó

tôi thích vậy đó

jwt.middleware.js

JWT Là Gì?

hùng đẹp trai

require('dotenv').config()
const jwt    = require('jsonwebtoken')
const secret = process.env.JWT_SECRET || 'jsonwebtoken-secret' // mình có dùng dotenv 

let isAuth = async (req, res, next) => {

    let code     = 401,
        response = {}
    // Lấy token được gửi lên từ phía client, thông thường tốt nhất là các bạn nên truyền token vào header
    const access =  req.headers["x-access-token"] || req.headers["authorization"] || req.query.token || req.body.token
    try {

        if (!access) {
            code = 403
            /// không tồn tại access token
            throw new Error('Unauthorized!!!')
        }
        // Thực hiện giải mã token xem có hợp lệ hay không?
        // let user = await jwt.decode( access, secret ) => hàm này chỉ decode thôi nghen không phải xác thực
        const user = await jwt.verify( access, secret ) // hàm này để xác thực

        // Nếu token hợp lệ, lưu thông tin giải mã được vào đối tượng req, dùng cho các xử lý ở phía sau.
        req.user = user
        
        // Cho phép req đi tiếp sang controller.
        next();
    } catch (error) {
        
        // Nếu giải mã gặp lỗi: Không đúng, hết hạn...etc:
        response.code             = code || 401
        response.message          = error.message || 'Unauthorized.'
        response.internal_message = error.message || 'Unauthorized!'

        return res.status(response.code).json(response)
    }
}

let isAuthSocket = async token => {

    try {

        return await jwt.verify( token, secret )
    } catch (error) {
        return false
    }
}

module.exports = {
    isAuth,
    isAuthSocket,
}

JWT Là Gì?

bài viết được viết bởi trương thanh hùng https://ebudezain.com/

bài viết được viết bởi trương thanh hùng https://ebudezain.com/

tôi thích vậy đó

JWT Là Gì?

|- PROJECT/
|     |- controller/
|     |-    |- Api/
|     |-    |-    |- user.controller.js
|     |- middleware/
|     |-    |- general.middleware.js
|     |-    |- jwt.middleware.js
|     |-    |- user.middleware.js
|     |- helper/
|     |-    |- auth.helper.js 
|     |-    |- error.helper.js
|     |- models/
|     |-    |- user.model.js
|     |- routes/
|     |-    |- api.js
|     |- .env
|     |- app.js
|     |- package.json
3.middleware.js

tôi thích vậy đó

JWT Là Gì?

JWT Là Gì?

const node_validator = require('node-input-validator'),
      errorHelper    = require('../helpers/error.helper'),
      { Validator }  = node_validator

let REGISTER = async function( req, res, next ){

    let validate = new Validator(req.body, {
        username: "required|string|minLength:1|maxLength:10000",
        email   : "required|email|minLength:3|maxLength:500",
        password: "required|string|minLength:1|maxLength:1000",
    },{
        'title.required'     : ":attribute is required"
    });
     
    let matched = await validate.check()
    if (!matched) {
        req.errors = validate.errors
        return errorHelper.apiResponseErrorResource( req, res )
    }
    next()
}

let LOGIN = async function( req, res, next ){

    let validate = new Validator(req.body, {
        email   : "required|email|minLength:3|maxLength:500",
        password: "required|string|minLength:1|maxLength:1000",
    },{
        'title.required'     : ":attribute is required"
    });
     
    let matched = await validate.check()
    if (!matched) {
        req.errors = validate.errors
        return errorHelper.apiResponseErrorResource( req, res )
    }
    next()
}

module.exports = {
    REGISTER,
    LOGIN,
}

tôi thích vậy đó

tôi thích vậy đó

JWT Là Gì?

tôi thích vậy đó

JWT Là Gì?

hùng ebudezain

tôi thích vậy đó

tôi thích vậy đó

hùng đẹp trai

/**
 * author hungtt
*/
const express = require("express")
const router  = express.Router()

const userApiController = require("../controller/Api/user.controller")
const generalMiddleware = require('../middlewares/general.middleware'),
      authMiddleware    = require('../middlewares/jwt.middleware'),
      userMiddleware    = require('../middlewares/user.middleware')
/**
 * Init all APIs on your application
 * @param {*} app from express
 */
let initAPIs = app => {
    ////////////////////////////////////////////////////////////////////////////
    router.use([ generalMiddleware.formatJsonApi, generalMiddleware.setAllowOrigin ])
    ////////////////////////////////////////////////////////////////////////////
    /////////////////// Route không cần login ////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////
    router.post('/register', [ userMiddleware.REGISTER ], userApiController.register)
    router.post('/login', [ userMiddleware.LOGIN ], userApiController.login)
    ////////////////////////////////////////////////////////////////////////////
    router.use([ authMiddleware.isAuth])
    ////////////////////////////////////////////////////////////////////////////
    /////////// route cần verify thành công jwt ////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////
    router.get('/users', userApiController.getUser )
    
    return app.use( "/api", router )
}
module.exports = initAPIs

tôi thích vậy đó

tôi thích vậy đó

tôi thích vậy đó

tôi thích vậy đó

bài viết được viết bởi trương thanh hùng https://ebudezain.com/

tôi thích vậy đó

tôi thích vậy đó

tôi thích vậy đó

hùng đẹp trai

hùng thông minh lắm

Trong file app.js chỉ cần thực hiện thêm thao tác : 

bài viết được viết bởi trương thanh hùng https://ebudezain.com/

tôi thích vậy đó

ahihi đồ ngốc trương thanh hùng nè

const initAPIs = require("./routes/api")
/// set root api
initAPIs(app)

tôi thích vậy đó

ahihi đồ ngốc trương thanh hùng nè

đọc dữ liệu hộ bố

ahihi đồ ngốc trương thanh hùng nè

Hướng dẫn api login nodejs - api đăng nhập nodejs

đọc dữ liệu hộ bố

hùng thông minh lắm

Xong ! bây giừo chạy npm start lên và xem kết quả: 

Xong ! bây giừo chạy npm start lên và xem kết quả: 

ahihi đồ ngốc trương thanh hùng nè

đọc dữ liệu hộ bố

tôi thích vậy đó

Hướng dẫn api login nodejs - api đăng nhập nodejs

Xong ! bây giừo chạy npm start lên và xem kết quả: 

ahihi đồ ngốc trương thanh hùng nè

bài viết được viết bởi trương thanh hùng https://ebudezain.com/

bài viết được viết bởi trương thanh hùng https://ebudezain.com/

tôi thích vậy đó

đọc dữ liệu hộ bố

ahihi đồ ngốc trương thanh hùng nè

bài viết được viết bởi trương thanh hùng https://ebudezain.com/

tôi thích vậy đó

Hướng dẫn api login nodejs - api đăng nhập nodejs

ahihi đồ ngốc trương thanh hùng nè