ソースを参照

😎完善超级API插件功能

zuohuaijun 2 年 前
コミット
1320520741

+ 1 - 1
Admin.NET/Plugins/Admin.NET.Plugin.ReZero/Admin.NET.Plugin.ReZero.csproj

@@ -24,7 +24,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="Rezero.Api" Version="1.0.10" />
+    <PackageReference Include="Rezero.Api" Version="1.0.14" />
   </ItemGroup>  
 
   <ItemGroup>

+ 2 - 1
Admin.NET/Plugins/Admin.NET.Plugin.ReZero/GlobalUsings.cs

@@ -4,4 +4,5 @@
 //
 // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
 
-global using Furion;
+global using Furion;
+global using Furion.ConfigurableOptions;

+ 20 - 0
Admin.NET/Plugins/Admin.NET.Plugin.ReZero/Option/ReZeroOptions.cs

@@ -0,0 +1,20 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Plugin.ReZero;
+
+public sealed class ReZeroOptions : IConfigurableOptions
+{
+    /// <summary>
+    /// AccessTokenKey
+    /// </summary>
+    public string AccessTokenKey { get; set; }
+
+    /// <summary>
+    /// RefreshAccessTokenKey
+    /// </summary>
+    public string RefreshAccessTokenKey { get; set; }
+}

+ 5 - 5
Admin.NET/Plugins/Admin.NET.Plugin.ReZero/SeedData/SysMenuSeedData.cs

@@ -22,11 +22,11 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData<SysMenu>
         return new[]
         {
             new SysMenu{ Id=1310000000651, Pid=1310000000601, Title="超级API", Path="/develop/reZero", Name="sysReZero", Component="Layout", Icon="ele-MagicStick", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=140 },
-            new SysMenu{ Id=1310000000655, Pid=1310000000651, Title="数据库管理", Path="/develop/reZero/database", Name="sysReZeroDatabase", Component="layout/routerView/iframe", Icon="ele-Menu", Type=MenuTypeEnum.Menu, IsIframe=true, OutLink="http://localhost:5005/rezero/database_manager.html?model=small", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000660, Pid=1310000000651, Title="实体表管理", Path="/develop/reZero/entity", Name="sysReZeroEntity", Component="layout/routerView/iframe", Icon="ele-Menu", Type=MenuTypeEnum.Menu, IsIframe=true, OutLink="http://localhost:5005/rezero/entity_manager.html?model=small", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
-            new SysMenu{ Id=1310000000665, Pid=1310000000651, Title="接口分类", Path="/develop/reZero/apiCategory", Name="sysReZeroApiCategory", Component="layout/routerView/iframe", Icon="ele-Menu", Type=MenuTypeEnum.Menu, IsIframe=true, OutLink="http://localhost:5005/rezero/interface_categroy.html?model=small", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=120 },
-            new SysMenu{ Id=1310000000670, Pid=1310000000651, Title="接口定义", Path="/develop/reZero/apiDefine", Name="sysReZeroApiDefine", Component="layout/routerView/iframe", Icon="ele-Menu", Type=MenuTypeEnum.Menu, IsIframe=true, OutLink="http://localhost:5005/rezero/interface_manager.html?model=small", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=130 },
-            new SysMenu{ Id=1310000000675, Pid=1310000000651, Title="动态接口", Path="/develop/reZero/dynamicApi", Name="sysReZeroDynamicApi", Component="layout/routerView/iframe", Icon="ele-Menu", Type=MenuTypeEnum.Menu, IsIframe=true, OutLink="http://localhost:5005/rezero/dynamic_interface.html?model=small", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=140 },
+            new SysMenu{ Id=1310000000655, Pid=1310000000651, Title="动态接口", Path="/develop/reZero/dynamicApi", Name="sysReZeroDynamicApi", Component="layout/routerView/iframe", Icon="ele-Menu", Type=MenuTypeEnum.Menu, IsIframe=true, OutLink="http://localhost:5005/rezero/dynamic_interface.html?model=small", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000660, Pid=1310000000651, Title="数据库管理", Path="/develop/reZero/database", Name="sysReZeroDatabase", Component="layout/routerView/iframe", Icon="ele-Menu", Type=MenuTypeEnum.Menu, IsIframe=true, OutLink="http://localhost:5005/rezero/database_manager.html?model=small", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
+            new SysMenu{ Id=1310000000665, Pid=1310000000651, Title="实体表管理", Path="/develop/reZero/entity", Name="sysReZeroEntity", Component="layout/routerView/iframe", Icon="ele-Menu", Type=MenuTypeEnum.Menu, IsIframe=true, OutLink="http://localhost:5005/rezero/entity_manager.html?model=small", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=120 },
+            new SysMenu{ Id=1310000000670, Pid=1310000000651, Title="接口分类", Path="/develop/reZero/apiCategory", Name="sysReZeroApiCategory", Component="layout/routerView/iframe", Icon="ele-Menu", Type=MenuTypeEnum.Menu, IsIframe=true, OutLink="http://localhost:5005/rezero/interface_categroy.html?model=small", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=130 },
+            new SysMenu{ Id=1310000000675, Pid=1310000000651, Title="接口定义", Path="/develop/reZero/apiDefine", Name="sysReZeroApiDefine", Component="layout/routerView/iframe", Icon="ele-Menu", Type=MenuTypeEnum.Menu, IsIframe=true, OutLink="http://localhost:5005/rezero/interface_manager.html?model=small", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=140 },
         };
     }
 }

+ 15 - 12
Admin.NET/Plugins/Admin.NET.Plugin.ReZero/Service/SuperApiAop.cs

@@ -13,7 +13,6 @@ using Microsoft.AspNetCore.Authentication;
 using Microsoft.AspNetCore.Authentication.JwtBearer;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.Logging;
-using NewLife;
 using ReZero.SuperAPI;
 
 namespace Admin.NET.Plugin.ReZero.Service;
@@ -25,12 +24,17 @@ public class SuperApiAop : DefaultSuperApiAop
 {
     public override async Task OnExecutingAsync(InterfaceContext aopContext)
     {
-        if (aopContext.InterfaceType == InterfaceType.DynamicApi)
-        {
-            var authenticateResult = await aopContext.HttpContext.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);
-            if (!authenticateResult.Succeeded)
-                throw Oops.Oh("没权限 Unauthorized");
-        }
+        //if (aopContext.InterfaceType == InterfaceType.DynamicApi)
+        //{
+        var authenticateResult = await aopContext.HttpContext.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);
+        if (!authenticateResult.Succeeded)
+            throw Oops.Oh("没权限 Unauthorized");
+        //}
+
+        var accessToken = aopContext.HttpContext.Request.Headers["Authorization"].ToString();
+        var (isValid, tokenData, validationResult) = JWTEncryption.Validate(accessToken.Replace("Bearer ", ""));
+        if (!isValid)
+            throw Oops.Oh("Token 无效");
 
         await base.OnExecutingAsync(aopContext);
     }
@@ -59,11 +63,10 @@ public class SuperApiAop : DefaultSuperApiAop
         var api = aopContext.InterfaceInfo;
         var context = aopContext.HttpContext;
 
-        var accessToken = context.Response.Headers["access-token"].ToString();
-        var token = string.IsNullOrWhiteSpace(accessToken)
-            ? context.Request.Headers["Authorization"].ToString()
-            : "Bearer " + accessToken;
-        var claims = JWTEncryption.ReadJwtToken(token)?.Claims;
+        var accessToken = context.Request.Headers["Authorization"].ToString();
+        if (!string.IsNullOrWhiteSpace(accessToken) && accessToken.StartsWith("Bearer "))
+            accessToken = accessToken.Replace("Bearer ", "");
+        var claims = JWTEncryption.ReadJwtToken(accessToken)?.Claims;
         var userName = claims?.FirstOrDefault(u => u.Type == ClaimConst.Account)?.Value;
         var realName = claims?.FirstOrDefault(u => u.Type == ClaimConst.RealName)?.Value;
 

+ 4 - 1
Admin.NET/Plugins/Admin.NET.Plugin.ReZero/Startup.cs

@@ -20,6 +20,8 @@ public class Startup : AppStartup
 {
     public void ConfigureServices(IServiceCollection services)
     {
+        var reZeroOpt = App.GetConfig<ReZeroOptions>("ReZero", true);
+
         // 获取默认数据库配置(第一个)
         var dbOptions = App.GetConfig<DbConnectionOptions>("DbConnection", true);
         var superAPIOption = new SuperAPIOptions()
@@ -35,7 +37,8 @@ public class Startup : AppStartup
             UiOptions = new UiOptions() { DefaultIndexSource = "/index.html" },
             InterfaceOptions = new InterfaceOptions()
             {
-                SuperApiAop = new SuperApiAop() // 授权拦截器
+                AuthorizationLocalStorageName = reZeroOpt.AccessTokenKey, // 浏览器本地存储LocalStorage存储Token的键名
+                SuperApiAop = new SuperApiAop() // 超级API拦截器
             }
         };
 

+ 2 - 1
Web/src/layout/routerView/iframes.vue

@@ -3,7 +3,7 @@
 		<div class="layout-padding-auto layout-padding-view">
 			<div class="w100" v-for="v in setIframeList" :key="v.path" v-loading="v.meta.loading" element-loading-background="white">
 				<transition-group :name="name">
-					<iframe :src="v.meta.isLink" :key="v.path" frameborder="0" height="100%" width="100%" style="position: absolute" :data-url="v.path" v-show="getRoutePath === v.path" ref="iframeRef" />
+					<iframe :src="`${v.meta.isLink}&token=${getToken()}`" :key="v.path" frameborder="0" height="100%" width="100%" style="position: absolute" :data-url="v.path" v-show="getRoutePath === v.path" ref="iframeRef" />
 				</transition-group>
 			</div>
 		</div>
@@ -13,6 +13,7 @@
 <script setup lang="ts" name="layoutIframeView">
 import { computed, watch, ref, nextTick } from 'vue';
 import { useRoute } from 'vue-router';
+import { getToken } from '/@/utils/axios-utils';
 
 // 定义父组件传过来的值
 const props = defineProps({