Smart-SSO实战避坑指南Vue项目单点登录集成全解析最近在Vue项目中集成Smart-SSO时我经历了从403错误到最终成功的完整历程。这篇文章将分享那些官方文档没有详细说明的关键配置点以及如何避免常见的坑。1. 环境准备与基础配置在开始集成之前有几个关键点需要特别注意服务端版本匹配确保使用的Smart-SSO服务端版本支持H5模式最低要求v2.3.0前端框架选择虽然官方示例使用jQuery但在Vue项目中我们可以更优雅地实现开发环境配置本地测试需要配置hosts文件添加服务端域名解析后端基础配置中最容易遗漏的是h5-enabled开关# application.yml关键配置 smart: sso: server-url: http://your-sso-server.com client-id: your_client_id client-secret: your_client_secret exclude-urls: /auth/* h5-enabled: true # 必须显式设置为true注意很多开发者遇到的第一个问题就是忘记开启h5-enabled导致前端始终无法获取token2. 跨域问题深度解决前后端分离架构下跨域是必须解决的问题。Smart-SSO的跨域配置有几个特殊要求CorsFilter的Order值必须小于ClientContainer的Order值默认为10Header特殊处理需要允许X-Requested-With头预检请求处理OPTIONS请求需要特殊处理正确的跨域过滤器实现Order(5) // 必须小于10 WebFilter Configuration public class CorsFilter implements Filter { Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response (HttpServletResponse) res; response.setHeader(Access-Control-Allow-Origin, *); response.setHeader(Access-Control-Allow-Methods, *); response.setHeader(Access-Control-Max-Age, 3600); response.setHeader(Access-Control-Allow-Headers, Content-Type, TOKEN_NAME_PREFIXCLIENT_ID, X-Requested-With); if (OPTIONS.equalsIgnoreCase(((HttpServletRequest) req).getMethod())) { response.setStatus(HttpServletResponse.SC_OK); return; } chain.doFilter(req, res); } }3. Vue前端集成最佳实践在Vue项目中我们需要实现以下几个核心功能登录跳转逻辑处理认证中心的重定向Token管理安全存储和刷新token请求拦截自动携带token和刷新逻辑推荐使用axios拦截器实现// src/utils/auth.js const TOKEN_KEY smart-sso-token; const CLIENT_ID your_client_id; export function setupAxiosInterceptors(axiosInstance) { // 请求拦截器 axiosInstance.interceptors.request.use(config { const token localStorage.getItem(${TOKEN_KEY}-${CLIENT_ID}); if (token) { config.headers[${TOKEN_KEY}-${CLIENT_ID}] token; config.headers[X-Requested-With] XMLHttpRequest; } return config; }); // 响应拦截器 axiosInstance.interceptors.response.use( response { if (response.data.code 15) { // token过期 return refreshToken().then(() { return axiosInstance(response.config); }); } return response; }, error { if (error.response.status 403) { redirectToLogin(); } return Promise.reject(error); } ); } async function refreshToken() { const refreshToken localStorage.getItem(${TOKEN_KEY}-refresh-${CLIENT_ID}); const { data } await axios.get(/auth/refresh-token, { params: { refreshToken } }); localStorage.setItem(${TOKEN_KEY}-${CLIENT_ID}, data.accessToken); localStorage.setItem(${TOKEN_KEY}-refresh-${CLIENT_ID}, data.refreshToken); }4. Nginx部署配置要点生产环境部署时Nginx配置有几个关键点代理设置确保正确代理前端和后端请求静态资源缓存合理配置缓存策略跨域支持虽然前端已经处理但Nginx也可以提供额外支持典型配置示例server { listen 80; server_name your-frontend.com; location / { root /path/to/dist; try_files $uri $uri/ /index.html; expires 1h; } location /api/ { proxy_pass http://backend:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /auth/ { proxy_pass http://backend:8080; # 特殊处理OPTIONS请求 if ($request_method OPTIONS) { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods GET, POST, OPTIONS; add_header Access-Control-Allow-Headers Content-Type,Authorization,X-Requested-With; return 204; } } }5. 常见问题排查指南在实际集成过程中我遇到了以下典型问题及解决方案问题现象可能原因解决方案403 Forbidden1. h5-enabled未开启2. exclude-urls配置错误3. 跨域配置问题1. 检查h5-enabled2. 确认/auth/*在exclude-urls中3. 检查CorsFilter Order值Token刷新失败1. refreshToken过期2. 客户端密钥不匹配3. 服务端时间不同步1. 重新登录获取新token2. 检查client-secret配置3. 同步服务器时间登录后无限重定向1. redirect_uri不匹配2. 本地存储未正确保存token1. 检查回跳地址编码2. 确认localStorage操作正常6. 安全增强建议在完成基础集成后可以考虑以下安全增强措施HTTPS强制所有通信必须使用HTTPSToken安全存储考虑使用更安全的存储方式定期刷新实现静默自动刷新机制权限验证前端路由守卫集成权限检查Vue路由守卫示例// src/router.js router.beforeEach((to, from, next) { if (to.meta.requiresAuth !isAuthenticated()) { next({ path: /login, query: { redirect: to.fullPath } }); } else { next(); } }); function isAuthenticated() { const token localStorage.getItem(smart-sso-token-your_client_id); if (!token) return false; // 可以添加额外的token有效性检查 return true; }在项目实际上线后我们发现最常出现的问题是token刷新时机的把握。经过多次调试最终采用了提前刷新策略在token过期前5分钟就自动发起刷新请求这样用户体验最为流畅。