RestTemplate发送GET请求如何传ID且不直接暴露在URI中
实现方案
你不需要手动拼接URI字符串,也不需要把studentId暴露在消费端的对外接口路径中,按以下步骤实现即可:
- 从服务端登录上下文获取当前学生ID
因为要避免越权,绝对不能让前端传入studentId参数,直接从服务端维护的登录态里取当前请求对应的学生ID即可:- 如果用Spring Security做权限控制,直接在Controller方法中注入
Authentication/Principal对象,从认证信息中解析出当前登录学生的ID - 如果是自研的登录逻辑,从你存储登录信息的位置(Session、ThreadLocal、解析后的JWT载荷)中获取对应的学生ID
- 如果用Spring Security做权限控制,直接在Controller方法中注入
- 通过RestTemplate的占位符机制自动替换路径参数
你代码里写的{id}就是RestTemplate原生支持的URI路径占位符,不需要手动拼接字符串,直接把获取到的实际ID作为参数传入,RestTemplate会自动完成占位符替换和参数转义,完全避免手动拼接带来的路径注入、特殊字符转义问题。
代码示例
以Spring Security场景为例,改造后的消费端接口代码如下:
@GetMapping("/my-applications") public ResponseEntity<List> getApplications(Authentication authentication) { // 从登录认证信息中获取当前学生ID,根据自身项目的用户对象结构调整取值逻辑 Long currentStudentId = ((CustomUserDetails) authentication.getPrincipal()).getStudentId(); // 直接传入ID变量,RestTemplate自动替换URI中的{id}占位符 return restTemplate.getForEntity( "http://localhost:8081/students/{id}/applications", List.class, currentStudentId ); }
如果需要传递多个路径/查询参数,还可以用Map方式传参,key和占位符名称一一对应即可:
Map<String, Object> uriParams = new HashMap<>(); uriParams.put("id", currentStudentId); uriParams.put("page", 1); uriParams.put("size", 10); ResponseEntity<List> response = restTemplate.getForEntity( "http://localhost:8081/students/{id}/applications?pageNum={page}&pageSize={size}", List.class, uriParams );
注意事项
- 禁止从前端传递的请求参数、请求头中获取studentId,必须从服务端留存的登录态中取值,否则会存在越权访问漏洞,用户可以篡改参数查看其他学生的申请信息
- 建议把服务提供方的基础地址(比如示例里的
http://localhost:8081)抽到配置文件中统一维护,不要硬编码在业务代码里 - RestTemplate的占位符替换机制会自动对参数做URL编码,比手动字符串拼接URI更安全可靠。
内容的提问来源于stack exchange,提问作者Piotr Wcisło
相关产品推荐
相关产品推荐

