在 javascript 中实现接口请求结果的 sso(单点登录)策略,核心做法是在 fetch 发起请求前自动附加认证凭证,并在响应拦截器中处理 401 unauthorized 状态码以触发重新登录或 token 刷新。具体而言,需设置 credentials: 'include' 确保 cookie 随请求发送,同时利用 promise 链或 async/await 包装请求逻辑,当检测到未授权错误时,调用 sso 提供的重定向 url 或刷新接口,从而保持用户会话的一致性。

如何配置 Fetch 以支持基于 Cookie 的 SSO 身份验证?
要实现基于 Cookie 的 SSO,必须在每次 fetch 调用中显式指定 credentials: 'include',否则浏览器默认不会跨域发送 Cookie。服务端需配合设置 Access-Control-Allow-Credentials: true 和正确的 Access-Control-Allow-Origin。这样,当用户通过 SSO 门户登录后,服务器下发的 Session ID 或 JWT Cookie 会自动携带在所有后续 API 请求中,无需前端手动提取和注入 Token。

const ssoFetch = async (url, options = {}) => {
const defaultOptions = {
credentials: 'include',
headers: {
'Content-Type': 'application/json'
}
};
const response = await fetch(url, { ...defaultOptions, ...options });
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
};
// 使用示例
ssoFetch('/api/user/profile')
.then(data => console.log('User Data:', data))
.catch(err => console.error('SSO Auth Failed:', err));
如何在 Fetch 响应中处理 401 错误以触发 SSO 重新认证?
当 SSO Token 过期或无效时,服务端通常返回 401 状态码。前端需在 fetch 的 catch 块或响应拦截器中检测此状态,并引导用户跳转至 SSO 登录页面。为避免无限循环,应检查是否已尝试过刷新操作。若未刷新,则先尝试调用刷新接口;若刷新失败或无刷新机制,则重定向至 SSO 登录页,并在登录后通过回调参数恢复原请求路径。
立即学习“Java免费学习笔记(深入)”;

const handleAuthError = async (response, originalRequest) => {
if (response.status === 401) {
try {
// 尝试刷新 Token
await refreshAccessToken();
// 重试原请求
return fetch(originalRequest.url, originalRequest.options);
} catch (refreshError) {
// 刷新失败,重定向至 SSO 登录
const loginUrl = `${SSO_LOGIN_URL}?redirect=${encodeURIComponent(window.location.href)}`;
window.location.href = loginUrl;
throw new Error('Authentication required');
}
}
throw response;
};
// 集成到主请求流程
try {
const data = await ssoFetch('/api/secure-data');
} catch (error) {
await handleAuthError(error.response, { url: '/api/secure-data', options: {} });
}
如果 SSO 服务返回的是 JSON 格式的 401 错误而非 HTTP 状态码,该如何解析?
某些 SSO 实现可能返回 200 OK 但 Body 中包含 {"error": "unauthorized"} 的 JSON 结构。此时需先解析响应体,检查特定字段(如 status、code 或 error)来判断认证状态。若发现未授权标识,同样执行重定向或刷新逻辑。这种做法要求对响应进行二次判断,避免将业务错误误认为网络错误。
const parseSSOResponse = async (response) => {
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
const json = await response.json();
if (json.error === 'unauthorized' || json.code === 401) {
throw new Error('SSO Unauthorized via JSON body');
}
return json;
}
return response.text();
};


















