如何让客户端使用返回的JWT令牌访问REST服务的受保护端点?
如何让客户端使用JWT访问受保护的REST端点
嘿,刚接触Web开发能搞定用户名密码验证并返回JWT,这已经迈出了很棒的一步!别担心,下面我会把客户端怎么用令牌、服务端怎么验证的流程说清楚,都是很基础的操作,跟着来就行~
一、客户端:存储并在请求中携带JWT
1. 先把JWT存起来
当你的服务返回JWT令牌后,客户端需要先把它存好,常用的存储方式有三种,你可以根据需求选:
- localStorage:令牌会持久保存在浏览器里,即使用户关闭浏览器再打开还在,适合需要长期保持登录状态的场景。
- sessionStorage:令牌只在当前会话有效,关闭浏览器就消失,安全性稍高一点,适合临时登录的场景。
- Cookie:可以设置
HttpOnly和Secure属性,防止XSS攻击,而且浏览器会自动在请求中携带(如果配置了SameSite),适合对安全性要求高的场景。
举个用localStorage存储的简单例子(JavaScript):
// 假设服务返回的响应里有token字段 fetch('/login', { method: 'POST', body: JSON.stringify({ username: 'xxx', password: 'xxx' }), headers: { 'Content-Type': 'application/json' } }) .then(res => res.json()) .then(data => { // 存储JWT localStorage.setItem('userToken', data.token); });
2. 请求受保护端点时带上JWT
客户端每次请求需要权限的接口时,要把JWT放在HTTP请求的Authorization请求头里,格式固定为 Bearer <你的JWT令牌>。
用fetch的例子:
const token = localStorage.getItem('userToken'); fetch('/protected-endpoint', { method: 'GET', headers: { 'Authorization': `Bearer ${token}`, // 关键:这里带上令牌 'Content-Type': 'application/json' } }) .then(res => { if (res.status === 401) { // 令牌无效或过期,跳转到登录页 window.location.href = '/login'; } return res.json(); }) .then(data => { // 处理返回的受保护数据 console.log(data); });
如果用Axios的话,可以设置全局拦截器,不用每次都手动加头:
import axios from 'axios'; const token = localStorage.getItem('userToken'); axios.defaults.headers.common['Authorization'] = `Bearer ${token}`; // 之后请求受保护接口就自动带令牌了 axios.get('/protected-endpoint') .then(res => console.log(res.data)) .catch(err => { if (err.response.status === 401) { // 处理未授权情况 } });
二、服务端:验证请求中的JWT
客户端把令牌发过来后,你的服务端需要验证这个令牌的有效性,通常是通过中间件来做(不同后端语言框架有对应的JWT库)。
以Node.js + Express为例,用express-jwt库来实现验证:
const express = require('express'); const jwt = require('express-jwt'); const app = express(); // 配置JWT验证中间件,这里的secret要和你生成JWT时用的密钥一致 const authenticateToken = jwt({ secret: '你的JWT密钥', // 注意:生产环境不要硬编码,用环境变量 algorithms: ['HS256'] // 加密算法,要和生成时一致 }); // 受保护的端点,加上authenticateToken中间件 app.get('/protected-endpoint', authenticateToken, (req, res) => { // 验证通过后,req.user里会包含JWT解析出的用户信息 res.json({ message: '这是受保护的数据', user: req.user }); }); // 处理验证失败的情况(比如令牌无效、过期) app.use((err, req, res, next) => { if (err.name === 'UnauthorizedError') { res.status(401).json({ message: '令牌无效或未提供' }); } else { next(err); } });
其他后端语言比如Java(Spring Boot)可以用spring-security-jwt,Python(Django)可以用djangorestframework-simplejwt,核心逻辑都是:
- 从Authorization头提取Bearer令牌
- 验证令牌的签名是否正确
- 检查令牌是否过期
- 验证通过后放行请求,否则返回401错误
三、一些重要的注意事项
- 一定要用HTTPS:JWT是明文传输的(虽然签名是加密的),用HTTPS可以防止令牌在传输过程中被窃听。
- 不要在JWT里存敏感信息:JWT的payload部分是Base64编码的,很容易解码,所以别放密码、手机号这种敏感内容。
- 处理令牌过期:可以设置合理的过期时间,客户端收到401错误时,引导用户重新登录获取新令牌,或者实现刷新令牌机制(进阶操作,之后可以慢慢研究)。
内容的提问来源于stack exchange,提问作者Reeser1728
相关产品推荐
相关产品推荐

