uni-app项目转为H5项目 session一直变化导致登录不了

uni-app项目转为H5项目 session一直变化导致登录不了

bug描述:

uni-app项目转为H5项目时,内置浏览器调式,调用登录接口,response-header的session与获取验证码接口时获取的session不一致,导致虽然输入正确的验证码,登录接口仍会报验证错误,且点击验证码刷新时,每次接口的session都会变化,鉴权失败!

字段
产品分类 uniapp/H5
PC开发环境操作系统 Windows
PC开发环境操作系统版本号 w11
HBuilderX类型 正式
HBuilderX版本号 3.3.5
浏览器平台 Chrome
浏览器版本 83.0.4103.97(正式版本) (32 位)
项目创建方式 HBuilderX

示例代码:

const Request = (url, method = 'GET', params, contentType = 1) => {    
    let token = uni.getStorageSync('token')    
    let cookie = uni.getStorageSync('cookie')    
    // console.log(state)    
    let header = {    
        'Content-Type': contentType === 1 ? 'application/json' : 'application/x-www-form-urlencoded',    
        'Set-Cookie': token,    
        // 'Cookie': token    
    }    
    if (method == 'GET') {    
        url = url + formatGetUri(params)    
    }    
    // console.log(url)    
    return new Promise((resolve, reject) => {    
        uni.request({    
            url:baseUrl + url,    
            data: method == 'GET' ? {} : params,    
            method: method,    
            header: header,    
            timeout: 1000000,    
            success: (res) => {    
                 // console.log(res)    
                 store.dispatch('setErrState',true)    
                store.dispatch('setBtnLoading',false)    
                if (res.statusCode==200) {    
                    if(res.data.success){    
                        resolve(res.data.data)    
                    }else{    
                        if(res.data.errorMessage||res.data.message){    
                            uni.showToast({    
                                icon: 'none',    
                                title: res.data.errorMessage||res.data.message    
                            });    
                        }    
                        resolve(res.data)    
                        store.dispatch('setErrState',false)    
                        store.dispatch('log', {    
                            url: url,    
                            time: new Date(),    
                            res    
                        })    
                    }    

                } else {    
                    store.dispatch('log', {    
                        url: url,    
                        time: new Date(),    
                        res    
                    })    
                    if(res.data.resultCode=='A00003'){    
                        uni.setStorageSync('token','')    
                        utils.router('login',null,3)    
                    }else{    
                        uni.showToast({    
                            icon: 'none',    
                            title: '服务异常,请稍后再试'    
                        });    
                    }    
                }    
            },    
            fail: (err) => {    
                console.log('request fail', err)    
                store.dispatch('setBtnLoading',false)    
                reject(err)    
                uni.showToast({    
                    icon: 'none',    
                    title: '服务连接异常,请稍后再试'    
                });    
            }    
        })    
    })    
}  

操作步骤:

getCode: function () {  
      // 验证码地址  
            //this.codeImg=this.$utils.getWebBaseUrl()+'/web-api/randomPicture.action?d=' + +new Date()  
             this.codeImg='http://localhost:8080/baseApi/web-api/randomPicture.action?d=' + +new Date()  
              console.log(this.codeImg)  
        },

更多关于uni-app项目转为H5项目 session一直变化导致登录不了的实战教程也可以访问 https://www.itying.com/category-93-b0.html

7 回复

首先,登录之前的话,是不是代表session是不存在的,那么,你请求验证码接口是不需要带session的. 当登录成功的时候才需要保存session

更多关于uni-app项目转为H5项目 session一直变化导致登录不了的实战教程也可以访问 https://www.itying.com/category-93-b0.html


你的意思是在 chrome环境下 session一直变化?

在内置浏览器和chrome环境下,没调用一次登录接口,session就会变化一次

看你在好几个地方发了帖子。我简单帮你梳理一下。为什么发了这么多帖子没人回复你。
首先
登录接口,response-header的session与获取验证码接口时获取的session不一致 session 本身是服务器端管理的会话标识。 实现方式有很多包括tomcat提供实现,servlet提供实现,或者基于cookie来实现,甚至你们自己的业务服务器都能自己实现一套。
session错乱,本身就是个你业务上的,服务端上的现象。 这个问题跟前端是没有直接关系。跟uni的框架是没有直接关系。
导致这个问题的可能非常多。 你不把问题阐述清楚。别人也很难,也没有耐心 帮你解决你的业务问题。
第二。
看你发的代码里面,唯一可能与之相关的是
let token = uni.getStorageSync(‘token’)
let cookie = uni.getStorageSync(‘cookie’)
除非你提出的问题是,明确阐述我们提供的api 有什么不符合文档描述的地方。 我们才能帮你处理

项目发布为H5时出现的这个问题,运行到手机或模拟器时调试没有session一直变化的问题,是不是项目发布为H5时有什么限制之类的

我感觉吧,你可能是对这个东西有什么误解,因为,还是那句话,一般来讲在没登录之前,是不需要存储什么session的,你只是在登录之前,当然你在登录之后,token过期了,那也情有可原,但是你既然有token了,那么在你请求的时候,吧token带给后端,让他去处理就好了,还有,为什么你获取验证码的接口都需要带着token呢,这本身逻辑不通.还有就是你在刷新验证码的时候,不需要动别的地方,只需要请求一个图片就好了 也可能我实现的方式跟你不一样,仅作为参考

在H5环境下,浏览器会自动管理Cookie(包括Session ID),你代码中手动设置'Set-Cookie': token作为请求头是错误的(Set-Cookie是响应头,不应出现在请求中),而且注释掉的'Cookie': token也不应该手动设置,因为这会与浏览器自动管理的Cookie冲突。

根本原因

  • 每个请求未携带正确的Session Cookie(因为手动管理方式导致浏览器未自动发送),服务端为每个请求都创建了新会话。
  • 验证码和登录接口的Session不一致,所以验证码校验失败。

修正方法

  1. 删除所有手动设置的header中的'Set-Cookie''Cookie'字段,让浏览器自动处理Cookie。
  2. uni.request配置中添加withCredentials: true(H5平台需要,用于跨域请求时携带Cookie)。
  3. 确保后端正确返回Set-Cookie(含HttpOnly等属性不影响),且响应头Access-Control-Allow-Credentials: trueAccess-Control-Allow-Origin不能为*(需指定具体域名)。

修改后的请求函数核心示例(仅H5):

uni.request({
    url: baseUrl + url,
    data: method == 'GET' ? {} : params,
    method: method,
    header: {
        'Content-Type': contentType === 1 ? 'application/json' : 'application/x-www-form-urlencoded'
    },
    withCredentials: true, // 关键:携带Cookie
    success: (res) => { ... }
});
回到顶部