讲师中心 微信公众号
AI工具推荐 视频效率加速

如何在不依赖JWT声明的情况下安全地从后端获取并验证用户角色

落雪酱_4432

落雪酱_4432

发布时间:2026-05-07 13:33:15

|

614人浏览过

|

来源于php中文网

原创

本文介绍一种安全可靠的方案:前端使用第三方oauth令牌(如google access token)完成身份认证后,后端验证其有效性并查询数据库中的用户角色,再签发一个由你完全控制的、含角色信息的自定义jwt;前端后续所有请求均携带该自定义jwt,确保角色数据不可篡改且服务端可信任。

本文介绍一种安全可靠的方案:前端使用第三方oauth令牌(如google access token)完成身份认证后,后端验证其有效性并查询数据库中的用户角色,再签发一个由你完全控制的、含角色信息的自定义jwt;前端后续所有请求均携带该自定义jwt,确保角色数据不可篡改且服务端可信任。

在基于第三方 OAuth(如 Google)的单页应用中,一个常见误区是直接将第三方 Access Token 用于前后端全部鉴权逻辑。但正如问题所述,Google 的 Access Token 不包含 roles 等业务级声明,且前端无法安全依赖后端响应中返回的角色字段——因为一旦攻击者拦截或篡改 /api/user/roles 接口的响应,就可能伪造高权限角色(如 "ROLE_ADMIN"),导致前端错误渲染管理界面,造成越权风险。

✅ 正确做法是:将第三方登录仅作为“身份断言”环节,真正的会话凭证(含角色)必须由你的后端签发、签名并全程管控。

✅ 推荐架构流程(安全闭环)

  1. 前端:用户点击“用 Google 登录” → 调用 Google OAuth 流程 → 获取 access_token(仅用于首次认证)

  2. 前端 → 后端:将该 access_token 发送到你自己的 /api/auth/login 接口(不暴露给资源服务器直接使用)

  3. 后端验证 & 角色注入:

    • 使用 Google Public Keys(JWKS)验证 JWT 签名与有效期;
    • 解析 sub(用户唯一标识)或 email 查询本地数据库(如 users 表)获取该用户的角色列表(如 ["ROLE_USER", "ROLE_EDITOR"]);
    • 使用你自己的密钥(如 HS512 或 RS256)签发一个全新 JWT,明确嵌入 authorities(Spring Security 兼容格式):
      {
        "sub": "1234567890",
        "email": "user@example.com",
        "authorities": ["ROLE_USER", "ROLE_EDITOR"],
        "exp": 1735689600,
        "iat": 1735686000
      }
  4. 后端返回该自定义 JWT 给前端(建议通过 HttpOnly + Secure Cookie,或前端安全存储于内存/sessionStorage)

  5. 后续所有 API 请求:前端在 Authorization: Bearer <your-custom-jwt> 中携带该令牌

  6. 后端资源保护:配置 Spring Security 验证你自己的 JWT(而非 Google Token):

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig {
        @Bean
        public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
            http
                .authorizeHttpRequests(auth -> auth
                    .requestMatchers("/api/public/**").permitAll()
                    .requestMatchers("/api/admin/**").hasRole("ADMIN")
                    .anyRequest().authenticated()
                )
                .oauth2ResourceServer(oauth2 -> oauth2
                    .jwt(jwt -> jwt
                        .jwtAuthenticationConverter(customJwtAuthConverter()) // 映射 authorities
                    )
                );
            return http.build();
        }
    
        @Bean
        public JwtAuthenticationConverter customJwtAuthConverter() {
            JwtGrantedAuthoritiesConverter authoritiesConverter = new JwtGrantedAuthoritiesConverter();
            authoritiesConverter.setAuthorityPrefix(""); // 不加 ROLE_ 前缀(若 payload 中已是 "ROLE_USER")
            authoritiesConverter.setAuthoritiesClaimName("authorities");
    
            JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
            converter.setJwtGrantedAuthoritiesConverter(authoritiesConverter);
            return converter;
        }
    }

⚠️ 关键注意事项

  • ❌ 切勿在前端解析或信任任意后端返回的“角色数组” —— 即使接口受保护,HTTP 响应仍可被浏览器插件或中间人篡改;
  • ✅ 所有权限判断必须在服务端完成:@PreAuthorize("hasRole('ADMIN')") 或 SecurityContext.getAuthentication().getAuthorities() 是唯一可信依据;
  • ? 自定义 JWT 必须使用强密钥签名(推荐 RS256 + 私钥签发 / 公钥校验),禁用 none 算法;
  • ? 前端角色展示(如菜单/按钮显隐)应仅作为 UX 优化,最终权限控制必须由后端 API 层强制校验;
  • ? 若需保留原始 Google Token(例如调用 Google Drive API),可将其作为额外 claim 存入自定义 JWT(如 "google_token": "ya29..."),但绝不用于你的系统鉴权。

通过该模式,你既复用了 Google 的身份认证能力,又完全掌控了授权上下文(roles)、会话生命周期与安全边界,真正实现“身份(Identity)与权限(Authority)分离”,兼顾安全性与可维护性。

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

相关专题

更多
python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2583

2023.08.11

前端和后端的区别
前端和后端的区别

前端关注的是用户界面的设计和交互,而后端则注重数据处理和逻辑控制。想了解更多前端后端的相关内容,可以阅读本专题下面的文章。

6610

2024.03.19

后端的主要工作内容介绍
后端的主要工作内容介绍

后端是应用程序的服务端部分,负责核心任务,如数据库交互、业务逻辑处理和响应客户端请求。想了解更多后端的相关内容,可以阅读本专题下面的文章。

6026

2024.03.19

js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

5106

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

1249

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

5024

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

980

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

1896

2023.09.04

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

0

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
LLVM官方文档
LLVM官方文档

共0课时 | 0人学习

Memcheck使用手册
Memcheck使用手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn