.NET 8 + Angular电商用户模块认证授权安全实践问询
电商用户模块生产级认证授权最佳实践(.NET 8 + Angular)
一、用户模块开发核心思路
先按分层架构拆分:.NET端用Clean Architecture,分Domain(定义用户角色、权限实体)、Application(写用户注册、登录、权限校验的业务逻辑)、Infrastructure(对接数据库、Redis做会话存储)、API层(对外提供接口);Angular端拆成Core(封装通用服务)、Shared(公共组件)、Features(用户登录、个人中心等业务模块)。
角色权限用RBAC+细粒度策略:先定义基础角色(普通用户、商家、管理员),再给每个角色绑定具体权限(比如普通用户仅能下单/查看订单,商家可管理自有商品)。用户类型扩展用抽象基类User,派生CustomerUser、MerchantUser,后续加新类型直接继承就行。
二、XSS、CSRF攻击防范
XSS防护
- .NET后端:启用内置防XSS中间件,API返回内容自动转义HTML;用
FluentValidation或DataAnnotations对用户输入(昵称、评价等)做过滤,直接拦截带<script>这类危险标签的内容;存储时可选转义后存储,或者读取渲染时再转义。 - Angular前端:默认
{{}}插值绑定会自动转义HTML,别随便用[innerHTML],真要用的话必须用DomSanitizer处理可信内容;配置Content Security Policy(CSP),不管是在angular.json里加还是后端返回响应头,限制脚本只能从可信来源加载。
CSRF防护
- .NET后端:Cookie认证场景下,ASP.NET Core自动生成Anti-Forgery令牌,接口上加
[ValidateAntiForgeryToken];JWT场景下,要在请求头带自定义CSRF令牌(比如X-XSRF-TOKEN),后端验证它和Cookie里的令牌值一致。 - Angular前端:HttpClient默认会自动读取Cookie里的
XSRF-TOKEN,并在POST/PUT/DELETE请求头里带X-XSRF-TOKEN,只需要确保请求配置了withCredentials: true;所有写操作绝对不能用GET,必须走POST/PUT/DELETE并校验CSRF。
三、认证方案:Cookie vs JWT
方案选型
- Cookie认证:适合同域/子域部署的场景,ASP.NET Core内置支持,自动管会话过期、刷新,前端不用额外处理存储;缺点是跨域配置麻烦,单Cookie最大4KB限制。
- JWT认证:适合前后端分离跨域的场景,无状态,后端不用存会话;缺点是没法主动吊销令牌(除非搞黑名单),前端得自己处理存储和刷新逻辑。
JWT存储:LocalStorage vs Cookie
生产级首选Cookie(带HttpOnly+Secure+SameSite属性):
HttpOnly:禁止JS读取Cookie,直接避免XSS窃取JWT;Secure:只在HTTPS请求里传输,防止明文泄露;SameSite=Strict/Lax:限制Cookie跨域发送,降低CSRF风险。
LocalStorage别用,XSS攻击一拿一个准,窃取后直接就能用JWT冒充用户请求。
Cookie跨域与大小问题解决
- 跨域:.NET API端配置CORS,允许前端域名,设置
AllowCredentials = true;Angular端HttpClient请求时加withCredentials: true。 - 大小限制:精简JWT的Claims,只存必要信息(用户ID、角色、过期时间),别把用户昵称、头像这些冗余数据塞进去;要是Claims真的多,把额外数据存在Redis里,JWT只存一个索引键,后端拿键去Redis查详情。
四、令牌吊销与刷新令牌处理
令牌吊销
- Cookie认证:后端直接清除Cookie就行,或者把会话ID存Redis标记为无效,每次请求先查Redis验证会话状态。
- JWT认证:因为JWT是无状态的,主动吊销得搞令牌黑名单:用Redis存已吊销JWT的
jti(令牌ID)和过期时间,后端每次验证JWT先查黑名单;建议把JWT有效期设短点(15-30分钟),这样黑名单存储压力小,过期自动清。
刷新令牌
用短期访问令牌+长期刷新令牌的组合:
- .NET后端:生成JWT时同时生成刷新令牌,把刷新令牌的哈希值存在Redis(关联用户ID);前端用刷新令牌换访问令牌时,后端先验证刷新令牌有效性,有效就发新的访问令牌和刷新令牌(旧的直接失效)。
- Angular前端:用HTTP拦截器监听401错误,自动调用刷新令牌接口,拿到新令牌后重试原请求;要处理并发请求的情况,避免多个请求同时触发刷新,搞个锁机制就行。
五、授权最佳实践
- .NET后端用
[Authorize(Roles = "Admin")]做角色授权,或者用[Authorize(Policy = "ManageProducts")]做细粒度策略授权,比如ManageProducts策略要求用户是商家或管理员; - Angular前端根据用户角色/权限动态显隐组件(比如管理员才能看后台菜单),但后端必须做最终校验,不能只靠前端控制,不然随便改前端代码就能越权。
内容的提问来源于stack exchange,提问作者student
相关产品推荐
相关产品推荐

