安全问题
任何客户端传过来的数据都是不能直接信任的
HTTP请求,任何客户端传过来的数据都是不能直接信任的,不能信任请求头与请求体里的任何内容。客户端传给服务端的数据只是信息收集,数据需要经过有效性验证、权限验证等后才能使用,并且这些数据只能认为是用户操作的意图,不能直接代表数据当前的状态。
如果接口面向内部服务,由服务调用方传入用户 ID 没什么不合理,但是这样的接口不能直接开放给客户端或 H5 使用。如果你的接口直面用户(比如给客户端或 H5 页面调用),那么一定需要用户先登录才能使用。登录后用户标识保存在服务端,接口需要从服务端(比如 Session 中)获取(sessionId)。
Spring Validation
@Validated public class TrustClientParameterController { @PostMapping("/better") @ResponseBody public String better( @RequestParam("countryId") @Min(value = 1, message = "非法参数") @Max(value = 3, message = "非法参数") int countryId) { return allCountries.get(countryId).getName(); } } |
@PostMapping("/orderRight") public void right(@RequestBody Order order) { //根据ID重新查询商品 Item item = Db.getItem(order.getItemId()); //客户端传入的和服务端查询到的商品单价不匹配的时候,给予友好提示 if (!order.getItemPrice().equals(item.getItemPrice())) { throw new RuntimeException("您选购的商品价格有变化,请重新下单"); } //重新设置商品单价 order.setItemPrice(item.getItemPrice()); //重新计算商品总价 BigDecimal totalPrice = item.getItemPrice().multiply(BigDecimal.valueOf(order.getQuantity())); //客户端传入的和服务端查询到的商品总价不匹配的时候,给予友好提示 if (order.getItemTotalPrice().compareTo(totalPrice)!=0) { throw new RuntimeException("您选购的商品总价有变化,请重新下单"); } //重新设置商品总价 order.setItemTotalPrice(totalPrice); createOrder(order); } |
Spring Wed技巧
自定义注解 @LoginRequired
@GetMapping("right") public String right(@LoginRequired Long userId) { return "当前用户Id:" + userId; } |
注解:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER |