如何在带有 AJAX 的客户端中使用 JWT
Posted
技术标签:
【中文标题】如何在带有 AJAX 的客户端中使用 JWT【英文标题】:How to use JWT in Client with AJAX 【发布时间】:2018-11-22 15:09:31 【问题描述】:我的应用程序是一个 Node.js API,在同一个应用程序内有一个客户端。
我正在尝试实现一个简单的身份验证登录,它使用由 Node.js API 生成的 JWT 令牌。
我的逻辑如下:
-
客户端:用户向
/auth/login
路由提交登录信息。
$.ajax(
url: "/auth/login",
type: "POST",
data: formData,
dataType: "json",
success: function(data, textStatus, jqXHR)
if (typeof data.redirect == "string")
window.location = data.redirect;
,
error: function(data)
if (typeof fail === "function") fail(data);
);
-
API:验证用户并在成功时生成 JWT 并发回给客户端。
router.post("/login", async (req, res) =>
var login = UID: req.body.UID, password: req.body.password ;
AU.manualLogin(login)
.then(result =>
res.header("x-auth-token", result.token).json(
status: 200,
message: "success",
data: result.data,
redirect: "/dashboard"
);
)
.catch(err => next( status: 400, message: err.message ));
);
客户端:将 JWT 保存到标头并检查 redirect
- 在这种情况下,我在成功登录后使用 window.location
指向 /dashboard
。 (这部分我不确定)
API:中间件检查受保护路由上的有效 JWT。
module.exports = function auth(req, res, next)
const token = req.headers["x-auth-token"];
if (!token)
return res.status(401).send("Access denied. No token provided.");
try
const decoded = jwt.verify(token, "jwtPrivateKey");
req.user = decoded;
next(); //pass control to next middleware
catch (ex)
res.status(400).send("Invalid token.");
;
问题:
令牌肯定是从 API -> 客户端发送的。但我不知道如何从客户端处理令牌。我认为问题可能与 window.location
重定向有关,因为此时它似乎没有将 x-auth-token
发送到 API。
我的尝试
我已经使用 Postman 从端到端测试了该解决方案,它运行良好。这可能证明问题不在于 API 方面。
我也试过这些来源:
Pass request headers in a jQuery AJAX GET call
Adding custom header in HTTP before redirect
How to add header to request in Jquery Ajax?
jwt on node - how does the client pass the token back to the server
【问题讨论】:
我建议在重定向之前,将令牌保存在本地存储或 cookie 中 @DarkLord 我从多个来源听说保存到本地存储或 cookie 不是一个好主意,但我还是很陌生。甚至可以在没有本地存储和 cookie 的情况下完成吗? 【参考方案1】:您需要某种存储来保存令牌。否则,用户必须在关闭浏览器/选项卡后再次登录。因此,将令牌保存在 本地 或 会话存储 中是很常见的。
方法 1:使用 Angular、vue.js、react 等单页应用程序 (SPA) 框架来保护您的客户端路由
方法 2:您只能从后端请求 html 和 css(视图),然后在登录过程后存储令牌。使用有效令牌,通过 ajax 请求获取(受保护的)数据。如果 ajax 请求返回状态码 401(未授权)或用户想要访问受保护的路由而不存储令牌,则重定向到登录页面。这也许是最适合你的。
方法 3:将 Node.js 与 express 等后端框架一起使用,并将身份验证信息存储在服务器端会话中
index.js
const express = require('express');
const session = require('express-session');
const app = express();
app.use(require("cookie-parser")());
app.use(session( secret: 'aslwezoweasdfasdlkfalksdfhweelaerfcv', resave: false, saveUninitialized: true));
routes/protectedRoutes.js
const express = require('express');
const router = express.Router();
router.all("/*", util.handleAuthenticate); // check auth on every request
// other routes
indexController.js(登录功能)
module.exports.login = function(req, res)
if(!req.session.name)
// check username/password --> db lookup
// if valid:
req.session.name = ...
// redirect to home or backref
// else: redirect to login
util/security.js
function isLoggedIn(req)
return !!req.session.name;
function handleAuthenticate(req, res, next)
if(isLoggedIn(req))
next();
else
// redirect to login page
【讨论】:
如何将该代码用于第 1 号(上图)的初始请求中?之后我尝试添加此内容,但没有成功。以上是关于如何在带有 AJAX 的客户端中使用 JWT的主要内容,如果未能解决你的问题,请参考以下文章
使用带有 JWT Auth/Laravel 的 Angular JS 获取新的刷新令牌后,如何恢复/重新发送请求?
如何在前端的 Javascript Ajax API 调用中隐藏我的 JWT 令牌?