b1996f3cd1
- Sanitize page_path before router.push (H5) to prevent cross-user login via shared link - onShareAppMessage: remove unionid/openid/status and related query keys from shared path - main.ts: fix login(to.query.toString()) bug; when already logged in, strip foreign unionid from URL instead of logout Made-with: Cursor
278 lines
10 KiB
JavaScript
278 lines
10 KiB
JavaScript
//index.js
|
|
//获取应用实例
|
|
const app = getApp();
|
|
const {
|
|
warn,
|
|
request
|
|
} = require("../../utils/util.js");
|
|
const log = require("../../utils/log.js");
|
|
const { shortTail, logWeapp } = require("../../utils/htyWeappLog.js");
|
|
|
|
// 0 => 已注册用户 1 => 新用户(已授权) 2 => 匿名用户(拒绝授权)
|
|
// keep synchronous with types.ts file in htymusic
|
|
const UserStates = {
|
|
Registered: 2,
|
|
Authorized: 1,
|
|
Anonymous: 0
|
|
}
|
|
|
|
const logInstance = (instance, label) => {
|
|
Object.entries(instance.data).forEach(([key, value]) => {
|
|
log.info(label + key, value);
|
|
});
|
|
};
|
|
|
|
const statusName = (status) => {
|
|
if (status === UserStates.Registered) return 'Registered'
|
|
if (status === UserStates.Authorized) return 'Authorized'
|
|
if (status === UserStates.Anonymous) return 'Anonymous'
|
|
return String(status)
|
|
}
|
|
|
|
const setUrl = (instance, status) => {
|
|
logInstance(instance, 'set url');
|
|
logWeapp('setUrl', { status: statusName(status), unionidTail: shortTail(instance.data.unionid), ready: true })
|
|
let { unionid, meta, openid, tongzhi_id, page_path } = instance.data;
|
|
let params = [
|
|
'unionid=' + unionid, "openid=" + openid, "ts=" + app.globalData.timestamp, 'status=' + status
|
|
];
|
|
if (meta) {
|
|
let {nickName, avatarUrl} = meta;
|
|
params.push('nickName=' + nickName, 'avatarUrl=' + avatarUrl);
|
|
}
|
|
// add scene value to check if nav by wx message
|
|
params.push("scene=" + app.globalData.scene)
|
|
if (tongzhi_id) {
|
|
params.push('tongzhi_id=' + tongzhi_id);
|
|
}
|
|
if (page_path) {
|
|
params.push('page_path=' + page_path);
|
|
}
|
|
log.info('set-url', params.join("&"))
|
|
instance.setData({
|
|
ready: true,
|
|
url: `${app.globalData.server}?${params.join('&')}`
|
|
})
|
|
}
|
|
|
|
const login_with_unionid = (instance) => {
|
|
wx.showLoading();
|
|
|
|
let unionid = wx.getStorageSync('unionid')
|
|
|
|
logWeapp('login_with_unionid_start', { unionidTail: shortTail(unionid) })
|
|
|
|
wx.removeStorageSync('token')
|
|
request({
|
|
url: `${app.globalData.api}/api/v1/uc/login2_with_unionid`,
|
|
method: 'GET',
|
|
header: { HtyHost: app.globalData.domain, unionid },
|
|
success: function (res) {
|
|
var statusCode = res.statusCode
|
|
var body = res.data || {}
|
|
var r = body.r
|
|
var d = body.d
|
|
var e = body.e
|
|
if (r) {
|
|
logWeapp('login_with_unionid_ok', {
|
|
httpStatus: statusCode,
|
|
tokenLen: typeof d === 'string' ? d.length : 0,
|
|
unionidTail: shortTail(unionid)
|
|
})
|
|
wx.setStorageSync('token', d)
|
|
instance.setData({token: d}, () => setUrl(instance, UserStates.Registered))
|
|
} else {
|
|
var meta = wx.getStorageSync('user-meta');
|
|
logWeapp('login_with_unionid_fail', {
|
|
httpStatus: statusCode,
|
|
r: r,
|
|
e: String(e || '').slice(0, 300),
|
|
hasMeta: !!meta,
|
|
unionidTail: shortTail(unionid)
|
|
})
|
|
if (meta) {
|
|
instance.setData({meta}, () => setUrl(instance, UserStates.Authorized))
|
|
} else {
|
|
logWeapp('login_with_unionid_stuck_native', {
|
|
reason: 'r_false_no_meta',
|
|
hint: 'shows_start_button_until_getUserProfile'
|
|
})
|
|
}
|
|
}
|
|
},
|
|
fail: function (err) {
|
|
logWeapp('login_with_unionid_request_fail', { err: String(err && err.errMsg ? err.errMsg : err).slice(0, 300) })
|
|
},
|
|
complete: function() {
|
|
wx.hideLoading()
|
|
}
|
|
})
|
|
}
|
|
|
|
const login = (instance) => {
|
|
logInstance(instance, "login start -> ")
|
|
wx.showLoading();
|
|
wx.removeStorageSync('unionid')
|
|
wx.login({
|
|
success: function ({ code, errMsg }) {
|
|
log.info("login succeed -> code: ", code);
|
|
if (code) {
|
|
log.info('wx login code...', code);
|
|
request({
|
|
url: `${app.globalData.api}/api/v1/uc/wx_login`,
|
|
method: 'POST',
|
|
header: { 'HtyHost': app.globalData.domain },
|
|
data: { code },
|
|
success: function (res) {
|
|
var statusCode = res.statusCode
|
|
var body = res.data || {}
|
|
var r = body.r
|
|
var d = body.d
|
|
var e = body.e
|
|
if (r) {
|
|
let { unionid, openid } = d;
|
|
logWeapp('wx_login_ok', {
|
|
httpStatus: statusCode,
|
|
unionidTail: shortTail(unionid),
|
|
openidTail: shortTail(openid)
|
|
})
|
|
if (unionid) {
|
|
wx.setStorageSync("unionid", unionid);
|
|
wx.setStorageSync("openid", openid);
|
|
instance.setData({unionid, openid}, () => login_with_unionid(instance));
|
|
} else {
|
|
warn("微信登录失败!")
|
|
logWeapp('wx_login_ok_but_no_unionid', { httpStatus: statusCode })
|
|
}
|
|
} else {
|
|
warn(e);
|
|
logWeapp('wx_login_fail', { httpStatus: statusCode, e: String(e || '').slice(0, 300) });
|
|
}
|
|
},
|
|
fail: function (err) {
|
|
logWeapp('wx_login_request_fail', { err: String(err && err.errMsg ? err.errMsg : err).slice(0, 300) })
|
|
},
|
|
});
|
|
} else {
|
|
log.info('获取用户登录态失败!' + errMsg);
|
|
}
|
|
},
|
|
complete: function() {
|
|
wx.hideLoading()
|
|
}
|
|
});
|
|
};
|
|
|
|
const init = (instance, {unionid, token}) => {
|
|
logInstance(instance, "init -> ");
|
|
var tokenLen = token ? String(token).length : 0
|
|
if (unionid) {
|
|
if (token) {
|
|
logWeapp('init_branch', {
|
|
branch: 'unionid_and_token_skip_api',
|
|
unionidTail: shortTail(unionid),
|
|
tokenLen: tokenLen,
|
|
note: 'webview_gets_status_Registered_without_validating_token_here'
|
|
})
|
|
setUrl(instance, UserStates.Registered)
|
|
} else {
|
|
logWeapp('init_branch', { branch: 'unionid_no_token_login_with_unionid', unionidTail: shortTail(unionid) })
|
|
login_with_unionid(instance)
|
|
}
|
|
} else {
|
|
logWeapp('init_branch', { branch: 'no_unionid_wx_login' })
|
|
login(instance)
|
|
}
|
|
}
|
|
|
|
Page({
|
|
data: {
|
|
url: '', ready: false, timestamp: 0, meta: null,
|
|
token: '', openid: '', tongzhi_id: '', page_path: ''
|
|
},
|
|
getUserProfile() {
|
|
let instance = this;
|
|
logWeapp('getUserProfile_start', {})
|
|
wx.getUserProfile({
|
|
desc: '请求获取您的微信信息',
|
|
success: function({userInfo}) {
|
|
wx.setStorageSync('user-meta', userInfo);
|
|
logWeapp('getUserProfile_ok', { nickLen: userInfo && userInfo.nickName ? String(userInfo.nickName).length : 0 })
|
|
instance.setData({meta: userInfo}, () => setUrl(instance, UserStates.Authorized))
|
|
},
|
|
fail: function(err) {
|
|
console.log('get profile error...', err);
|
|
logWeapp('getUserProfile_fail', { err: String(err && err.errMsg ? err.errMsg : err).slice(0, 200) })
|
|
setUrl(instance, UserStates.Anonymous)
|
|
}
|
|
});
|
|
|
|
},
|
|
onShareAppMessage({from, target, webViewUrl}) {
|
|
log.info("share", [from, target, webViewUrl].join(" | "))
|
|
let pathname = webViewUrl.replace(app.globalData.server, '');
|
|
// 分享勿带 WebView 入口里的 unionid/openid/status 等,避免接收方串号
|
|
if (pathname && pathname !== '/') {
|
|
try {
|
|
const q = pathname.indexOf('?')
|
|
let base = pathname
|
|
let search = ''
|
|
if (q === 0) {
|
|
base = '/'
|
|
search = pathname.slice(1)
|
|
} else if (q > 0) {
|
|
base = pathname.slice(0, q) || '/'
|
|
search = pathname.slice(q + 1)
|
|
}
|
|
if (search) {
|
|
const sp = new URLSearchParams(search)
|
|
;['unionid', 'openid', 'status', 'nickName', 'avatarUrl', 'ts', 'scene'].forEach((k) => sp.delete(k))
|
|
const rest = sp.toString()
|
|
pathname = rest ? `${base}?${rest}` : (base || '/')
|
|
}
|
|
} catch (e) {
|
|
log.info('share strip query skip', e)
|
|
}
|
|
pathname = pathname === '/' ? '/' : encodeURIComponent(pathname)
|
|
}
|
|
const promise = new Promise(resolve => {
|
|
setTimeout(() => {
|
|
resolve({
|
|
title: '慧添翼课后辅导系统',
|
|
path: `/pages/index/index?page_path=${pathname}`
|
|
})
|
|
}, 2000)
|
|
})
|
|
return {
|
|
title: '慧添翼课后辅导系统',
|
|
path: `/pages/index/index?page_path=${pathname}`,
|
|
promise
|
|
}
|
|
},
|
|
onLoad (options) {
|
|
log.info('load-options', options)
|
|
this.setData({
|
|
tongzhi_id: options.hty_tongzhi_id || "",
|
|
page_path: options.page_path
|
|
})
|
|
},
|
|
onShow() {
|
|
logInstance(this, 'on show')
|
|
let { unionid, openid, meta, token } = this.data;
|
|
unionid = unionid || wx.getStorageSync("unionid");
|
|
openid = openid || wx.getStorageSync('openid');
|
|
meta = meta || wx.getStorageSync('user-meta');
|
|
token = token || wx.getStorageSync('token');
|
|
logWeapp('onShow_storage', {
|
|
unionidTail: shortTail(unionid),
|
|
openidTail: shortTail(openid),
|
|
tokenLen: token ? String(token).length : 0,
|
|
hasMeta: !!meta,
|
|
readyBefore: this.data.ready,
|
|
scene: app.globalData.scene,
|
|
page_path: this.data.page_path ? 'yes' : ''
|
|
})
|
|
this.setData({unionid, openid, meta, token}, () => init(this, this.data));
|
|
}
|
|
});
|