diff --git a/OpenAuth.Identity/wwwroot/css/site.css b/OpenAuth.Identity/wwwroot/css/site.css index 292cf8ca..861353ea 100644 --- a/OpenAuth.Identity/wwwroot/css/site.css +++ b/OpenAuth.Identity/wwwroot/css/site.css @@ -1,71 +1,73 @@ /* ============================================ - OpenAuth.Net 认证中心 - 现代化设计系统 + OpenAuth.Net 认证中心 - 设计系统 ============================================ */ /* --- 设计令牌 (Design Tokens) --- */ :root { - /* 主色调 */ - --color-primary: #6366f1; - --color-primary-hover: #4f46e5; - --color-primary-light: #eef2ff; - --color-secondary: #8b5cf6; - - /* 背景渐变 */ - --bg-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - --bg-gradient-subtle: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); - + /* 主色调 - 标准蓝 */ + --color-primary: #1677ff; + --color-primary-hover: #4096ff; + --color-primary-active: #0958d9; + --color-primary-light: #e6f4ff; + --color-primary-border: #91caff; + + /* 页面背景 */ + --bg-page: #f0f2f5; + /* 中性色 */ - --color-text: #1e293b; - --color-text-secondary: #64748b; - --color-text-muted: #94a3b8; - --color-border: #e2e8f0; + --color-text: rgba(0, 0, 0, 0.85); + --color-text-secondary: rgba(0, 0, 0, 0.65); + --color-text-muted: rgba(0, 0, 0, 0.45); + --color-border: #d9d9d9; + --color-border-split: #f0f0f0; --color-bg-white: #ffffff; - --color-bg-gray: #f8fafc; - + --color-bg-gray: #fafafa; + --color-bg-hover: #f5f5f5; + /* 状态色 */ - --color-success: #10b981; - --color-warning: #f59e0b; - --color-error: #ef4444; - --color-error-bg: #fef2f2; - --color-error-border: #fecaca; - --color-info: #3b82f6; - + --color-success: #52c41a; + --color-warning: #faad14; + --color-error: #ff4d4f; + --color-error-bg: #fff2f0; + --color-error-border: #ffccc7; + --color-info: #1677ff; + /* 圆角 */ - --radius-sm: 6px; - --radius-md: 8px; - --radius-lg: 12px; - --radius-xl: 16px; + --radius-sm: 2px; + --radius-md: 4px; + --radius-lg: 6px; + --radius-xl: 8px; --radius-full: 9999px; - + /* 阴影 */ - --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05); - --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1); - --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1); - --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1); - --shadow-card: 0 25px 50px -12px rgba(0, 0, 0, 0.15); - + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04); + --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.06); + --shadow-lg: 0 2px 8px rgba(0, 0, 0, 0.08); + --shadow-xl: 0 4px 12px rgba(0, 0, 0, 0.08); + --shadow-card: 0 2px 8px rgba(0, 0, 0, 0.08); + /* 间距 */ --space-xs: 4px; --space-sm: 8px; --space-md: 16px; --space-lg: 24px; --space-xl: 32px; - --space-2xl: 48px; - + --space-2xl: 40px; + /* 字体 */ --font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif; --font-size-xs: 12px; --font-size-sm: 14px; - --font-size-base: 16px; - --font-size-lg: 18px; - --font-size-xl: 20px; - --font-size-2xl: 24px; - --font-size-3xl: 30px; - + --font-size-base: 14px; + --font-size-lg: 16px; + --font-size-xl: 18px; + --font-size-2xl: 22px; + --font-size-3xl: 28px; + /* 动画 */ - --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1); - --transition-base: 250ms cubic-bezier(0.4, 0, 0.2, 1); - --transition-slow: 350ms cubic-bezier(0.4, 0, 0.2, 1); + --transition-fast: 150ms ease; + --transition-base: 200ms ease; + --transition-slow: 300ms ease; } /* --- 全局重置 --- */ @@ -81,15 +83,14 @@ html, body { padding: 0; font-family: var(--font-family); font-size: var(--font-size-base); - line-height: 1.6; + line-height: 1.5715; color: var(--color-text); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } body { - background: var(--bg-gradient); - background-attachment: fixed; + background: var(--bg-page); } a { @@ -106,7 +107,7 @@ a:hover { .auth-wrapper { display: flex; flex-direction: column; - height: 100vh; + min-height: 100vh; } .auth-header { @@ -114,50 +115,51 @@ a:hover { display: flex; align-items: center; justify-content: space-between; - padding: var(--space-md) var(--space-xl); - background: rgba(255, 255, 255, 0.1); - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); - border-bottom: 1px solid rgba(255, 255, 255, 0.15); + padding: 0 var(--space-xl); + height: 56px; + background: var(--color-bg-white); + border-bottom: 1px solid var(--color-border-split); + box-shadow: 0 1px 4px rgba(0, 21, 41, 0.04); } .auth-header .brand { display: flex; align-items: center; gap: var(--space-sm); - color: #fff; + color: var(--color-text); font-size: var(--font-size-lg); font-weight: 600; text-decoration: none; } .auth-header .brand img { - width: 32px; - height: 32px; + width: 28px; + height: 28px; border-radius: var(--radius-sm); } .auth-header .user-menu { display: flex; align-items: center; - gap: var(--space-sm); - color: rgba(255, 255, 255, 0.9); + gap: var(--space-md); + color: var(--color-text-secondary); font-size: var(--font-size-sm); } .auth-header .user-menu a { - color: rgba(255, 255, 255, 0.9); + color: var(--color-text-secondary); padding: var(--space-xs) var(--space-md); - border-radius: var(--radius-full); - border: 1px solid rgba(255, 255, 255, 0.3); + border-radius: var(--radius-md); + border: 1px solid var(--color-border); + background: var(--color-bg-white); transition: all var(--transition-fast); font-size: var(--font-size-sm); } .auth-header .user-menu a:hover { - background: rgba(255, 255, 255, 0.2); - border-color: rgba(255, 255, 255, 0.5); - color: #fff; + color: var(--color-primary); + border-color: var(--color-primary); + background: var(--color-primary-light); } .auth-main { @@ -165,7 +167,7 @@ a:hover { display: flex; align-items: center; justify-content: center; - padding: var(--space-lg) var(--space-xl); + padding: var(--space-xl) var(--space-xl); overflow-y: auto; scrollbar-width: none; /* Firefox */ -ms-overflow-style: none; /* IE/Edge */ @@ -179,24 +181,22 @@ a:hover { flex: 0 0 auto; text-align: center; padding: var(--space-md); - color: rgba(255, 255, 255, 0.6); + color: var(--color-text-muted); font-size: var(--font-size-xs); } /* --- 认证卡片 --- */ .auth-card { width: 100%; - max-width: 420px; + max-width: 400px; background: var(--color-bg-white); - border-radius: var(--radius-xl); + border-radius: var(--radius-lg); box-shadow: var(--shadow-card); - padding: var(--space-2xl); - animation: slideUp 0.4s cubic-bezier(0.16, 1, 0.3, 1); - will-change: transform, opacity; + padding: var(--space-xl); } .auth-card.auth-card--wide { - max-width: 560px; + max-width: 480px; } .auth-card-header { @@ -205,20 +205,21 @@ a:hover { } .auth-card-header .auth-icon { - width: 56px; - height: 56px; - border-radius: var(--radius-lg); + width: 48px; + height: 48px; + border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; margin: 0 auto var(--space-md); - font-size: 28px; + font-size: 24px; background: var(--color-primary-light); + color: var(--color-primary); } .auth-card-header h1 { font-size: var(--font-size-2xl); - font-weight: 700; + font-weight: 600; color: var(--color-text); margin-bottom: var(--space-xs); } @@ -236,28 +237,31 @@ a:hover { .form-group label { display: block; font-size: var(--font-size-sm); - font-weight: 500; + font-weight: 400; color: var(--color-text); margin-bottom: var(--space-xs); } .form-control { width: 100%; - padding: 12px 16px; - font-size: var(--font-size-base); + padding: 8px 12px; + font-size: var(--font-size-sm); font-family: var(--font-family); color: var(--color-text); - background: var(--color-bg-gray); - border: 1.5px solid var(--color-border); + background: var(--color-bg-white); + border: 1px solid var(--color-border); border-radius: var(--radius-md); outline: none; transition: all var(--transition-fast); } +.form-control:hover { + border-color: var(--color-primary-hover); +} + .form-control:focus { - background: var(--color-bg-white); border-color: var(--color-primary); - box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.12); + box-shadow: 0 0 0 2px rgba(22, 119, 255, 0.1); } .form-control::placeholder { @@ -269,71 +273,89 @@ a:hover { display: inline-flex; align-items: center; justify-content: center; - padding: 12px 24px; - font-size: var(--font-size-base); - font-weight: 600; + padding: 8px 16px; + font-size: var(--font-size-sm); + font-weight: 400; font-family: var(--font-family); border-radius: var(--radius-md); - border: none; + border: 1px solid var(--color-border); cursor: pointer; transition: all var(--transition-fast); text-decoration: none; line-height: 1; gap: var(--space-sm); + background: var(--color-bg-white); + color: var(--color-text); } .btn:active { - transform: scale(0.97); + /* no transform */ } .btn-primary { width: 100%; background: var(--color-primary); color: #fff; - box-shadow: 0 2px 4px rgba(99, 102, 241, 0.3); + border-color: var(--color-primary); } .btn-primary:hover { background: var(--color-primary-hover); - box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4); - transform: translateY(-1px); + border-color: var(--color-primary-hover); color: #fff; } +.btn-primary:active { + background: var(--color-primary-active); + border-color: var(--color-primary-active); +} + .btn-secondary { - background: var(--color-bg-gray); + background: var(--color-bg-white); color: var(--color-text); - border: 1.5px solid var(--color-border); + border: 1px solid var(--color-border); } .btn-secondary:hover { + border-color: var(--color-primary-hover); + color: var(--color-primary-hover); background: var(--color-bg-white); - border-color: var(--color-primary); - color: var(--color-primary); +} + +.btn-secondary:active { + border-color: var(--color-primary-active); + color: var(--color-primary-active); } .btn-outline { background: transparent; color: var(--color-primary); - border: 1.5px solid var(--color-primary); + border: 1px solid var(--color-primary); } .btn-outline:hover { background: var(--color-primary); color: #fff; + border-color: var(--color-primary); } .btn-danger { background: var(--color-error); color: #fff; + border-color: var(--color-error); } .btn-danger:hover { - background: #dc2626; - transform: translateY(-1px); + background: #ff7875; + border-color: #ff7875; color: #fff; } +.btn-danger:active { + background: #d9363e; + border-color: #d9363e; +} + .btn-group { display: flex; gap: var(--space-sm); @@ -353,8 +375,8 @@ a:hover { } .checkbox-group input[type="checkbox"] { - width: 18px; - height: 18px; + width: 16px; + height: 16px; accent-color: var(--color-primary); cursor: pointer; } @@ -368,37 +390,38 @@ a:hover { /* --- 提示信息 --- */ .alert { - padding: var(--space-md); + padding: var(--space-sm) var(--space-md); border-radius: var(--radius-md); font-size: var(--font-size-sm); margin-bottom: var(--space-md); display: flex; align-items: flex-start; gap: var(--space-sm); + line-height: 1.5715; } .alert-error { background: var(--color-error-bg); border: 1px solid var(--color-error-border); - color: #991b1b; + color: rgba(0, 0, 0, 0.85); } .alert-warning { - background: #fffbeb; - border: 1px solid #fed7aa; - color: #92400e; + background: #fffbe6; + border: 1px solid #ffe58f; + color: rgba(0, 0, 0, 0.85); } .alert-info { - background: #eff6ff; - border: 1px solid #bfdbfe; - color: #1e40af; + background: #e6f4ff; + border: 1px solid var(--color-primary-border); + color: rgba(0, 0, 0, 0.85); } .alert-success { - background: #ecfdf5; - border: 1px solid #a7f3d0; - color: #065f46; + background: #f6ffed; + border: 1px solid #b7eb8f; + color: rgba(0, 0, 0, 0.85); } /* --- 分割线 --- */ @@ -414,7 +437,7 @@ a:hover { .divider::after { content: ''; flex: 1; - border-top: 1px solid var(--color-border); + border-top: 1px solid var(--color-border-split); } .divider span { @@ -441,23 +464,23 @@ a:hover { color: var(--color-text-muted); padding: var(--space-sm) var(--space-md); background: var(--color-bg-gray); - border-radius: var(--radius-sm); + border-radius: var(--radius-md); } /* --- 状态页面 --- */ .status-icon { - width: 72px; - height: 72px; + width: 64px; + height: 64px; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto var(--space-lg); - font-size: 36px; + font-size: 32px; } .status-icon--success { - background: #ecfdf5; + background: #f6ffed; color: var(--color-success); } @@ -467,12 +490,12 @@ a:hover { } .status-icon--warning { - background: #fffbeb; + background: #fffbe6; color: var(--color-warning); } .status-icon--info { - background: #eff6ff; + background: #e6f4ff; color: var(--color-info); } @@ -488,18 +511,20 @@ a:hover { align-items: center; gap: var(--space-xs); margin-top: var(--space-lg); - padding: 10px 20px; - background: var(--color-primary-light); + padding: 8px 16px; + background: var(--color-bg-white); color: var(--color-primary); - border-radius: var(--radius-full); + border: 1px solid var(--color-primary); + border-radius: var(--radius-md); font-size: var(--font-size-sm); - font-weight: 500; + font-weight: 400; transition: all var(--transition-fast); } .status-link:hover { background: var(--color-primary); color: #fff; + border-color: var(--color-primary); } /* --- 首页欢迎 --- */ @@ -512,37 +537,32 @@ a:hover { align-items: center; gap: var(--space-xs); margin-top: var(--space-md); - padding: 10px 20px; - background: var(--color-primary-light); + padding: 8px 16px; + background: var(--color-bg-white); color: var(--color-primary); - border-radius: var(--radius-full); + border: 1px solid var(--color-primary); + border-radius: var(--radius-md); font-size: var(--font-size-sm); - font-weight: 500; + font-weight: 400; transition: all var(--transition-fast); } .welcome-content .discovery-link:hover { background: var(--color-primary); color: #fff; + border-color: var(--color-primary); } /* --- 动画 --- */ -@keyframes slideUp { - from { - opacity: 0; - transform: translateY(20px); - } - to { - opacity: 1; - transform: translateY(0); - } -} - @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } +.auth-card { + animation: fadeIn 0.2s ease; +} + @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } @@ -565,17 +585,17 @@ a:hover { .auth-card { padding: var(--space-lg); margin: var(--space-md); - border-radius: var(--radius-lg); } - + .auth-header { - padding: var(--space-sm) var(--space-md); + padding: 0 var(--space-md); + height: 48px; } - + .auth-main { padding: var(--space-md); } - + .btn-group { flex-direction: column; } @@ -585,7 +605,7 @@ a:hover { .auth-card { padding: var(--space-md); } - + .auth-card-header h1 { font-size: var(--font-size-xl); } @@ -668,4 +688,4 @@ a:hover { } .grants .grant li:last-child:after { content: ''; -} \ No newline at end of file +} diff --git a/README.md b/README.md index bd03a97d..dba992e6 100644 --- a/README.md +++ b/README.md @@ -53,10 +53,13 @@ #### 付费订阅效果 -![主列表](snapshot/maintable.jpg) +![登录](snapshot/login.png) +![主页](snapshot/home.png) +![主列表](snapshot/mainlist.png) ![工作流](snapshot/image.png) ![打印方案设计](snapshot/sysprinterplan.png) + ## 📞官方QQ交流群 1. ***618473076*** **付费订阅专属QQ群,第一时间提供开发进度、技术咨询服务等,[如何加入请移步这里](http://old.openauth.net.cn/question/detail.html?id=a2be2d61-7fcb-4df8-8be2-9f296c22a89c)** @@ -84,8 +87,8 @@ * ✅支持多语言 * ✅支持自建OAuth2登录体系,详情:[登录认证及OAuth集成](http://doc.openauth.net.cn/core/identity/) * ✅支持已有系统无缝对接本项目流程引擎 -* ✅vue前端采用 vue2/3 + element-ui/plus + vform + hiprint + pinia + axios + uniapp -* ✅后端采用 .net +EF + sqlsugar + autofac + quartz +IdentityServer4 + nunit + swagger +* ✅vue前端采用 vue2/3 + element-ui/plus + vform + hiprint + pinia + axios + uniapp +* ✅后端采用 .net +EF + sqlsugar + autofac + quartz + openiddict + nunit + swagger * ✅设计工具 PowerDesigner +PDManer + Enterprise Architect ## 🔜后续 diff --git a/newdocs/docs/notes/core/identity.md b/newdocs/docs/notes/core/identity.md index e7cb30b5..7f858375 100644 --- a/newdocs/docs/notes/core/identity.md +++ b/newdocs/docs/notes/core/identity.md @@ -4,21 +4,24 @@ createTime: 2025/04/23 21:03:10 outline: [2,4] permalink: /core/identity/ --- - ## 前言 -OpenAuth.Net支持两种登录认证方式:Token认证和==自己搭建=={.tip}的OpenAuth.IdentityServer认证。 + +OpenAuth.Net支持两种登录认证方式:Token认证和==自己搭建=={.tip}的统一认证服务OpenAuth.Identity。 这两种方式通过配置webapi的appsettings.json可以自由切换: ```json "IdentityServerUrl": "http://localhost:12796", //IdentityServer服务器地址。如果为空,则不启用OAuth认证 ``` + ## Token认证 当我们启动OpenAuth.WebApi时,如果IdentityServerUrl为空,则采用普通的token认证,这时不需要启动OpenAuth.Identity项目: + ```json "IdentityServerUrl": "", //如果为空,则采用普通的token认证 ``` + 这时前端发出请求时会在请求头中添加X-Token字段,携带token值。以OpenAuth.WebApi为例,客户端在访问的接口时,先调用登录接口,得到授权token: ![20220119182845](http://img.openauth.net.cn/20220119182845.png) @@ -27,17 +30,19 @@ OpenAuth.Net支持两种登录认证方式:Token认证和==自己搭建=={.tip ![20220119182853](http://img.openauth.net.cn/20220119182853.png) -## OpenAuth.IdentityServer认证 +## OpenAuth.Net 统一认证 -不同于其他项目的统一登录(如微信登录、支付宝登录等),OpenAuth.Net的统一登录指的是自己搭建一套OAuth登录服务,提供给其他项目使用。即OpenAuth.IdentityServer。启动后,直接访问[http://localhost:12796](http://localhost:12796),效果如下: -![2025-03-18-23-12-18](http://img.openauth.net.cn/2025-03-18-23-12-18.png) +不同于其他项目使用微信登录、支付宝登录等,OpenAuth.Net的统一认证指的是自己搭建一套基于 OpenIddict 的统一身份认证服务,为其他项目提供 OpenID Connect / OAuth 2.0 协议支持,提供安全可靠的身份验证服务。 + +项目中的OpenAuth.Identity启动后,直接访问[http://localhost:12796](http://localhost:12796),效果如下: +![2026-06-27-20-22-30](http://img.openauth.net.cn/2026-06-27-20-22-30.png) 这时我们修改OpenAuth.WebApi的IdentityServerUrl配置: + ```json "IdentityServerUrl": "http://localhost:12796", //IdentityServer服务器地址。 ``` - ### OpenAuth.WebApi效果 当启用了Identity时,客户端调用API需要先通过OpenAuth.IdentityServer服务器的OAuth验证,才能调用接口。目前调用OpenAuth.WebApi的客户端有两种: @@ -53,14 +58,15 @@ VITE_OIDC_REDIRECTURI = http://localhost:1803 #登录回调 VITE_OIDC_RESPONSETYPE = code #认证方式 VITE_OIDC_SCOPE = openid profile openauthapi #认证范围 VITE_OIDC_AUTOMATICSILENTRENEW = true #自动续期 - ``` + 如果服务端启用了Identity认证,则打开登录界面如下: ![2025-03-10-14-46-47](http://img.openauth.net.cn/2025-03-10-14-46-47.png) 这时点击登录超链接,会跳转到OpenAuth.Identity登录界面。效果如下: -![2025-04-24-00-24-40](http://img.openauth.net.cn/2025-04-24-00-24-40.png) +![2026-06-27-20-23-17](http://img.openauth.net.cn/2026-06-27-20-23-17.png) +输入用户名和密码,登录成功后,会自动跳转回原页面,并提示授权成功。 #### SwaggerUI @@ -77,7 +83,3 @@ VITE_OIDC_AUTOMATICSILENTRENEW = true #自动续期 这时所有的接口都可以直接访问,访问时会在http头上自动加认证信息: ![20220119180608](http://img.openauth.net.cn/20220119180608.png) - - - - diff --git a/snapshot/home.png b/snapshot/home.png new file mode 100644 index 00000000..35ea0d49 Binary files /dev/null and b/snapshot/home.png differ diff --git a/snapshot/layui.jpg b/snapshot/layui.jpg deleted file mode 100644 index 94d13d43..00000000 Binary files a/snapshot/layui.jpg and /dev/null differ diff --git a/snapshot/login.png b/snapshot/login.png new file mode 100644 index 00000000..b29279cb Binary files /dev/null and b/snapshot/login.png differ diff --git a/snapshot/mainlist.png b/snapshot/mainlist.png new file mode 100644 index 00000000..b88f44c1 Binary files /dev/null and b/snapshot/mainlist.png differ diff --git a/snapshot/sysprinterplan.png b/snapshot/sysprinterplan.png index 683a8ec1..e18ab55e 100644 Binary files a/snapshot/sysprinterplan.png and b/snapshot/sysprinterplan.png differ