【问题标题】:GET information from user in database从数据库中的用户获取信息
【发布时间】:2023-04-06 09:22:01
【问题描述】:

我正在制作全栈应用程序并从教程和视频中学习。我在获取有关登录系统的用户信息的 GET 请求时遇到问题。我使用 Postman 来检查请求。当我使用 /login 添加用户时,邮递员会查看用户的访问令牌代码。我复制他的代码并将其粘贴到 Postman 标头中的授权密钥中,当我将 localhost 中的 URL 更改为 /infor 以获取有关此用户的信息并发送它时。但它说我“身份验证无效”。我找不到错误。我认为问题出在 getUser 函数中的 controllers/userCtrl.js 中。你能帮帮我吗?

我放代码:

server.js

require('dotenv').config()
const express = require('express')
const mongoose = require('mongoose')
const cors = require('cors')
const fileUpload = require('express-fileupload')
const cookieParser = require('cookie-parser')


const app = express()
app.use(express.json())
app.use(cookieParser())
app.use(cors())

// Use temp files instead of memory for managing the upload process.
app.use(fileUpload({
    useTempFiles: true
}))

// Routes

app.use('/user', require('./routes/userRouter'))

// Connect to Mongodb
const URL = process.env.MONGO_URL
mongoose.connect(URL,{
    useCreateIndex: true,
    useFindAndModify: false,
    useNewUrlParser: true,
    useUnifiedTopology: true
}, err =>{
    if(err) throw err;
    console.log('Connected to MongoDB')
})



const PORT = process.env.PORT || 5000
app.listen(PORT, () => {
    console.log('Server is running on port', PORT)
})

.env

MONGO_URL = ***********
ACCESS_TOKEN_SECRET = ***********
REFRESH_TOKEN_SECRET = *************

routes/userRouter.js

require('dotenv').config()
const express = require('express')
const mongoose = require('mongoose')
const cors = require('cors')
const fileUpload = require('express-fileupload')
const cookieParser = require('cookie-parser')


const app = express()
app.use(express.json())
app.use(cookieParser())
app.use(cors())

// Use temp files instead of memory for managing the upload process.
app.use(fileUpload({
    useTempFiles: true
}))

// Routes

app.use('/user', require('./routes/userRouter'))

// Connect to Mongodb
const URL = process.env.MONGO_URL
mongoose.connect(URL,{
    useCreateIndex: true,
    useFindAndModify: false,
    useNewUrlParser: true,
    useUnifiedTopology: true
}, err =>{
    if(err) throw err;
    console.log('Connected to MongoDB')
})



const PORT = process.env.PORT || 5000
app.listen(PORT, () => {
    console.log('Server is running on port', PORT)
})

models/userModel.js

const mongoose = require('mongoose')

const userSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true,
        trim: true
    },
    email: {
        type: String,
        required: true,
        unique: true
    },
    password: {
        type: String,
        required: true,
       
    },
    role: {
        type: Number,
       default: 0
    },
    cart: {
        type: Array,
        default: []
    }
}, {
    timestamps: true
})

module.exports = mongoose.model('Users', userSchema)

中间件/auth.js

const jwt = require('jsonwebtoken')

const auth = (req, res, next) => {
    try{
        const token = req.header("Authorization")
        if(!token) return res.status(400).json({ msg: "Invalid Authentication" })

        jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
            if(!err) return res.status(400).json({msg: "Invalid Authentication" })

            req.user = user
            next()
        })
    } catch (err) {
        return res.status(500).json({msg: err.message})
    }
}

module.exports = auth

控制器/userCtrl.js

const Users = require('../models/userModel')
const bcrypt = require('bcrypt')
const jwt = require('jsonwebtoken')

const userCtrl = {
    register: async (req, res) => { // async before a function means one simple thing: a function always returns a promise. 
       try{
           const { name, email, password } = req.body

           const user = await Users.findOne({ email }) // wait until the promise resolves
           if(user) return res.status(400).json({msg: "The email already exists"})

           if(password.length < 6)
           return res.status(400).json({msg: "Password is at least 6 characteres long."})

           //Password encryption
           const passwordHash = await bcrypt.hash(password, 10)
           const newUser = new Users({
               name, email, password: passwordHash
           })

           // save mongodb
           await newUser.save()

           //then create jsonwebtoken to authentication
           const accesstoken = createAccessToken({ id: newUser._id })
           const refreshtoken = createRefreshToken({ id: newUser._id })

           res.cookie('refreshtoken', refreshtoken, {
            httpOnly: true,
            path: '/user/refresh_token'
          });

           res.json({accesstoken})

       } catch(err){
           return res.status(500).json({msg: err.message})
       }
    },
    login: async (req, res) => {
        try{
            const {email, password} = req.body;

            const user = await Users.findOne({email})
            if(!user) return res.status(400).json({msg: "User does not exist."})

            const isMatch = await bcrypt.compare(password, user.password)
            if(!isMatch) return res.status(400).json({msg: "Incorrect password"})
           
            // if login success, create access token and refresh token
            const accesstoken = createAccessToken({ id: user._id })
            const refreshtoken = createRefreshToken({ id: user._id })
 
            res.cookie('refreshtoken', refreshtoken, {
             httpOnly: true,
             path: '/user/refresh_token'
           });

           res.json({accesstoken})

        } catch(err){
            return res.status(500).json({msg: err.message})
        }
    },
    logout: async (req, res)=> {
        try{
            res.clearCookie('refreshtoken', {path: '/user/refresh_token'})
            return res.json({msg: "Logged out"})
        }catch(err){
            return res.status(500).json({msg: err.message})

        }
    },
    refreshToken: (req, res) => {
        try{
            const rftoken = req.cookies.refreshtoken
            if(!rftoken) return res.status(400).json({msg: "Please login or Register"})
           jwt.verify(rftoken, process.env.REFRESH_TOKEN_SECRET, (err, user) => {
               if(err) return res.status(400).json({msg: "Please login or Register"})
               const accesstoken = createAccessToken({id: user.id})
               res.json({ accesstoken })

           })

        }catch (err) {
            return res.status(500).json({msg: err.message})
        }
        
    },
    getUser: async (req, res) => {  // problem
        try{
            const user = await (await Users.findById(req.user.id)).isSelected('-password')
            if(!user) return res.status(400).json({ msg: "Useer does not exist."})

            res.json(req.user)
        }catch (err) {
            return res.status(500).json({msg: err.message})
        }
    }
} 
    const createAccessToken = (user) => {
        return jwt.sign(user, process.env.ACCESS_TOKEN_SECRET, { expiresIn: '1d' })
    }

    const createRefreshToken = (user) => {
        return jwt.sign(user, process.env.REFRESH_TOKEN_SECRET, { expiresIn: '7d' })
    }
 

module.exports = userCtrl

【问题讨论】:

  • 我还没有前端代码。只有后端。

标签: javascript node.js mongodb express


【解决方案1】:

用于获取令牌的中间件(身份验证功能)

    const { authorization } = req.headers
    

    if (!authorization) {
        console.log('[No Authorization Code]'); 
        return res.status(401).send({ message: 'Unauthorized' });
    }
        

    if (!authorization.startsWith('Bearer')) {
        console.log('[Authorization need to start with Bearer]')
        return res.status(401).send({ message: 'Unauthorized' });
    }

    const split = authorization.split('Bearer ')
    if (split.length !== 2) {
        console.log('[Invalid Authorization Param')
        return res.status(401).send({ message: 'Unauthorized' });
    }

     const token = split[1]  //this is your token to use with jwt.verify

在postman中发送token时,选择Bearer Token

当你开始创建你的前端时,代码应该等同于下面的获取请求

fetch('/api/path', { method: 'GET', headers: { "Authorization": `Bearer ${token}`}}).(res => res.json())

可以将方法更改为您想要的方法(例如获取或发布),并且令牌将是 jwt 令牌

【讨论】:

  • 我在中间件 auth.js 中添加了这段代码并使用 Bearer Token 发送请求,邮递员说我“未经授权”
  • 你的 console.log 说了什么?打印的错误应该非常明显地表明你做错了什么
  • 我添加了截图
  • 你说你使用令牌,但截图使用用户名密码。如果您要问其他问题,请打开其他问题线程。
猜你喜欢
  • 2014-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-31
  • 2019-10-22
相关资源
最近更新 更多