打开 “懒猫微服客户端” 下载应用

it-tools

在线工具集合

92 次下载
2 次点赞
0 条评论
0 次催更
92

安装次数

2

点赞

0

应用评论

0

催更次数

桌面端

应用描述

为开发人员提供的方便的在线工具集合,具有出色的用户体验。

相关攻略

给IT tools加Oauth的代码示例

IT tools是Vue的纯前端项目。其实可以接入SSO。 https://appstore.lazycat.cloud/#/shop/detail/iamxiaoe.lzcapp.ittools 修改路由器守卫:涵盖了动态路由生成、组件懒加载、基于 token 的登录鉴权和未登录用户的自动重定向。所有受保护的页面都会在跳转前通过 API 校验 token 的有效性,确保只有合法用户才能访问。同时,我们为工具类页面统一指定了专属布局 ```jsx import { createRouter, createWebHistory } from 'vue-router'; import { layouts } from './layouts/index'; import HomePage from './pages/Home.page.vue'; import NotFound from './pages/404.page.vue'; import { tools } from './tools'; import { config } from './config'; import { routes as demoRoutes } from './ui/demo/demo.routes'; import AuthCallback from './pages/AuthCallback.page.vue'; import Login from './pages/Login.page.vue'; import axios, { AxiosResponse } from 'axios'; const toolsRoutes = tools.map(({ path, name, component, ...config }) => ({ path, name, component, meta: { requiresAuth: true, isTool: true, layout: layouts.toolLayout, name, ...config }, })); const toolsRedirectRoutes = tools .filter(({ redirectFrom }) => redirectFrom && redirectFrom.length > 0) .flatMap( ({ path, redirectFrom }) => redirectFrom?.map(redirectSource => ({ path: redirectSource, redirect: path })) ?? [], ); const router = createRouter({ history: createWebHistory(config.app.baseUrl), routes: [ { path: '/', name: 'home', component: HomePage, meta: { requiresAuth: true } }, { path: '/about', name: 'about', component: () => import('./pages/About.vue'), meta: { requiresAuth: true } }, { path: '/login', name: 'Login', component: Login }, { path: '/auth/callback', name: 'AuthCallback', component: AuthCallback, }, ...toolsRoutes, ...toolsRedirectRoutes, ...(config.app.env === 'development' ? demoRoutes : []), { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound }, ], }); router.beforeEach((to, from, next) => { const token = localStorage.getItem('access_token'); if (to.matched.some(record => record.meta.requiresAuth)) { if (!token) { // 如果没有token,重定向到登录页面 next({ path: '/login', query: { redirect: to.fullPath } }); } else { // 如果有token,检查token的有效性 axios.post(`${import.meta.env.VITE_APP_API_URL}:8000/session`, {},{ headers: { 'Authorization': `Bearer ${token}` } }) .then(response => { // 根据响应判断token是否有效 if (response.data.error_code === 200 && response.data.message === 'Valid session') { // Token有效,放行 next(); } else { // Token无效,清除localStorage中的token并重定向到登录页面 localStorage.removeItem('access_token'); next({ path: '/login', query: { redirect: to.fullPath } }); } }) .catch(error => { // 请求出错,清除localStorage中的token并重定向到登录页面 localStorage.removeItem('access_token'); next({ path: '/login', query: { redirect: to.fullPath } }); }); } } else { // 如果路由不需要认证,直接放行 next(); } }); export default router; ``` 在实现单点登录(SSO)时,我们设计了一个专门的跳转页组件。当用户访问该页面时,前端会自动拼接好后端的登录地址(带上回调参数 redirect_uri),并立即将浏览器重定向到该地址,发起 SSO 登录流程。这个组件无需展示 UI,只负责发起跳转,逻辑简单但至关重要,是整个认证链路中的入口节点。 ```jsx <template> <!-- <div> <h1>SSO...</h1> </div> --> </template> <script> import axios from 'axios'; export default { mounted() { this.redirectToSSO(); }, methods: { redirectToSSO() { console.log(`API: ${import.meta.env.VITE_APP_API_URL}`) const ssoLoginUrl = `${import.meta.env.VITE_APP_API_URL||"na"}:8000/login?redirect_uri=${import.meta.env.VITE_APP_API_URL||"na"}/auth/callback`; window.location.href = ssoLoginUrl; } } } </script> ``` 前端回调 当用户完成 SSO 授权并跳转回前端时,我们通过一个专门的回调页面组件捕获 URL 中的授权码 code。组件加载时自动执行鉴权逻辑: 从 code 中构造后端请求,调用 /callback 获取 access_token 成功后将 token 写入 localStorage,并跳转回首页 若失败或缺少授权码,则重定向回登录页重新发起认证 这一过程实现了 OAuth2 标准中的「授权码交换令牌」流程,是前后端 SSO 登录闭环的关键一环。 ```jsx <template> <div> <h1>SSO...</h1> </div> </template> <script> import axios from 'axios'; export default { created() { this.handleAuthentication(); }, methods: { handleAuthentication() { console.log("handleAuthentication hook") const code = new URLSearchParams(this.$route.query).get('code'); if (code) { // console.log(1, code) axios.post(`${import.meta.env.VITE_APP_API_URL||"na"}:8000/callback?code=${code}`,) .then(response => { // console.log("response",response) localStorage.setItem('access_token', response.data.access_token); this.$router.push('/'); }) .catch(() => { this.$router.push('/login'); }); } else { this.$router.push('/login'); } } } } </script> ``` 后端跳转 为实现前后端分离的单点登录(SSO)功能,我们基于 FastAPI 构建了轻量级认证服务。后端会根据环境自动从 AWS Secrets Manager 加载 SSO 配置信息,避免敏感信息硬编码。整个登录流程遵循 OAuth2 协议,包括: 登录接口 /login 会构造并重定向用户到授权服务器 用户授权后由 /callback 接收授权码并换取访问令牌 前端持有的 token 可通过 /session 接口进行二次校验,确保权限合法 整套认证链路简洁、模块化,适用于支持 GitHub、Auth0 等主流 SSO 平台的企业级项目。 ```python from fastapi import FastAPI, Depends, HTTPException, Request from fastapi.responses import RedirectResponse, JSONResponse import requests import os from fastapi import FastAPI, Request, HTTPException from fastapi.responses import JSONResponse from fastapi.middleware.cors import CORSMiddleware from dotenv import load_dotenv import boto3 from botocore.exceptions import ClientError import json from fastapi import FastAPI, Request, Header app = FastAPI() load_dotenv() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) secrets_client = boto3.client('secretsmanager') def get_secret(environment): secret_name = f"{environment}/xxxx" region_name = "cn-northwest-1" # Create a Secrets Manager client session = boto3.session.Session() client = session.client( service_name='secretsmanager', region_name=region_name ) try: get_secret_value_response = client.get_secret_value( SecretId=secret_name ) except ClientError as e: raise e secret = get_secret_value_response['SecretString'] secret = json.loads(secret) return secret environment = os.getenv('ENV', 'dev') secrets = get_secret(environment) CLIENT_ID = secrets.get('CLIENT_ID', 'na') CLIENT_SECRET = secrets.get('CLIENT_SECRET', 'na') AUTHORIZATION_BASE_URL = secrets.get('AUTHORIZATION_BASE_URL', 'na') TOKEN_URL = secrets.get('TOKEN_URL', 'na') REDIRECT_URI = secrets.get('REDIRECT_URI', 'na') SESSION_URL = secrets.get('SESSION_URL', 'na') @app.get("/") def read_root(): return { "ENVIRONMENT": environment, "AUTHORIZATION_BASE_URL": AUTHORIZATION_BASE_URL } @app.get("/login") def login(): authorization_url = ( f"{AUTHORIZATION_BASE_URL}?response_type=code&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}" ) return RedirectResponse(authorization_url) @app.post("/callback") def callback(request: Request): code = request.query_params.get('code') print("code",code) if not code: raise HTTPException(status_code=400, detail="Missing authorization code") token_data = { 'grant_type': 'authorization_code', 'code': code, 'redirect_uri': REDIRECT_URI, 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET, } try: token_response = requests.post(TOKEN_URL, data=token_data) token_response.raise_for_status() token_json = token_response.json() access_token = token_json.get('access_token') except requests.RequestException as e: raise HTTPException(status_code=400, detail=str(e)) return JSONResponse(content={"access_token": access_token}) @app.post("/session") def auth_session(Authorization: str = Header(default=None)): headers = {'Authorization': f'{Authorization}'} try: token_response = requests.get(SESSION_URL, headers=headers) token_response.raise_for_status() token_json = token_response.json() msg = token_json.get("message") if msg == "Valid session": return token_json except requests.RequestException as e: raise HTTPException(status_code=400, detail=str(e)) if __name__ == '__main__': import uvicorn uvicorn.run(app, host='0.0.0.0', port=8000) ```

懒猫评分/评论

0.0

0 条评论

此 App 尚未收到足够的评分或评论,无法显示评论列表。

应用信息

最新版本

0.0.1

更新日期

6/4/2025

预估安装占用

21.78 MB

不支持平台

--

提供者

我是小E

兼容性

可在此设备上使用

"为开发人员提供的方便的在线工具集合,具有出色的用户体验。"