diff --git a/Infrastructure/ConfigUtils.cs b/Infrastructure/ConfigUtils.cs index 617875d..c733a9e 100644 --- a/Infrastructure/ConfigUtils.cs +++ b/Infrastructure/ConfigUtils.cs @@ -14,7 +14,7 @@ namespace Infrastructure static ConfigUtils() { - Config = App.ServiceProvider.GetRequiredService(); + Configuration = App.ServiceProvider.GetRequiredService(); if (Instance == null) Instance = new ConfigUtils(); @@ -22,35 +22,22 @@ namespace Infrastructure public static ConfigUtils Instance { get; private set; } #endregion - - private static IConfiguration Config { get; set; } - - /// - /// 泛型读取配置文件 - /// 目前还不能绑定到实体类 - /// - /// 获取不到配置文件设定默认值 - /// 要获取的配置文件节点名称 - /// - //public T GetConfig(string key, T defaultValue = default) - //{ - // //GetValue扩展包需要安装Microsoft.Extensions.Configuration - // var setting = Config.GetValue(key, defaultValue); - - // Console.WriteLine($"获取配置文件值key={key},value={setting}"); - // return setting; - //} + private static IConfiguration Configuration { get; set; } public T GetAppConfig(string key, T defaultValue = default(T)) { - T setting = (T)Convert.ChangeType(Config[key], typeof(T)); + T setting = (T)Convert.ChangeType(Configuration[key], typeof(T)); var value = setting; if (setting == null) value = defaultValue; - //Console.WriteLine($"获取配置文件值key={key},value={value}"); return value; } - + public T Bind(string key, T t) + { + Configuration.Bind(key, t); + + return t; + } /// /// 获取配置文件 /// @@ -58,7 +45,7 @@ namespace Infrastructure /// public string GetConfig(string key) { - return Config[key]; + return Configuration[key]; } /// @@ -66,10 +53,9 @@ namespace Infrastructure /// /// /// - public string GetConnectionStrings(string key) + public string GetConnectionString(string key) { - return Config.GetConnectionString(key); - + return Configuration.GetConnectionString(key); } } } diff --git a/Infrastructure/OptionsSetting.cs b/Infrastructure/OptionsSetting.cs index 7833a53..dc36620 100644 --- a/Infrastructure/OptionsSetting.cs +++ b/Infrastructure/OptionsSetting.cs @@ -50,4 +50,27 @@ namespace Infrastructure public string KEY { get; set; } public string SECRET { get; set; } } + + /// + /// Jwt + /// + public class JwtSettings + { + /// + /// token是谁颁发的 + /// + public string Issuer { get; set; } + /// + /// token可以给那些客户端使用 + /// + public string Audience { get; set; } + /// + /// 加密的key(SecretKey必须大于16个,是大于,不是大于等于) + /// + public string SecretKey { get; set; } + /// + /// token时间(分) + /// + public int Expire { get; set; } = 1440; + } } diff --git a/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs b/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs index b76f953..6687616 100644 --- a/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs +++ b/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs @@ -79,7 +79,7 @@ namespace ZR.Admin.WebApi.Controllers.System #endregion LoginUser loginUser = new LoginUser(user.UserId, user.UserName, roles, permissions); - return SUCCESS(JwtUtil.GenerateJwtToken(HttpContext.WriteCookies(loginUser))); + return SUCCESS(JwtUtil.GenerateJwtToken(HttpContext.AddClaims(loginUser))); } /// @@ -90,11 +90,11 @@ namespace ZR.Admin.WebApi.Controllers.System [HttpPost("logout")] public IActionResult LogOut() { - Task.Run(async () => - { - //注销登录的用户,相当于ASP.NET中的FormsAuthentication.SignOut - await HttpContext.SignOutAsync(); - }).Wait(); + //Task.Run(async () => + //{ + // //注销登录的用户,相当于ASP.NET中的FormsAuthentication.SignOut + // await HttpContext.SignOutAsync(); + //}).Wait(); return SUCCESS(1); } diff --git a/ZR.Admin.WebApi/Extensions/HttpContextExtension.cs b/ZR.Admin.WebApi/Extensions/HttpContextExtension.cs index d2cb61f..8f8faca 100644 --- a/ZR.Admin.WebApi/Extensions/HttpContextExtension.cs +++ b/ZR.Admin.WebApi/Extensions/HttpContextExtension.cs @@ -1,6 +1,7 @@ using Infrastructure; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Http; using Newtonsoft.Json; using System; @@ -67,7 +68,7 @@ namespace ZR.Admin.WebApi.Extensions { var uid = context.User.FindFirstValue(ClaimTypes.PrimarySid); - return !string.IsNullOrEmpty(uid) ? long.Parse(uid) : 0 ; + return !string.IsNullOrEmpty(uid) ? long.Parse(uid) : 0; } public static string GetName(this HttpContext context) { @@ -75,6 +76,16 @@ namespace ZR.Admin.WebApi.Extensions return uid; } + + /// + /// ClaimsIdentity + /// + /// + /// + public static IEnumerable GetClaims(this HttpContext context) + { + return context.User?.Identities; + } //public static int GetRole(this HttpContext context) //{ // var roleid = context.User.FindFirstValue(ClaimTypes.Role) ?? "0"; @@ -84,9 +95,7 @@ namespace ZR.Admin.WebApi.Extensions public static string GetUserAgent(this HttpContext context) { - var str = context.Request.Headers["User-Agent"]; - - return str; + return context.Request.Headers["User-Agent"]; } /// @@ -96,9 +105,7 @@ namespace ZR.Admin.WebApi.Extensions /// public static string GetToken(this HttpContext context) { - var str = context.Request.Headers["Token"]; - - return str; + return context.Request.Headers["Authorization"]; } public static ClientInfo GetClientInfo(this HttpContext context) @@ -116,12 +123,12 @@ namespace ZR.Admin.WebApi.Extensions } /// - /// 登录cookie写入 + ///组装Claims /// /// /// /// - public static List WriteCookies(this HttpContext context, LoginUser user) + public static List AddClaims(this HttpContext context, LoginUser user) { //1、创建Cookie保存用户信息,使用claim var claims = new List() @@ -138,13 +145,21 @@ namespace ZR.Admin.WebApi.Extensions { claims.Add(new Claim("perm", string.Join(",", user.Permissions))); } + + //写入Cookie + //WhiteCookie(context, claims); + return claims; + } + + private static void WhiteCookie(HttpContext context, List claims) + { //2.创建声明主题 指定认证方式 这里使用cookie var claimsIdentity = new ClaimsIdentity(claims, "Login"); Task.Run(async () => { await context.SignInAsync( - CookieAuthenticationDefaults.AuthenticationScheme,//这里要注意的是HttpContext.SignInAsync(AuthenticationType,…) 所设置的Scheme一定要与前面的配置一样,这样对应的登录授权才会生效。 + JwtBearerDefaults.AuthenticationScheme,//这里要注意的是HttpContext.SignInAsync(AuthenticationType,…) 所设置的Scheme一定要与前面的配置一样,这样对应的登录授权才会生效。 new ClaimsPrincipal(claimsIdentity), new AuthenticationProperties() { @@ -153,7 +168,6 @@ namespace ZR.Admin.WebApi.Extensions ExpiresUtc = DateTimeOffset.Now.AddDays(1),//有效时间 }); }).Wait(); - return claims; } } diff --git a/ZR.Admin.WebApi/Filters/VerifyAttribute.cs b/ZR.Admin.WebApi/Filters/VerifyAttribute.cs index cbfaff1..2b4db73 100644 --- a/ZR.Admin.WebApi/Filters/VerifyAttribute.cs +++ b/ZR.Admin.WebApi/Filters/VerifyAttribute.cs @@ -10,6 +10,7 @@ using NLog; using System; using System.Linq; using ZR.Admin.WebApi.Extensions; +using ZR.Admin.WebApi.Framework; using ZR.Model.System; namespace ZR.Admin.WebApi.Filters @@ -44,12 +45,10 @@ namespace ZR.Admin.WebApi.Filters string ip = HttpContextExtension.GetClientUserIp(context.HttpContext); string url = context.HttpContext.Request.Path; var isAuthed = context.HttpContext.User.Identity.IsAuthenticated; - // 检查登陆 - 在SignIn中判断用户合法性,将登陆信息保存在Cookie中,在SignOut中移除登陆信息 var userName = context.HttpContext.User.Identity.Name; //使用jwt token校验2020-11-21 - //string token = context.HttpContext.Request.Headers["Token"]; - LoginUser info = Framework.JwtUtil.GetLoginUser(context.HttpContext); + LoginUser info = JwtUtil.GetLoginUser(context.HttpContext); if (info != null && info.UserId > 0) { @@ -58,7 +57,7 @@ namespace ZR.Admin.WebApi.Filters else { string msg = $"请求访问:{url}授权认证失败,无法访问系统资源"; - logger.Info(msg); + logger.Info($"用户{userName}{msg}"); context.Result = new JsonResult(new ApiResult((int)ResultCode.DENY, msg)); } diff --git a/ZR.Admin.WebApi/Framework/JwtUtil.cs b/ZR.Admin.WebApi/Framework/JwtUtil.cs index 1f7f073..75f237a 100644 --- a/ZR.Admin.WebApi/Framework/JwtUtil.cs +++ b/ZR.Admin.WebApi/Framework/JwtUtil.cs @@ -18,8 +18,6 @@ namespace ZR.Admin.WebApi.Framework /// public class JwtUtil { - public static readonly string KEY = "asdfghjklzxcvbnm"; - /// /// 获取用户身份信息 /// @@ -28,6 +26,7 @@ namespace ZR.Admin.WebApi.Framework public static LoginUser GetLoginUser(HttpContext httpContext) { string token = HttpContextExtension.GetToken(httpContext); + if (!string.IsNullOrEmpty(token)) { return ValidateJwtToken(ParseToken(token)); @@ -42,21 +41,52 @@ namespace ZR.Admin.WebApi.Framework /// public static string GenerateJwtToken(List claims) { + JwtSettings jwtSettings = new(); + ConfigUtils.Instance.Bind("JwtSettings", jwtSettings); + var tokenHandler = new JwtSecurityTokenHandler(); - var key = Encoding.ASCII.GetBytes(KEY); - var expires = ConfigUtils.Instance.GetAppConfig("sysConfig:tokenExpire", 10); + var key = Encoding.ASCII.GetBytes(jwtSettings.SecretKey); + claims.Add(new Claim("Audience", jwtSettings.Audience)); + claims.Add(new Claim("Issuer", jwtSettings.Issuer)); + var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claims), - //Issuer = "", - //Audience = "", - Expires = DateTime.Now.AddMinutes(expires), + Issuer = jwtSettings.Issuer, + Audience = jwtSettings.Audience, + IssuedAt = DateTime.Now,//token生成时间 + Expires = DateTime.Now.AddMinutes(jwtSettings.Expire), + TokenType = "Bearer", + //对称秘钥,签名证书 SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); } + /// + /// 验证Token + /// + /// + public static TokenValidationParameters ValidParameters() + { + JwtSettings jwtSettings = new(); + ConfigUtils.Instance.Bind("JwtSettings", jwtSettings); + var key = Encoding.ASCII.GetBytes(jwtSettings.SecretKey); + + var tokenDescriptor = new TokenValidationParameters + { + ValidateIssuerSigningKey = true, + ValidateIssuer = true, + ValidateAudience = true, + ValidIssuer = jwtSettings.Issuer, + ValidAudience = jwtSettings.Audience, + IssuerSigningKey = new SymmetricSecurityKey(key), + ValidateLifetime = true,//是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比 + RequireExpirationTime = true,//过期时间 + }; + return tokenDescriptor; + } /// /// 从令牌中获取数据声明 /// @@ -65,21 +95,13 @@ namespace ZR.Admin.WebApi.Framework public static IEnumerable ParseToken(string token) { var tokenHandler = new JwtSecurityTokenHandler(); - var key = Encoding.ASCII.GetBytes(KEY); + var validateParameter = ValidParameters(); + token = token.Replace("Bearer ", ""); try { - tokenHandler.ValidateToken(token, new TokenValidationParameters - { - ValidateIssuerSigningKey = true, - IssuerSigningKey = new SymmetricSecurityKey(key), - ValidateIssuer = false, - ValidateAudience = false, - // set clockskew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later) - ClockSkew = TimeSpan.Zero - }, out SecurityToken validatedToken); + tokenHandler.ValidateToken(token, validateParameter, out SecurityToken validatedToken); - //{{"alg":"HS256","typ":"JWT"}.{"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid":"2","unique_name":"ry","nameid":"2","given_name":"若依","nbf":1606654010,"exp":1606740410,"iat":1606654010}} - var jwtToken = (JwtSecurityToken)validatedToken; + var jwtToken = tokenHandler.ReadJwtToken(token); return jwtToken.Claims; } catch (Exception ex) diff --git a/ZR.Admin.WebApi/Startup.cs b/ZR.Admin.WebApi/Startup.cs index 4535ce5..d1407f8 100644 --- a/ZR.Admin.WebApi/Startup.cs +++ b/ZR.Admin.WebApi/Startup.cs @@ -2,6 +2,7 @@ using Hei.Captcha; using Infrastructure; using Infrastructure.Extensions; using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Hosting; @@ -55,11 +56,23 @@ namespace ZR.Admin.WebApi services.AddSession(); services.AddHttpContextAccessor(); - //Cookie ֤ - services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(); //Model services.Configure(Configuration); + services.Configure(Configuration); + var jwtSettings = new JwtSettings(); + Configuration.Bind("JwtSettings", jwtSettings); + + //Cookie ֤ + services.AddAuthentication(options => + { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }).AddCookie() + .AddJwtBearer(o => + { + o.TokenValidationParameters = JwtUtil.ValidParameters(); + }); InjectRepositories(services); @@ -78,11 +91,11 @@ namespace ZR.Admin.WebApi services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "ZrAdmin", Version = "v1" }); - if (CurrentEnvironment.IsDevelopment()) - { - //ĵע - c.IncludeXmlComments("ZRAdmin.xml", true); - } + //if (CurrentEnvironment.IsDevelopment()) + //{ + //ĵע + c.IncludeXmlComments(Path.Combine(CurrentEnvironment.ContentRootPath, "ZRAdmin.xml"), true); + //} }); } @@ -112,7 +125,9 @@ namespace ZR.Admin.WebApi //app.UseAuthenticationAuthenticationммݵǰHttpеCookieϢHttpContext.Userԣõ //ֻapp.UseAuthentication֮עмܹHttpContext.Userжȡֵ //ҲΪʲôǿapp.UseAuthenticationһҪapp.UseMvcǰ棬ΪֻASP.NET CoreMVCмвܶȡHttpContext.Userֵ + //1.ȿ֤ app.UseAuthentication(); + //2.ٿȨ app.UseAuthorization(); app.UseSession(); app.UseResponseCaching(); @@ -149,12 +164,12 @@ namespace ZR.Admin.WebApi SugarIocServices.AddSqlSugar(new List() { new IocConfig() { - ConfigId = "0", + ConfigId = "0", ConnectionString = connStr, DbType = (IocDbType)dbType, IsAutoCloseConnection = true//Զͷ }, new IocConfig() { - ConfigId = "1", + ConfigId = "1", ConnectionString = connStrBus, DbType = (IocDbType)dbType_bus, IsAutoCloseConnection = true//Զͷ diff --git a/ZR.Admin.WebApi/appsettings.json b/ZR.Admin.WebApi/appsettings.json index 8723085..b8dcce0 100644 --- a/ZR.Admin.WebApi/appsettings.json +++ b/ZR.Admin.WebApi/appsettings.json @@ -15,9 +15,14 @@ "urls": "http://localhost:8888", //Ŀurl "sysConfig": { "DBCommandTimeout": 10, - "tokenExpire": 1440, //Jwt tokenʱʱ䣨֣ "cors": "http://localhost:8887" //ַ"," }, + "JwtSettings": { + "Issuer": "https://localhost:8888", + "Audience": "https://localhost:8888", + "SecretKey": "Hello-key-ZRADMIN.NET-20210101", + "Expire": 5 + }, "DemoMode": false, //Ƿʾģʽ "DbKey": "", //ݿkey "Upload": { @@ -30,7 +35,7 @@ "KEY": "XX", "SECRET": "XX", "bucketName": "bucketName", - "domainUrl": "http://xxx.xxx.com"//Դ + "domainUrl": "http://xxx.xxx.com" //Դ }, "gen": { "conn": "server=LAPTOP-STKF2M8H\\SQLEXPRESS;user=zr;pwd=abc;database=ZrAdmin;Trusted_Connection=SSPI", diff --git a/ZR.Vue/src/permission.js b/ZR.Vue/src/permission.js index 2b3b080..32676e7 100644 --- a/ZR.Vue/src/permission.js +++ b/ZR.Vue/src/permission.js @@ -1,11 +1,17 @@ import router from './router' import store from './store' -import { Message } from 'element-ui' +import { + Message +} from 'element-ui' import NProgress from 'nprogress' import 'nprogress/nprogress.css' -import { getToken } from '@/utils/auth' +import { + getToken +} from '@/utils/auth' -NProgress.configure({ showSpinner: false }) +NProgress.configure({ + showSpinner: false +}) const whiteList = ['/login', '/auth-redirect', '/bind', '/register', '/demo'] @@ -17,7 +23,9 @@ router.beforeEach((to, from, next) => { if (hasToken) { /* has token*/ if (to.path === '/login') { - next({ path: '/' }) + next({ + path: '/' + }) NProgress.done() } else { if (store.getters.roles.length === 0) { @@ -27,21 +35,28 @@ router.beforeEach((to, from, next) => { //console.log('拉取userInfo', JSON.stringify(res)) // 拉取user_info const roles = res.data.roles - store.dispatch('GenerateRoutes', { roles }).then(accessRoutes => { + store.dispatch('GenerateRoutes', { + roles + }).then(accessRoutes => { // 测试 默认静态页面 // store.dispatch('permission/generateRoutes', { roles }).then(accessRoutes => { // 根据roles权限生成可访问的路由表 router.addRoutes(accessRoutes) // 动态添加可访问路由表 - next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 + next({ + ...to, + replace: true + }) // hack方法 确保addRoutes已完成 }) next() }).catch(err => { console.error(err) //这部不能少,否则会出现死循环 store.dispatch('FedLogOut').then(() => { - Message.error(err) - next({ path: '/' }) + Message.error(err != undefined ? err : '登录失败') + next({ + path: '/' + }) }) next(`/login?redirect=${to.path}`) }) diff --git a/ZR.Vue/src/utils/request.js b/ZR.Vue/src/utils/request.js index 85dd568..cf02372 100644 --- a/ZR.Vue/src/utils/request.js +++ b/ZR.Vue/src/utils/request.js @@ -1,7 +1,12 @@ import axios from 'axios' -import { MessageBox, Message } from 'element-ui' +import { + MessageBox, + Message +} from 'element-ui' import store from '@/store' -import { getToken } from '@/utils/auth' +import { + getToken +} from '@/utils/auth' // import errorCode from '@/utils/errorCode' // 解决后端跨域获取不到cookie问题 @@ -18,15 +23,9 @@ const service = axios.create({ // request拦截器 service.interceptors.request.use(config => { // 是否需要设置 token - // const isToken = (config.headers || {}).isToken === false - // if (getToken() && !isToken) { - // config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 - // } - // return config - // console.log(store.getters) if (getToken()) { //将token放到请求头发送给服务器,将tokenkey放在请求头中 - config.headers.Token = getToken(); + config.headers['Authorization'] = 'Bearer ' + getToken(); } else { // console.log(config) } @@ -38,50 +37,47 @@ service.interceptors.request.use(config => { // 响应拦截器 service.interceptors.response.use(res => { - if (res.status !== 200) { - Promise.reject('network error'); - return; - } - // 未设置状态码则默认成功状态 - const code = res.data.code; - const msg = res.data.msg; - - if (code == 401) { - MessageBox.confirm('登录状态已过期,请重新登录', '系统提示', { - confirmButtonText: '重新登录', - cancelButtonText: '取消', - type: 'warning' + if (res.status !== 200) { + Promise.reject('network error'); + return; } - ).then(() => { - store.dispatch('LogOut').then(() => { - location.href = '/index'; - }) - }) + // 未设置状态码则默认成功状态 + const code = res.data.code; + const msg = res.data.msg; - return Promise.reject() - } - else if (code == 0 || code == 110 || code == 101 || code == 403 || code == 500) { - Message({ - message: msg, - type: 'error' - }) - return Promise.reject() - } - else { - //返回标准 code/msg/data字段 - return res.data; - } -}, + if (code == 401) { + MessageBox.confirm('登录状态已过期,请重新登录', '系统提示', { + confirmButtonText: '重新登录', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + store.dispatch('LogOut').then(() => { + location.href = '/index'; + }) + }) + + return Promise.reject() + } else if (code == 0 || code == 110 || code == 101 || code == 403 || code == 500) { + Message({ + message: msg, + type: 'error' + }) + return Promise.reject() + } else { + //返回标准 code/msg/data字段 + return res.data; + } + }, error => { console.log('err' + error) - let { message } = error; + let { + message + } = error; if (message == "Network Error") { message = "后端接口连接异常"; - } - else if (message.includes("timeout")) { + } else if (message.includes("timeout")) { message = "系统接口请求超时"; - } - else if (message.includes("Request failed with status code")) { + } else if (message.includes("Request failed with status code")) { message = "系统接口" + message.substr(message.length - 3) + "异常"; } Message({ @@ -129,10 +125,10 @@ export function post(url, params) { } /** -* 提交表单 -* @param {*} url -* @param {*} data -*/ + * 提交表单 + * @param {*} url + * @param {*} data + */ export function postForm(url, data, config) { return new Promise((resolve, reject) => { axios.post(url, data, config).then(res => { diff --git a/ZR.Vue/src/utils/zipdownload.js b/ZR.Vue/src/utils/zipdownload.js index 500d371..f8cf764 100644 --- a/ZR.Vue/src/utils/zipdownload.js +++ b/ZR.Vue/src/utils/zipdownload.js @@ -14,7 +14,7 @@ export function downLoadZip(str, filename) { method: 'get', url: str, responseType: 'blob', - headers: { 'Token': getToken() } + headers: { 'Authorization': 'Bearer ' + getToken() } }).then(res => { resolveBlob(res, mimeMap.zip) }) @@ -25,7 +25,7 @@ export function downLoadExcel(str, filename) { method: 'get', url: url, responseType: 'blob', - headers: { 'Token': getToken() } + headers: { 'Authorization': 'Bearer ' + getToken() } }).then(res => { resolveExcel(res, filename) }) diff --git a/ZR.Vue/src/views/system/user/index.vue b/ZR.Vue/src/views/system/user/index.vue index 71da5d1..ec2631c 100644 --- a/ZR.Vue/src/views/system/user/index.vue +++ b/ZR.Vue/src/views/system/user/index.vue @@ -273,7 +273,7 @@ export default { // 是否更新已经存在的用户数据 updateSupport: 0, // 设置上传的请求头部 - headers: { Authorization: getToken() }, + headers: { Authorization: 'Bearer ' + getToken() }, // 上传的地址 url: process.env.VUE_APP_BASE_API + "system/user/importData", }, diff --git a/ZR.Vue/src/views/tool/email/sendEmail.vue b/ZR.Vue/src/views/tool/email/sendEmail.vue index 02bdb5e..199530e 100644 --- a/ZR.Vue/src/views/tool/email/sendEmail.vue +++ b/ZR.Vue/src/views/tool/email/sendEmail.vue @@ -9,7 +9,7 @@ - + @@ -37,7 +37,7 @@ export default { fileUrl: "", }, headers: { - Token: "", + Authorization: "Bearer " + getToken(), }, uploadActionUrl: process.env.VUE_APP_BASE_API + "upload/SaveFile", rules: { @@ -55,7 +55,6 @@ export default { }; }, mounted() { - this.headers.Token = getToken(); }, methods: { // 表单重置 @@ -106,7 +105,7 @@ export default { loading.close(); }, 5000); } else { - console.log('未通过') + console.log("未通过"); //校验不通过 return false; }