> 技术文档 > 解决uniapp/小程序访问Ruoyi框架报错401,认证失败,无法访问系统资源(已解决)_若依 认证失败,无法访问系统资源

解决uniapp/小程序访问Ruoyi框架报错401,认证失败,无法访问系统资源(已解决)_若依 认证失败,无法访问系统资源

        在前后端分离开发场景中,当自己的后台管理系统搭建好之后,想要使用uniapp或微信小程序对接Ruoyi框架时,做一款小程序,常会遇到401(Unauthorized)认证失败错误。

        作者在网上搜索了大量资料,大多数都是因过滤器问题,需要放行权限或者是删掉注解等方案,经过逐一碰壁,发现问题并没有得到解决,最终通过令牌解决了。

        本文将通过实际案例,深入剖析问题根源并提供系统化的解决方案。

 

一、问题现象还原、代码复现(uniapp请求为例)

//uniapp getinfo()请求用户信息方法 methods: {getinfo(){const requestTask = uni.request({url: \'http://localhost:8080/system/user/list\',success: function(res) {this.userlist= res.data.rows console.log(res.data);}});}}}

解决uniapp/小程序访问Ruoyi框架报错401,认证失败,无法访问系统资源(已解决)_若依 认证失败,无法访问系统资源

图1 调用getinfo()方法出现401报错

 

解决uniapp/小程序访问Ruoyi框架报错401,认证失败,无法访问系统资源(已解决)_若依 认证失败,无法访问系统资源

图2 直接使用浏览器请求接口,同样报错401

 

二、问题根源剖析

(1)认证令牌缺失(最常见)

举个例子:你要回家拿衣服,可是门锁了,你没拿钥匙,就进不去,无法拿到衣服

检测方法:在浏览器的控制台查看请求Headers是否含有令牌

异常表现:请求头缺少Authorization字段

解决uniapp/小程序访问Ruoyi框架报错401,认证失败,无法访问系统资源(已解决)_若依 认证失败,无法访问系统资源

图3 请求头含有Authorization令牌

解决uniapp/小程序访问Ruoyi框架报错401,认证失败,无法访问系统资源(已解决)_若依 认证失败,无法访问系统资源

图4 请求头没有Authorization令牌(主要问题)

(2)Token失效情形

举个例子:你家里的是密码锁,你家的密码是一次性的,也就是说,使用完这个密码开门,把门关上后,密码会变为一个新的密码(令牌),所以会过期,又或者是你把家里的密码锁换了个新的(重启后端),密码也会变为一个新的。

也就是说:每一次登录或者重启ruoyi后端都会更新一个Authorization令牌,但在开发中,小程序不可能每次令牌变更都去更新一次Authorization令牌,所以这就需要我们去延长令牌的过期时间,避免令牌失效即可。

失效类型 特征描述 解决方案 过期失效(常见) Token解码后 重新登录获取新Token 服务端主动失效(常见) 服务器重启或强制退出 客户端重新认证 签名验证失败 Token被篡改 检查Token生成/传输过程

(3)过滤器配置

  Ruoyi框架的过滤器可能会拦截所有请求,包括静态资源请求,导致页面无法正常渲染。未正确放行静态资源如果过滤器没有正确配置静态资源的放行规则,可能会导致静态资源无法正常加载,进而影响前端页面的显示。

解决方法:在过滤器中明确放行静态资源路径。

 /** * anyRequest | 匹配所有请求路径 * access  | SpringEl表达式结果为true时可以访问 * anonymous  | 匿名可以访问 * denyAll | 用户不能访问 * fullyAuthenticated | 用户完全认证可以访问(非remember-me下自动登录) * hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问 * hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问 * hasAuthority | 如果有参数,参数表示权限,则其权限可以访问 * hasIpAddress | 如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问 * hasRole | 如果有参数,参数表示角色,则其角色可以访问 * permitAll  | 用户可以任意访问 * rememberMe | 允许通过remember-me登录的用户访问 * authenticated | 用户登录后可访问 */ @Override protected void configure(HttpSecurity httpSecurity) throws Exception { // 注解标记允许匿名访问的url ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests(); permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll()); httpSecurity // CSRF禁用,因为不使用session .csrf().disable() // 禁用HTTP响应标头 .headers().cacheControl().disable().and() // 认证失败处理类 .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() // 基于token,所以不需要session .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() // 过滤请求 .authorizeRequests() // 对于登录login 注册register 验证码captchaImage 允许匿名访问 .antMatchers(\"/login\", \"/register\", \"/captchaImage\").permitAll() // 静态资源,可匿名访问 .antMatchers(HttpMethod.GET, \"/\", \"/*.html\", \"/**/*.html\", \"/**/*.css\", \"/**/*.js\", \"/profile/**\").permitAll() .antMatchers(\"/swagger-ui.html\",\"/test/user\",\"/swagger-resources/**\", \"/webjars/**\", \"/*/api-docs\", \"/druid/**\").permitAll() // 除上面外的所有请求全部需要鉴权认证 .anyRequest().authenticated() .and() .headers().frameOptions().disable(); // 添加Logout filter httpSecurity.logout().logoutUrl(\"/logout\").logoutSuccessHandler(logoutSuccessHandler); // 添加JWT filter httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); // 添加CORS filter httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class); httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class); }

三、解决步骤

第一步:获取令牌

运行项目,使用谷歌浏览器打开开发者界面Network界面后,点击登录,注意检查Network里的get方法,均可以找到令牌。

解决uniapp/小程序访问Ruoyi框架报错401,认证失败,无法访问系统资源(已解决)_若依 认证失败,无法访问系统资源

图5 获取Authorization令牌

Authorization:

Bearer eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjQ4YTVlNGI5LTVhMzctNGYwNi05MTE3LTVkY2YyZTIwNDU2NiJ9.E5Yp1D3QcIfX3JviRaB_hJpUl-gbItdjwXrDETacQnH1xPaCMj8m1I3zXd3YrdCaCq3RhqSZMLJAq8WEBblGPw

第二步:修改令牌有效时间

打开ruoyi项目,找到token配置,修改令牌有效时间,改为久一点。

解决uniapp/小程序访问Ruoyi框架报错401,认证失败,无法访问系统资源(已解决)_若依 认证失败,无法访问系统资源

图6 Token配置

第三步:Uni-app请求添加请求头(令牌)

在Uni-app请求方法里面,添加请求头header,里面加入令牌参数。(一般来说,把获取到的令牌和请求方法代码,扔给AI,让他帮你加入请求头完善该请求方法即可实现)

 getgames() { const requestTask = uni.request({ url: \'http://193.112.157.48:8080/system/games/list\', header: { \'Authorization\': \'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjEwYjc3MWQ3LTJkM2UtNGI3MS1hMTIyLTdkM2Q5MDU1MjExNiJ9.z3CpkE2a1wHPUWq-Mgm28zuKEMjYWUK3nytiq6I3DS6Ye8HowFrBpHQeqW2e24LaZ9LMJE4HheguU_djcTo4Xw\' // 你的完整token }, success: (res) => { // 改用箭头函数保持this指向 if(res.statusCode === 200 && res.data.code === 200) { this.gameslist = res.data.rows; console.log(\'数据加载成功:\', this.gameslist); } } }); },

四、测试结果

(1)PostMan接口测试成功获取数据

解决uniapp/小程序访问Ruoyi框架报错401,认证失败,无法访问系统资源(已解决)_若依 认证失败,无法访问系统资源

图7 PostMan测试图

 (2)Uni-app页面测试成功获取数据

解决uniapp/小程序访问Ruoyi框架报错401,认证失败,无法访问系统资源(已解决)_若依 认证失败,无法访问系统资源

图8 Uni-app请求头数据

解决uniapp/小程序访问Ruoyi框架报错401,认证失败,无法访问系统资源(已解决)_若依 认证失败,无法访问系统资源

图8 Uni-app请求结果