5分钟了解 NodeJS 密码加密 + Token生成 jsonwebtoken &bcryptjs

 想写个简介写了又删,删了又写,实在想不出什么好的词汇了.这个topic其实对于很多前端和全栈来说涉及的不多,毕竟在一个项目中nodejs的密码加密和token的部分在你入职的时候已经有人完成了,如果一个新项目要求从0开始或者想扩展下实践的技术栈不妨来了解下.

0.准备工作

  • Nodejs既然是Nodejs作为后端,首先我们要有一个nodejs的环境.推荐>=18.
  • Ejs.做nodejs的都了解,nodejs模版引擎
  • nodemon:让nodejs service持久化

  • express不多说了

  • 还有其他一些插件后续用到再做说明

1.Express替换模版引擎

传统方法直接新建文件

mkdir myapp
cd muapp 
npm init

来点不一样的,使用express generator来一步搞定

mkdir myapp
cd myapp 
npx express-generator

看下目录结构

不错,继续 npm i  创建node_moduls初始化我们的express项目.执行npm run start or yarn start
看下效果,虽然大多数时候我们用不到UI界面,但是开发和测试的时候还是得有个界面方便我们调试开发这比纯后端的摸黑开发好很多.

习惯了手动配置端口的可能有点陌生,端口在哪?bin->www

打开游览器http://localhost:3000/

很多express的servic已经启动.

更改模版引擎.

默认的是jade模版,但是看上去很难接受,这里换成对vue,jsp开发都好理解的ejs.

npm i ejs -D

修改引用引擎.在app.js中替换

app.set('view engine', 'jade') =>
app.set('view engine', 'ejs')

修改package.json 添加nodemon启动规则,不用每次修改都重新re-strart service的繁琐操作

 "dev": "nodemon ./bin/www"

修改index.jade => index.ejs,别忘也把error.ejs顺手改了 

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
  </head>
<body >
    <div>Hello Evan <%= title %></div> 
</body>



看下效果,舒服了

2. 密码加密

  使用的bcryptjs 插件,为什么用这个.好处也是它的劣势,加密后不可逆,加密后没办法再转明文创建一个加密方法

const bcrypt = require('bcryptjs');

const hashLen = 10
const hashPassword = (pwd) => {
    return bcrypt.hashSync(pwd, hashLen)
}

const comparePassword = (pwd, hash) =>{
    return bcrypt.compareSync(pwd, hash, (err, isMatch) => isMatch)
}
module.exports = {
    hashPassword,
    comparePassword,
}

haslen: 密码后的秘文长度

hashPassword: 新用户注册的时候为其加密密码

comparePassword:当前端发送秘文时候与db中存储的秘文比较验证是否可以登录,或者权重.

3.生成token

npm i jsonwebtoken

     genterator token方法

const jwt = require('jsonwebtoken');
const secret = ('../keys/secret')
const createToken = (data, time) => {
    return jwt.sign(data, secret, {expiresIn: time})
}

需求在创建一个解密的密文文件 (keys/secret) 如果别人知道这个解密的密钥token就十分不安全了,很推荐用代理服务做获取

const secretKey = `adahksldss is hsd ^^ !@123`

module.exports = secretKey

 在来一个验证token的合法性的函数

const verifyToken = (token) => {
    try {
        return jwt.verify(token, secret);
    } catch (e) {
        console.log(e);
        return false;
    }
}

很简单的代码全部完成. 

创建新的路由登录加密

在app.js中 

app.use('/login',login)

在router中创建login.js

const express = require('express');
const router = express.Router();
const db = require('../db/db');
const {hashPassword, comparePassword} = require('../keys/valition')

创建新用户,并加密密码

            const addUserSql = `INSERT INTO users values ( ?, ?, ? ,? ,?, ?)`;
            db.insert(addUserSql, [null,new Date(), acc,null, 0, await hashPassword(psd)], function(data, err) {
                if (data != "1") {
                    console.log(`create new user: ${acc} successfully.`)
                    res.send(`create new user: ${acc} successfully.`)
                } else {
                    res.send(err)
                    throw err
                }
            })

已注册用户登录(密码登录,没有token情况)

            const s = comparePassword(psd.toString(), data[0]['pwd'].toString())
            if (s) {
                const token = createToken({username:acc}, '1h');
                // res.header('Authorization', `Bearer ${token}`)
                res.setHeader('Access-Control-Expose-Headers', 'Authorization');
                res.header('Authorization', `Bearer ${token}`)
                res.send({
                    statecode: `success`,
                    stateMessage: `username: ${acc} login successful`,
                    userInfo: {
                        role:data[0]['content'],
                        roleLevel: data[0]['level'],
                        lastloginTime: data[0]['lastlogindate'],
                    }
                })
               await markLoginTime(acc)
            } else {
                res.send({
                    statecode: `error`,
                    stateMessage:  `username or password not correct`
                })
            }

使用token验证只需要函数替换成我们上面提到的验证token的函数就可以

const s = comparePassword(psd.toString(), data[0]['pwd'].toString())

=>

const s = verifyToken(token)

当然这个验证最好是写到中间件上, token的参数在头部


const validationLogin = (req, res, next) => { 
    const {token} = req.header;
    if (verifyToken(token) ) {
       // account validate success
    } else {
        req.body = {
            ...req.body,
            stateBuffer: "e_403",
            stateMessage: "You account not exist  ."
        }
    }
    next()
}

router.post('/validation',validationLogin ,async function(req, res) {
    // xxxxx
    //logic
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值