解决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);
			}
			});
		}
		}
	}

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

 

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

 

二、问题根源剖析

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

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

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

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

图3 请求头含有Authorization令牌

图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<HttpSecurity>.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方法,均可以找到令牌。

图5 获取Authorization令牌

Authorization:

Bearer eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjQ4YTVlNGI5LTVhMzctNGYwNi05MTE3LTVkY2YyZTIwNDU2NiJ9.E5Yp1D3QcIfX3JviRaB_hJpUl-gbItdjwXrDETacQnH1xPaCMj8m1I3zXd3YrdCaCq3RhqSZMLJAq8WEBblGPw

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

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

图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接口测试成功获取数据

图7 PostMan测试图

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

图8 Uni-app请求头数据

图8 Uni-app请求结果

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WEICHENG__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值