diff --git a/src/pages/user/login.vue b/src/pages/user/login.vue index b16e660..545c1af 100644 --- a/src/pages/user/login.vue +++ b/src/pages/user/login.vue @@ -36,7 +36,8 @@ const doSubmit = async () => { scope: "server", }) if (res.code != 0) { - uni.showToast({ title: res.msg + ",登录失败,请重新登录", icon: "error" }) + const errText = res.msg || res.error_description || res.error || "登录失败" + uni.showToast({ title: errText + ",请重试", icon: "error" }) return } uni.setStorageSync(tokenKey, res.data) diff --git a/src/sheep/api/user.ts b/src/sheep/api/user.ts index 4cfb042..833a576 100644 --- a/src/sheep/api/user.ts +++ b/src/sheep/api/user.ts @@ -49,27 +49,34 @@ export default { // params, // }), - // 账号密码登录 + // 账号密码登录:与 pjcloud-ui 一致——非密码字段走 query,password 单独 x-www-form-urlencoded body(Spring 会合并参数) login: (params: any) => { const { username, password, randomStr, code, grant_type, scope } = params - const encPassword = encryption(password, import.meta.env.VITE_PWD_ENC_KEY) + const encKey = import.meta.env.VITE_PWD_ENC_KEY + // 未配置密钥时只能明文(需与 auth 客户端 encFlag 一致);或显式 VITE_OAUTH_PWD_PLAIN=true + const plainPwd = import.meta.env.VITE_OAUTH_PWD_PLAIN === "true" || !encKey + const pwdForWire = plainPwd ? password : encryption(password, encKey) + const query: Record = { + username: username ?? "", + grant_type: grant_type ?? "", + scope: scope ?? "", + } + if (randomStr != null && String(randomStr) !== "") { + query.randomStr = String(randomStr) + } + if (code != null && String(code) !== "") { + query.code = String(code) + } return request({ url: `/auth/oauth2/token`, method: "POST", - params: { - username, - password, - randomStr, - code, - grant_type, - scope, - }, - data: { password }, + params: query, + data: `password=${encodeURIComponent(pwdForWire)}`, header: { skipToken: true, Authorization: BASIC_AUTH, - "content-type": "application/x-www-form-urlencoded", + "Content-Type": "application/x-www-form-urlencoded", }, }) }, diff --git a/src/sheep/utils/request.ts b/src/sheep/utils/request.ts index a8fdb28..ccc8178 100644 --- a/src/sheep/utils/request.ts +++ b/src/sheep/utils/request.ts @@ -70,8 +70,8 @@ https.interceptors.request.use(async (config) => { config_header["TENANT-ID"] = "1" if (import.meta.env.VITE_IS_TOC === "true") config_header["CLIENT-TOC"] = "Y" - // 判断是否需要设置认证头 - if (!SKIP_AUTH_URLS.some((url) => config.url?.startsWith(url))) { + // 判断是否需要设置认证头(url 可能是完整地址,故用 includes) + if (!SKIP_AUTH_URLS.some((url) => (config.url || "").includes(url))) { if (!isEmpty(tokenStorage)) { // token存在,检查是否过期 if (isTokenExpires(tokenStorage)) { @@ -101,13 +101,17 @@ https.interceptors.request.use(async (config) => { // 响应拦截器 https.interceptors.response.use( async (response) => { - // 账号密码登录响应结果特殊处理 - if (response.config.url === "/auth/oauth2/token") { - return Promise.resolve({ - code: 0, - data: response.data, - msg: null, - }) + // 账号密码登录:OAuth2 成功体无 code 字段,需包一层;url 可能是带 base 的完整路径 + const reqUrl = response.config?.url || "" + if (reqUrl.includes("/auth/oauth2/token")) { + const d = response.data + if (d && (d.access_token || d.accessToken?.tokenValue)) { + return Promise.resolve({ + code: 0, + data: d, + msg: null, + }) + } } return Promise.resolve(response.data)