JWT 令牌验证以解码和保护 MEAN 应用程序中的路由
Posted
技术标签:
【中文标题】JWT 令牌验证以解码和保护 MEAN 应用程序中的路由【英文标题】:JWT Token Verification to decode and Protect Routes in MEAN App 【发布时间】:2021-12-06 23:08:05 【问题描述】:我正在尝试使用 JWT 对用户进行身份验证。我在登录时分配了一个令牌。
if (client)
// Check if Client does exist, then compare password provided by Client
if (!req.body.password)
res.json( success: false, message: "No password provided" ); // Password was not provided
else
var validPassword = client.password === req.body.password; // Check if password matches password provided by Client
if (!validPassword)
res.json( success: false, message: password: message: "Incorrect Password" ); // Password does not match password in database
else
if (!client.active)
res.json( success: false, message: active: message: "Account is not activated" ); // Account is not activated
else
var token = jwt.sign(
username: client.username, email: client.email ,
secret,
expiresIn: "24h"
); // Logged in: Give Client token
res.json(
success: true,
message: "Client authenticated!",
token: token
); // Return token in JSON object to controller
登录后,我正在检查请求中的令牌使我成为用户。
router.use(function(req, res, next)
var token = req.body.token || req.body.query || req.headers['x-access-token']; // Check for token in body, URL, or headers
// Check if token is valid and not expired
if (token)
// Function to verify token
jwt.verify(token, secret, (err, decoded) =>
if (err)
res.json( success: false, message: 'Token invalid' ); // Token has expired or is invalid
else
req.decoded = decoded; // Assign to req. variable to be able to use it in next() route ('/me' route)
next(); // Required to leave middleware
);
else
res.json( success: false, message: 'No token provided' ); // Return error if no token was provided in the request
);
我将所有受保护的路由放在检查令牌之后。用户可以访问个人资料页面/me
router.post('/me', function(req, res)
res.send(req.decoded); // Return the token acquired from middleware
);
如何在 Angular 11 中检查 req.body 中的令牌?我曾尝试使用 localStorage 设置令牌,但似乎我做得不对。
localStorage.setItem('userToken', response.token);
通过在正文中传递令牌访问 /me 路由时,它似乎在 Postman 中工作正常。它显示是否找到令牌。如果找到则显示结果
“电子邮件”:“example@gmail.com”, "iat": 1634704834, “exp”:1634791234
【问题讨论】:
【参考方案1】:一切似乎都很好。我认为,您只需要在前端实现一个拦截器。它将从本地存储中选择身份验证令牌,并将其附加到所有请求中。
示例代码
import HttpRequest, HttpHandler, HttpEvent, HttpInterceptor from '@angular/common/http';
import Observable from 'rxjs';
import AuthService from './service/auth.module';
@Injectable()
export class AuthInterceptor implements HttpInterceptor
constructor(private authService: AuthService)
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
let loggedInUser = this.authService.currentUserValue;
token = JSON.parse(localStorage.getItem(user.token));
if (token)
request = request.clone(
setHeaders:
Authorization: `Bearer $token`
);
return next.handle(request);
是的,在正文参数中发送身份验证令牌并不是一个好习惯。安全的方法是始终对此类敏感信息使用标题。更多详情可查看here
【讨论】:
感谢 Pankaj 的帮助。我按照建议使用了 HttpInterceptor 。它似乎工作正常。 如果你认为我的回答有帮助或者它是正确的答案,也许你应该投票/接受这个答案。【参考方案2】:我用过HttpInterceptor
import Injectable, Injector from '@angular/core';
import HttpInterceptor from '@angular/common/http';
import AuthService from './auth.service';
@Injectable()
export class TokenInterceptorService implements HttpInterceptor
constructor(private injector: Injector)
intercept(req, next)
let auth = this.injector.get(AuthService);
let tokenizedReq = req.clone(
setHeaders:
Authorization: `Bearer $auth.getToken()`,
,
);
return next.handle(tokenizedReq);
它反映了标头中的令牌,但当我尝试从任何路由上的后端获取数据时提示“令牌无效”。我正在使用console.log(response);
进行检查,而它在 nodemon 中工作正常,同时在标头中传递令牌。
请帮忙。
【讨论】:
您的陈述不清楚。请编辑或添加更多详细信息,您所面临的问题究竟是什么。 抱歉,我是 Angular 新手。使用 HttpInterceptor 后,我可以在请求标头中获取令牌,但是当我访问路由时,它会显示 Token Invalid 并且没有从后端呈现数据。不知何故,登录时提供的令牌和请求标头令牌不匹配。在请求标头和 localStorage 令牌中手动检查令牌时,两者是相同的。甚至邮递员在传递令牌后也在渲染数据,但它没有在前端渲染。 我很确定,这要归功于Bearer $token
。从令牌中删除 Bearer,它将起作用。所以在你的 HttpInterceptor 中,使用这个授权:$auth.getToken()
,(从中删除 Bearer)
感谢 Pankaj 的帮助。
如果它有帮助并且你觉得它是一个正确的答案,也许你应该接受这个答案或支持它。它将激励我和其他用户帮助他人。以上是关于JWT 令牌验证以解码和保护 MEAN 应用程序中的路由的主要内容,如果未能解决你的问题,请参考以下文章