平台网站建设的公司/能让手机流畅到爆的软件
大家好,我是梅巴哥er
,本篇介绍的是在注册/ 登录 / 用户信息更新 中关于cookie携带userid数据的获取和处理。具体是哪些知识点呢?
- 怎么把userid加入到cookie中进行携带
- 怎么获取cookie中的userid数据
- 当用户登录失效时,怎么删除浏览器cookie中的userid信息,并提示用户重新登录
- 当用户更新个人信息时,怎么响应新的数据(一部分老数据要和新修改的数据进行合并)
- 对于这篇博客在express保存请求数据时,Cannot read property ‘_id‘ of undefined
https://blog.csdn.net/tuzi007a/article/details/108401966
中存在的问题进行修复和解释。
对应的知识点:
1,在cookie中携带userid数据
res.cookie('userid', user._id, { maxAge: 1000*60*60*24 })
2,POST请求下,获取cookie中的userid数据
const userid = req.cookies.userid
3,删除浏览器cookie中的userid信息
res.clearCookie('userid')
4,响应新的数据(一部分老数据要和新修改的数据进行合并)
// 先获取到用户新提交的信息
const user = req.body
// 再把需要合并的信息,从老数据中拿出来
const { _id, username, type } = oldUser
// 数据合并
const data = Object.assign({ _id, username, type }, user)
// 把合并后的数据响应出来
res.send({ code: 0, data })
5,从后台获取随机生成的id,并用Object()进行数据类型转换的问题(对那篇博客的内容进行修复和解释)
- 首先,这种方法确实解决了当初获取不到userid的问题
- 其次,这种方法有个弊端
- 就是,在后续要获取这个userid时,获取到的userid和cookie中携带的登录userid,是不一样的
- 这就产生一个新的问题,
- 就是当用户更新信息时,因为登录时的userid和更新信息时获取的userid不一致,导致后台判断用户未登录的错误信息
- 于是,新的解决办法,就是不再引入
const ObjectId = require('mongodb').ObjectId
,也不再做类型转换const id = ObjectId(req.body.id)
,cookie里也不再用后台随机生成的id做userid,res.cookie('userid', id, { maxAge: 1000*60*60*24 })
- 而是把引入和转换都注释掉,在cookie里把
id
换成user._id
。 这样才能获取到一致的userid数据。 - 从而完成用户信息更新。
关于 登录/ 注册 / 更新信息 的代码,全部在这里了,请参考:
var express = require('express');
var router = express.Router();
// UserModel在models.js文件里已经暴露出来了,要拿到这里用,所以要先引入
const UserModel = require('../db/models').UserModel
// console.log(UserModel)
// 引入密码加密的包
const md5 = require('blueimp-md5')// 如果没有这里的引入,还有后面id的定义,会报错:
// TypeError: Cannot read property '_id' of undefined
// 解决办法就是,先引入,再定义id,最后把user._id换成id即可。// const ObjectId = require('mongodb').ObjectIdconst filter = { password: 0 } // 指定过滤属性/* GET home page. */
router.get('/', function(req, res, next) {res.render('index', { title: 'Express' });
});// 测试: 定义一个路由,实现用户注册
/*
a) path为 /register
b) 请求方式为post
c) 接收username和password参数
d) admin是已注册用户
e) 注册成功,返回: { code:0, data: { _id: 'abc', username: 'xxx', password: '123' } }
f) 注册失败,返回: {code: 1, msg: '此用户已存在'}
*/
// router.post('/register', (req, res) => {
// /* 1,获取请求参数
// 2,处理
// 3,返回响应数据 */
// const {username, password} = req.body
// if (username === 'admin') {
// res.send({code: 1, msg: '此用户已存在'})
// } else {
// res.send({ code: 0, data: { id: 'abc', username, password } })
// }
// })// 注册的路由
router.post('/register', function(req, res) {// 读取请求参数数据// 此时的id才是后台传过来的id,才能与数据库对照// const id = ObjectId(req.body.id)const { username, password, type } = req.body// console.log(id)// const _id = id// console.log(typeof(_id))// console.log(req.body)// console.log(req.body.username)// console.log({ username })// console.log(username)// console.log({ username, password, type })// 处理// 1,判断 看用户是否存在UserModel.findOne( { username }, function(err, user) {// console.log(user)// console.log(username)// console.log(user.username)if (user) { // user已存在,user值为true// 返回提示错误信息res.send({ code: 1, msg: '此用户已存在' })// console.log(user)} else { // user不存在// console.log(user)// 保存注册的用户数据new UserModel({ username, password: md5(password), type }).save(function(err, user) {// console.log(user._id)// 在发送响应数据之前,生成一个cookie(userid: user._id),// 并交给浏览器保存// 参数maxAge单位是毫秒,表示cookie存活的时间。// 1000*60*60*24 是一天res.cookie('userid', user._id, { maxAge: 1000*60*60*24 })// 响应数据中,不要携带密码const data = { _id: user._id, username, type } res.send({ code: 0, data })// console.log(err, user)// res.send(user)})}})// 返回响应数据
})// const userModel = new UserModel({
// username: 'ming',
// password: 233,
// type: 'dashen'
// })
// userModel.save((err, user) => {
// console.log(err, 'user is', user)
// })// 登录的路由
router.post('/login', (req, res) => {// 获取数据const { username, password } = req.body// const id = ObjectId(req.body.id)// 处理数据// 根据username和password去查询数据库users,但是这个password是加密的// 如果有,返回登录成功信息。// 如果没有,就返回提示登录失败的信息// filter是个过滤器UserModel.findOne({ username, password: md5(password) }, filter, (err, user) => {// console.log(user)if (user) { // 登录成功// 生成一个cookie,并交给浏览器保存res.cookie('userid', user._id, { maxAge: 1000*60*60*24 })// 返回登录信息,包含userres.send({ code: 0, data: user})} else { // 登录失败res.send({ code: 1, msg: '用户名或密码不正确!'})}})
})// 更新用户信息的路由
router.post('/update', function(req, res) {// console.log('cookies: ', req.cookies)// 获取cookie携带的useridconst userid = req.cookies.userid // console.log('userid: ', userid)// 获取提交的用户数据// 对用户userid进行判断, 如果不存在,就说明用户还没登录if (!userid) {res.send({code: 1, msg: '请先登录'})} else {// 用户已登录,根据userid更新对应的user信息const user = req.body // console.log('user: ', user) // 这里面是没有_id的// user 里面是用户提交的header头像等信息UserModel.findByIdAndUpdate({ _id: userid }, user, function(err, oldUser) {// console.log('oldUser', oldUser)// oldUser里面有_id, username, password, type等信息// 如果登录失效,则oldUser就不存在了。// 这时候需要提醒浏览器删除cookie携带的userid// 所以 这里需要对oldUser做个判断if (!oldUser) { // 不存在res.clearCookie('userid')res.send({code: 1, msg: '请先登录'})} else { // 存在const { _id, username, type } = oldUser// 做用户信息合并,把user里的header头像等新数据,和登录数据进行合并const data = Object.assign({ _id, username, type }, user)res.send({ code: 0, data })}})}})module.exports = router;