使用 JWT 和 auth 中间件从'/user/login'重定向到'/user/me'
Posted
技术标签:
【中文标题】使用 JWT 和 auth 中间件从\'/user/login\'重定向到\'/user/me\'【英文标题】:Redirect from '/user/login' to '/user/me' in express with JWT and auth middleware使用 JWT 和 auth 中间件从'/user/login'重定向到'/user/me' 【发布时间】:2021-11-07 13:42:35 【问题描述】:我试图在用户登录后将他们重定向到他们的个人资料。我想做的是当他们登录时,我们将通过凭据找到用户,然后从他们那里生成和验证令牌(注意 I为测试目的创建了一个用户 const)。两者都完成后,我将设置一个标头 Authorization,使用令牌,并将其传递给 /user/me 路由。这是我的路线:
(登录 POST 路由,“/user/login”):
router.post('/user/login', async (req, res) =>
try
const user = await User.findByCredentials(req.body.email, req.body.password)
const token = await user.generateAuthToken()
res.header('Authorization', 'Bearer '+token)
res.status(302).redirect('/user/me')
catch (err)
res.status(400).send(err)
)
(个人资料路径:“/user/me”):
router.get('/user/me', auth, async (req, res) =>
res.send(req.user)
)
(我在上一个方法中传递的“auth”中间件):
const auth = async (req, res, next) =>
try
const token = req.header('Authorization').replace('Bearer ', '')
const decoded = jwt.verify(token, SECRET_TOKEN)
const user = await User.findOne( _id: decoded._id, 'tokens.token': token)
console.log(token)
if(!user)
throw new Error("User not found")
req.token = token
req.user = user
next()
catch(err)
res.status(503).send(error: 'Please authenticate')
但是每当我尝试这个时,它都会从 auth 方法中给出我的 503 错误:
"error": "Please authenticate"
正如我在开发工具中看到的那样,授权标头正确传递。
如需更多信息,generateAuthToken 和 findByCredentials 方法如下所示:
userSchema.methods.generateAuthToken = async function()
const user = this
const token = jwt.sign( _id: user._id.toString() , SECRET_TOKEN)
user.tokens = user.tokens.concat(token)
await user.save()
return token
userSchema.statics.findByCredentials = async (email, password) =>
const user = await User.findOne(email)
if(!user)
throw new Error(message: "Unable to log in.")
const isValid = await bcrypt.compare(password, user.password)
if(!isValid)
throw new Error(message: "Unable to log in.")
return user
如需更多信息,我的用户模型如下所示:
const userSchema = mongoose.Schema(
email:
type: String,
required: true,
unique: true,
trim: true,
validate(value)
if(!validator.isEmail(value))
throw new Error("Not a valid email")
,
password:
type: String,
required: true,
validate(value)
if(value === "password")
throw new Error("Enter a strong password.")
if(value.length < 8)
throw new Error("Enter minimum 8 letters for a password.")
,
tokens: [
token:
type: String,
required: true
]
)
【问题讨论】:
“但是每当我尝试这个时,它都会从 auth 方法中给出我的 503 错误:” - 你无条件地发送 503。您的代码中还有其他可能失败的地方,所有这些都会导致 503。当您输出错误本身时,您会看到什么? @Tomalak 我的错误,它说“无法读取未定义的属性'替换'”。这意味着“授权”标头未定义。如何将它从 /user/login 传递给 /user/me? @Tomalak 我使用 cookie 解决了它。它现在工作正常。非常感谢!!! 【参考方案1】:我已经通过使用 cookie 解决了这个问题。这可能是一种临时解决方法,但我会找到资源以使其更安全!
在登录路径中:
res.cookie('Authorization', `Bearer $token`,
maxAge: 60000,
)
在身份验证中间件中:
const token = req.cookies['Authorization'].replace('Bearer ', '')
【讨论】:
您应该为每个请求设置授权标头。使用 cookie 只能回避问题,因为浏览器会为您管理 cookie 标头。使用 cookie 并不是解决此问题的最佳方法。探究如何在客户端一致地设置 Authorization 标头的问题。 好吧,重写您的服务器代码,以便根据情况发送正确的响应代码。 503 并不意味着“请验证”,它意味着“服务不可用”(即“服务器关闭”等)。 “未授权”是 401。像 "Cannot read property 'replace' of undefined" 这样的编程错误应该会导致 500。 非常感谢您的建议@Tomalak。我目前正在调查您提出的所有建议。以上是关于使用 JWT 和 auth 中间件从'/user/login'重定向到'/user/me'的主要内容,如果未能解决你的问题,请参考以下文章