当数据库中存储的密码以 Node.js 的形式进行哈希运算时,如何使用原始密码登录?
原文:https://www . geesforgeks . org/如何使用原始密码登录-当密码存储在数据库中-被散列-节点中-表单-js/
出于安全考虑,数据库中存储的密码始终是(哈希+salt) 形式。当用户在任何网站上注册时,都会以原始形式给出密码。但是将原始密码直接存储在数据库中并不是一个好的做法。使用一些服务器端逻辑,我们首先转换(散列+盐)形式的原始密码,然后将其存储在数据库中。这就产生了一个新的挑战,如何比较用户在登录时给出的原始密码,并根据密码的正确与否授予用户访问权限。
以如下形式存储在数据库中的密码:
Hashed(password, salt)
例:
22 cbca 6aa 74d 354971 ca 355 a 7641649 b 222 a 7858 f 972 f 50d 68 ea 65 B3 c 5067 a 008 ea 4 CDC 897446190 a 36d 7815215 ab 4659d 2333 a 94 b 15d 43 c 758 f 4d 08 ab 60.7 FB 85 e 87188 DD 649
设置使用原始密码登录逻辑的步骤:
- 借助用户登录时给出的唯一用户名或电子邮件搜索数据库。
- 找到唯一的记录,如果没有找到,返回“用户不存在”。
- 在“”处拆分加密密码。'分别查找哈希密码和盐。
- 使用 salt 对用户提供的原始密码进行哈希处理,以使用 node . js“scrypt”方法登录。
- 将获得的散列值与通过拆分数据库密码获得的散列值进行比较。
- 如果两个散列值相等,则在用户中签名,并授予访问权限。
- 如果两者哈希不相等,则拒绝访问,并显示消息“密码无效”。
注意:为了说明逻辑,这里我们取一个本地或者定制的数据库。同样的逻辑也可以用 MongoDB、MySql 等常规数据库来实现。
示例:此示例说明了当数据库中存储的密码为(哈希+盐)形式时,如何使用原始密码登录。
java 描述语言
const util = require('util')
const crypto = require('crypto')
const express = require('express')
const bodyParser = require('body-parser')
const repo = require('./repository')
const app = express()
const scrypt = util.promisify(crypto.scrypt)
const port = process.env.PORT || 3000
// The body-parser middleware to parse form data
app.use(bodyParser.urlencoded({ extended: true }))
// Get route to display HTML form to sign in
app.get('/signin', (req, res) => {
res.send(`
<div>
<form method='POST'>
<div>
<div>
<label id='email'>Username</label>
</div>
<input type='text' name='email'
placeholder='Email' for='email'>
</div>
<div>
<div>
<label id='password'>Password</label>
</div>
<input type='password' name='password'
placeholder='Password' for='password'>
</div>
<div>
<button>Sign In</button>
</div>
</form>
</div>
`)
})
// Post route to handle form submission logic and
app.post('/signin', async (req, res) => {
// Email and password submitted by the user
const { email, password } = req.body
// Find record by given unique username or email
const user = await repo.findBy({ email })
console.log(user)
// If record not found by given username
if (!user) {
return res.send('User Not Exist')
}
// Hashed and salt of database password
const [hashed, salt] = user.password.split('.')
// Hashing raw password submitted by the user
// to sign in third argument is the key length
// that must be same when hashing the password
// to store it into the database when user sign up
const hashedBuff = await scrypt(password, salt, 64)
console.log(hashed)
console.log(hashedBuff.toString('hex'))
// Compare saved hashed of database and
// obtained hashed
const isValid = hashed === hashedBuff.toString('hex')
if (isValid) {
return res.send('Sign In successfully')
}
return res.send('Invalid Password')
})
// Server setup
app.listen(port, () => {
console.log(`Server start on port ${port}`)
})
Filename: repository.js 这个文件包含所有与创建本地数据库以及如何与之交互相关的逻辑。
java 描述语言
// Importing node.js file system, util,
// crypto module
const fs = require('fs')
const util = require('util')
const crypto = require('crypto')
// Convert callback based scrypt method
// to promise based method
const scrypt = util.promisify(crypto.scrypt)
class Repository {
constructor(filename) {
// The filename where datas are
// going to store
if (!filename) {
throw new Error(
'Filename is required to create a datastore!')
}
this.filename = filename
try {
fs.accessSync(this.filename)
} catch (err) {
// If file not exist it is created
// with empty array
fs.writeFileSync(this.filename, '[]')
}
}
async findBy(attrs) {
// Read all file contents of the datastore
const jsonRecords = await
fs.promises.readFile(this.filename, {
encoding: 'utf8'
})
// Parsing json records in javascript
// object type records
const records = JSON.parse(jsonRecords)
// Iterating through each record
for (let record of records) {
let found = true
// Iterate through each given
// propert for each record
for (let key in attrs) {
// If any given property not matches
// with record record is discarded
if (record[key] !== attrs[key]) {
found = false
}
}
// If 'found' remains true after iterating
// through each given property that
// means record found
if (found) {
return record
}
}
}
}
// The 'datastore.json' file created at runtime
// if it not exist, here we try to fetch
// information from database using some properties
// that means database(datastore.json) already
// exist and there are also records in it.
module.exports = new Repository('datastore.json')
使用以下命令运行 index.js 文件:
node index.js
文件名:package.json
package.json 文件
数据库:
数据库ˌ资料库
输出:
在这里,我们使用用户名和密码的不同组合分别提交三个表单,并分别获得如图所示的输出。
使用无效的用户名登录
使用有效的用户名登录,但密码无效
使用有效的用户名和密码登录
重定向页面:T2】
使用无效用户名登录时的响应
使用有效用户名但无效密码登录时的响应
使用有效的用户名和密码登录时的响应
版权属于:月萌API www.moonapi.com,转载请注明出处