微信小程序与后端集成开发指南:登录、Token加密与全局拦截实践

一、需求分析与场景定位

在开发微信小程序时,用户认证是核心功能模块。以家属端原型为例,所有需要展示用户专属信息的页面(如个人中心、订单详情)均需前置登录校验。未登录状态下,用户点击任意受保护页面时,系统应自动跳转至登录页。登录方式采用微信账号授权,通过获取用户手机号完成身份核验,这种设计既符合微信生态规范,又能确保账号安全性。

二、开发环境搭建与配置

1. 小程序基础环境准备

开发者需完成三步基础操作:

  • 测试号申请:通过微信公众平台注册小程序测试账号,获取AppID及开发密钥
  • 开发工具安装:从官方渠道下载最新版微信开发者工具,支持Windows/macOS双平台
  • 项目导入:扫码登录后,通过”导入项目”功能加载代码包,需注意选择正确的项目目录

2. 开发者工具深度配置

网络请求配置

  • 在”详情”->”本地设置”中勾选”不校验合法域名”,解决测试环境HTTPS问题
  • 修改request合法域名列表,添加后端服务基础地址

安全策略调整

  • 关闭”ES6转ES5”选项提升编译效率(生产环境需重新开启)
  • 配置uploadFile域名白名单,支持文件上传功能

性能优化设置

  • 启用”增强编译”模式加速热更新
  • 调整”调试基础库”版本与生产环境保持一致

三、后端服务集成方案

1. 安全框架适配策略

传统Spring Security框架需进行针对性改造:

  1. @Configuration
  2. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  3. @Override
  4. protected void configure(HttpSecurity http) throws Exception {
  5. // 放行小程序所有请求路径
  6. http.authorizeRequests()
  7. .antMatchers("/api/miniapp/**").permitAll()
  8. .anyRequest().authenticated();
  9. }
  10. }

通过路径匹配规则,区分小程序请求与传统Web请求,实现差异化认证策略。

2. 核心Controller实现

以房型查询接口为例:

  1. @RestController
  2. @RequestMapping("/api/miniapp")
  3. public class RoomTypeController {
  4. @Autowired
  5. private RoomTypeService roomTypeService;
  6. @GetMapping("/roomTypes")
  7. public ResponseEntity<List<RoomTypeDTO>> getAllRoomTypes() {
  8. List<RoomTypeDTO> types = roomTypeService.findAll();
  9. return ResponseEntity.ok(types);
  10. }
  11. }

关键实现要点:

  • 统一接口前缀/api/miniapp便于拦截器识别
  • 返回标准化DTO对象而非实体类
  • 使用ResponseEntity封装HTTP响应

四、微信登录认证全流程

1. 认证协议解析

基于微信开放平台文档,完整流程包含:

  1. 前端调用wx.login()获取临时code
  2. 携带code请求后端/api/miniapp/auth接口
  3. 后端通过code向微信服务器换取openid及session_key
  4. 生成自定义登录态token返回前端

2. Token生成与验证

采用JWT标准实现:

  1. public class TokenUtil {
  2. private static final String SECRET_KEY = "your-256-bit-secret";
  3. private static final long EXPIRATION_TIME = 864_000_000; // 10天
  4. public static String generateToken(String openId) {
  5. return Jwts.builder()
  6. .setSubject(openId)
  7. .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
  8. .signWith(SignatureAlgorithm.HS512, SECRET_KEY)
  9. .compact();
  10. }
  11. public static String getOpenIdFromToken(String token) {
  12. return Jwts.parser()
  13. .setSigningKey(SECRET_KEY)
  14. .parseClaimsJws(token)
  15. .getBody()
  16. .getSubject();
  17. }
  18. }

安全增强措施:

  • 使用强加密算法(HS512)
  • 定期轮换密钥
  • 结合设备指纹防重放攻击

五、全局拦截器实现

1. 拦截器核心逻辑

  1. @Component
  2. public class MiniAppAuthInterceptor implements HandlerInterceptor {
  3. @Override
  4. public boolean preHandle(HttpServletRequest request,
  5. HttpServletResponse response,
  6. Object handler) throws Exception {
  7. // 排除登录接口及静态资源
  8. String uri = request.getRequestURI();
  9. if (uri.startsWith("/api/miniapp/auth") || uri.contains(".")) {
  10. return true;
  11. }
  12. // 获取Authorization头
  13. String token = request.getHeader("Authorization");
  14. if (StringUtils.isEmpty(token)) {
  15. response.sendError(HttpStatus.UNAUTHORIZED.value(), "Token缺失");
  16. return false;
  17. }
  18. try {
  19. String openId = TokenUtil.getOpenIdFromToken(token);
  20. // 可将openId存入RequestAttribute供后续使用
  21. request.setAttribute("currentOpenId", openId);
  22. return true;
  23. } catch (Exception e) {
  24. response.sendError(HttpStatus.UNAUTHORIZED.value(), "Token无效");
  25. return false;
  26. }
  27. }
  28. }

2. 拦截器注册配置

  1. @Configuration
  2. public class WebConfig implements WebMvcConfigurer {
  3. @Autowired
  4. private MiniAppAuthInterceptor authInterceptor;
  5. @Override
  6. public void addInterceptors(InterceptorRegistry registry) {
  7. registry.addInterceptor(authInterceptor)
  8. .addPathPatterns("/api/miniapp/**")
  9. .excludePathPatterns("/api/miniapp/auth/**");
  10. }
  11. }

六、测试验证方案

1. 单元测试

  1. @SpringBootTest
  2. @AutoConfigureMockMvc
  3. public class AuthControllerTest {
  4. @Autowired
  5. private MockMvc mockMvc;
  6. @Test
  7. public void testLoginSuccess() throws Exception {
  8. String mockCode = "test_code_001";
  9. mockMvc.perform(post("/api/miniapp/auth")
  10. .param("code", mockCode))
  11. .andExpect(status().isOk())
  12. .andExpect(jsonPath("$.token").exists());
  13. }
  14. }

2. 集成测试

  1. 使用Postman模拟前端请求
  2. 验证不同场景下的响应状态码
  3. 检查Token生成与解析的正确性
  4. 测试拦截器对未授权请求的拦截效果

七、生产环境部署建议

  1. 密钥管理:将SECRET_KEY存储在配置中心或密钥管理服务中
  2. 性能优化:对JWT解析操作添加本地缓存
  3. 监控告警:集成日志服务跟踪认证失败事件
  4. 灾备方案:准备备用密钥应对密钥泄露场景

通过上述完整方案,开发者可系统掌握微信小程序与后端服务的集成技术,构建出符合安全规范且具备良好扩展性的认证体系。实际开发中需根据具体业务需求调整安全策略,建议定期进行安全审计确保系统健壮性。