## 安装 ```bash npm install unified-login-sdk --save # 或 yarn add unified-login-sdk ``` ## 快速开始 ### 基本使用 ```typescript import unifiedLoginSDK from 'unified-login-sdk'; // 初始化配置 unifiedLoginSDK.init({ clientId: 'your-client-id', authorizationEndpoint: 'https://auth.example.com/authorize', tokenEndpoint: 'https://auth.example.com/token', userInfoEndpoint: 'https://auth.example.com/userinfo', redirectUri: 'https://your-app.example.com/callback', storageType: 'localStorage', autoRefreshToken: true, tenantId: 'your-tenant-id' // 可选,会自动添加到请求头中的tenant-id字段 }); // 登录 document.getElementById('login-btn')?.addEventListener('click', () => { unifiedLoginSDK.login(); }); // 处理回调 if (unifiedLoginSDK.isAuthenticated()) { // 已登录,获取用户信息 unifiedLoginSDK.getUserInfo().then(userInfo => { console.log('User info:', userInfo); }); } else if (unifiedLoginSDK.isCallback()) { // 处理授权回调 unifiedLoginSDK.handleCallback().then(userInfo => { console.log('Login successful:', userInfo); // 跳转到首页 window.location.href = '/'; }).catch(error => { console.error('Login failed:', error); }); } // 退出登录 document.getElementById('logout-btn')?.addEventListener('click', () => { unifiedLoginSDK.logout().then(() => { console.log('Logout successful'); window.location.href = '/login'; }); }); ``` ## 核心功能 ### 初始化配置 ```typescript unifiedLoginSDK.init({ clientId: 'your-client-id', clientSecret: 'your-client-secret', // 可选,某些场景下需要 authorizationEndpoint: 'https://auth.example.com/authorize', tokenEndpoint: 'https://auth.example.com/token', userInfoEndpoint: 'https://auth.example.com/userinfo', redirectUri: 'https://your-app.example.com/callback', storageType: 'localStorage', // 可选,默认localStorage autoRefreshToken: true, // 可选,默认true permissionsEndpoint: 'https://auth.example.com/permissions' // 可选,权限端点 }); ``` ### 登录流程 1. 调用`login()`方法跳转到授权页面 2. 用户在授权页面登录并授权 3. 授权服务器重定向到配置的`redirectUri` 4. 调用`handleCallback()`方法处理授权回调,获取用户信息 ### Token管理 ```typescript // 获取访问令牌 const accessToken = unifiedLoginSDK.getAccessToken(); // 刷新令牌 unifiedLoginSDK.refreshToken().then(() => { console.log('Token refreshed'); }).catch(error => { console.error('Failed to refresh token:', error); }); // 检查是否已认证 const isAuthenticated = unifiedLoginSDK.isAuthenticated(); ``` ### 用户信息管理 ```typescript // 获取用户信息 unifiedLoginSDK.getUserInfo().then(userInfo => { console.log('User info:', userInfo); }); // 获取用户权限列表 unifiedLoginSDK.getPermissions().then(permissions => { console.log('Permissions:', permissions); }); ``` ### 事件监听 ```typescript // 监听登录事件 unifiedLoginSDK.on('login', () => { console.log('User logged in'); }); // 监听退出事件 unifiedLoginSDK.on('logout', () => { console.log('User logged out'); }); // 监听Token过期事件 unifiedLoginSDK.on('tokenExpired', () => { console.log('Token expired'); // 可以在这里执行自定义逻辑,如跳转到登录页 unifiedLoginSDK.login(); }); // 移除事件监听 const handleLogin = () => console.log('User logged in'); unifiedLoginSDK.on('login', handleLogin); unifiedLoginSDK.off('login', handleLogin); ``` ## 框架集成 ### Vue 2 ```javascript // main.js import Vue from 'vue'; import { createVuePlugin } from 'unified-login-sdk'; import App from './App.vue'; import router from './router'; // 创建Vue插件 const vuePlugin = createVuePlugin('localStorage'); // 安装插件 Vue.use(vuePlugin, { config: { clientId: 'your-client-id', authorizationEndpoint: 'https://auth.example.com/authorize', tokenEndpoint: 'https://auth.example.com/token', userInfoEndpoint: 'https://auth.example.com/userinfo', redirectUri: 'https://your-app.example.com/callback' } }); new Vue({ router, render: h => h(App) }).$mount('#app'); ``` 在组件中使用: ```vue Welcome, {{ userInfo?.name }} Logout Login ``` ### Vue 3 ```javascript // main.js import { createApp } from 'vue'; import { createVuePlugin } from 'unified-login-sdk'; import App from './App.vue'; import router from './router'; // 创建Vue插件 const vuePlugin = createVuePlugin('localStorage'); const app = createApp(App); // 安装插件 app.use(vuePlugin, { config: { clientId: 'your-client-id', authorizationEndpoint: 'https://auth.example.com/authorize', tokenEndpoint: 'https://auth.example.com/token', userInfoEndpoint: 'https://auth.example.com/userinfo', redirectUri: 'https://your-app.example.com/callback' } }); app.use(router); app.mount('#app'); ``` 在组件中使用(Composition API): ```vue Welcome, {{ userInfo?.name }} Logout Login ``` ``` ## API参考 ### 初始化 ```typescript init(config: SDKConfig): void ``` 初始化SDK配置。 ### 登录 ```typescript login(redirectUri?: string): void ``` 触发登录流程,可选参数`redirectUri`可覆盖初始化时的配置。 ### 退出登录 ```typescript logout(): Promise ``` 退出登录,清除本地存储的Token和用户信息。 ### 处理授权回调 ```typescript handleCallback(): Promise ``` 处理授权回调,获取用户信息。 ### 获取用户信息 ```typescript getUserInfo(): Promise ``` 获取用户基本信息。 ### 获取用户权限列表 ```typescript getPermissions(): Promise ``` 获取用户权限列表。 ### 检查是否已认证 ```typescript isAuthenticated(): boolean ``` 检查用户是否已认证。 ### 获取访问令牌 ```typescript getAccessToken(): string | null ``` 获取访问令牌。 ### 刷新访问令牌 ```typescript refreshToken(): Promise ``` 刷新访问令牌。 ### 事件监听 ```typescript on(event: 'login' | 'logout' | 'tokenExpired', callback: Function): void ``` 监听登录、退出或Token过期事件。 ### 移除事件监听 ```typescript off(event: 'login' | 'logout' | 'tokenExpired', callback: Function): void ``` 移除事件监听。 ## 配置选项 | 选项 | 类型 | 必填 | 默认值 | 描述 | |------|------|------|--------|------| | clientId | string | 是 | - | 客户端ID | | clientSecret | string | 否 | - | 客户端密钥,某些场景下需要 | | authorizationEndpoint | string | 是 | - | 授权端点URL | | tokenEndpoint | string | 是 | - | Token端点URL | | userInfoEndpoint | string | 是 | - | 用户信息端点URL | | redirectUri | string | 是 | - | 重定向URL | | storageType | 'localStorage' 'sessionStorage' 'cookie' | 否 | 'localStorage' | Token存储类型 | | autoRefreshToken | boolean | 否 | true | 是否自动刷新Token | | permissionsEndpoint | string | 否 | - | 权限端点URL | | stateLength | number | 否 | 32 | 状态参数长度 | | tenantId | string | 否 | - | 租户ID,会自动添加到请求头中的tenant-id字段 | ## 事件处理 | 事件 | 描述 | |------|------| | login | 用户登录成功时触发 | | logout | 用户退出登录时触发 | | tokenExpired | Token过期时触发 | ## 路由守卫 ### Vue路由守卫 ```javascript // router/index.js import VueRouter from 'vue-router'; import { Auth } from 'unified-login-sdk'; import { Storage } from 'unified-login-sdk'; import { RouterGuard } from 'unified-login-sdk'; const storage = new Storage('localStorage'); const auth = new Auth(storage); const routerGuard = new RouterGuard(auth); const router = new VueRouter({ routes: [ { path: '/', name: 'Home', component: Home }, { path: '/protected', name: 'Protected', component: Protected, meta: { auth: { requiresAuth: true, requiredPermissions: ['read:protected'] } } } ] }); // 添加路由守卫 router.beforeEach(routerGuard.createVueGuard()); export default router; ``` ## 错误处理 ### 网络错误处理 ```typescript try { await unifiedLoginSDK.getUserInfo(); } catch (error) { if (error.name === 'HttpError') { // 处理HTTP错误 console.error('HTTP Error:', error.status, error.message); if (error.status === 401) { // 未授权,跳转到登录页 unifiedLoginSDK.login(); } else if (error.status === 403) { // 权限不足 window.location.href = '/403'; } } else { // 处理其他错误 console.error('Error:', error.message); } } ``` ### Token失效处理 ```typescript // 监听Token过期事件 unifiedLoginSDK.on('tokenExpired', () => { console.log('Token expired'); // 跳转到登录页 unifiedLoginSDK.login(); }); ``` ## 最佳实践 1. **配置安全存储**:根据项目需求选择合适的存储类型,敏感信息建议使用cookie并设置secure和httpOnly标志。 2. **合理设置Token过期时间**:根据项目安全性要求设置合适的Token过期时间,建议access token过期时间较短,refresh token过期时间较长。 3. **使用路由守卫保护敏感路由**:对需要登录或特定权限的路由使用路由守卫进行保护。 4. **处理网络错误**:在调用SDK方法时,使用try-catch捕获并处理可能的错误。 5. **监听Token过期事件**:及时处理Token过期情况,避免用户体验下降。 6. **不要直接暴露clientSecret**:clientSecret应该只在后端使用,前端SDK尽量避免使用clientSecret。 7. **使用HTTPS**:确保所有与授权服务器的通信都使用HTTPS,避免Token被窃取。 8. **定期清理存储**:在用户退出登录时,确保清理所有相关存储的信息。 ## 浏览器兼容性 - Chrome (推荐) - Firefox - Safari - Edge ## 许可证 MIT License