index.js 8.1 KB
Newer Older
L
123  
linju 已提交
1
'use strict';
L
123  
linju 已提交
2
let uniID = require('uni-id')
L
123  
linju 已提交
3
const uniCaptcha = require('uni-captcha')
4 5 6 7
const createConfig = require('uni-config-center')
const uniIdConfig = createConfig({
	pluginId: 'uni-id'
})._config
L
123  
linju 已提交
8 9
const db = uniCloud.database()
const dbCmd = db.command
DCloud_JSON's avatar
DCloud_JSON 已提交
10 11 12 13 14 15 16 17 18 19 20
exports.main = async (event, context) => {
	/**
	 * UNI_WYQ:这里的uniID换成新的,保证多人访问不会冲突
	 */
	uniID = uniID.createInstance({
		context
	})
	//event为客户端上传的参数
	console.log('event : ' + JSON.stringify(event))
	let params = event.params || {}

DCloud_JSON's avatar
DCloud_JSON 已提交
21
	//防止黑客恶意破解登录,连续登录失败一定次数后,需要用户提供验证码
DCloud_JSON's avatar
DCloud_JSON 已提交
22
	const getNeedCaptcha = async () => {
DCloud_JSON's avatar
DCloud_JSON 已提交
23
		//当用户最近“2小时内(recordDate)”登录失败达到2次(recordSize)时。要求用户提交验证码
DCloud_JSON's avatar
DCloud_JSON 已提交
24 25 26
		const now = Date.now(),
			recordDate = 120 * 60 * 1000,
			recordSize = 2;
L
123  
linju 已提交
27 28 29 30 31 32 33 34 35 36 37
		const uniIdLogCollection = db.collection('uni-id-log')
		let recentRecord = await uniIdLogCollection.where({
				deviceId: params.deviceId || context.DEVICEID,
				create_date: dbCmd.gt(now - recordDate),
				type: 'login'
			})
			.orderBy('create_date', 'desc')
			.limit(recordSize)
			.get();
		return recentRecord.data.filter(item => item.state === 0).length === recordSize;
	}
DCloud_JSON's avatar
DCloud_JSON 已提交
38

DCloud_JSON's avatar
DCloud_JSON 已提交
39
	//设置某些模块不需要token(也就是登录成功后)才能操作,如果需要token就获取当前操作账户的uid
L
123  
linju 已提交
40
	let noCheckAction = [
DCloud_JSON's avatar
DCloud_JSON 已提交
41 42 43 44 45
		'register', 'checkToken', 'login', 'logout', 'sendSmsCode',
		'createCaptcha', 'verifyCaptcha', 'refreshCaptcha', 'inviteLogin',
		'login_by_weixin', 'login_by_univerify', 'login_by_apple', 'loginBySms', 'resetPwdBySmsCode'
	]
	let payload;
L
123  
linju 已提交
46 47
	console.log(event.action);
	if (!noCheckAction.includes(event.action)) {
L
123  
linju 已提交
48 49 50 51 52
		if (!event.uniIdToken) {
			return {
				code: 403,
				msg: '缺少token'
			}
DCloud_JSON's avatar
DCloud_JSON 已提交
53
		}
L
123  
linju 已提交
54
		payload = await uniID.checkToken(event.uniIdToken)
L
123  
linju 已提交
55 56 57 58 59
		if (payload.code && payload.code > 0) {
			return payload
		}
		params.uid = payload.uid
	}
DCloud_JSON's avatar
DCloud_JSON 已提交
60

61 62 63 64 65 66 67 68 69 70 71
	//注册成功后为用户执行相关操作,如创建该用户的积分表等
	async function registerSuccess(uid) {
		await db.collection('uni-id-scores').add({
			user_id: uid,
			score: 1,
			type: 1,
			balance: 1,
			comment: "",
			create_date: Date.now()
		})
	}
DCloud_JSON's avatar
DCloud_JSON 已提交
72
	//记录成功登录的日志
DCloud_JSON's avatar
DCloud_JSON 已提交
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
	const loginLog = async (res = {}, type = 'login') => {
		const now = Date.now()
		const uniIdLogCollection = db.collection('uni-id-log')
		let logData = {
			deviceId: params.deviceId || context.DEVICEID,
			ip: params.ip || context.CLIENTIP,
			type,
			ua: context.CLIENTUA,
			create_date: now
		};

		Object.assign(logData,
			res.code === 0 ? {
				user_id: res.uid,
				state: 1
			} : {
				state: 0
			})
91 92
		if (res.type == 'register') {
			await registerSuccess(res.uid)
93 94
		}
		return await uniIdLogCollection.add(logData)
DCloud_JSON's avatar
DCloud_JSON 已提交
95 96 97
	}


L
123  
linju 已提交
98 99 100

	let res = {}
	switch (event.action) {
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
		case 'bind_mobile_by_univerify':
			let {
				appid, apiKey, apiSecret
			} = uniIdConfig.service.univerify
			let univerifyRes = await uniCloud.getPhoneNumber({
				provider: 'univerify',
				appid,
				apiKey,
				apiSecret,
				access_token: params.access_token,
				openid: params.openid
			})
			if (univerifyRes.code === 0) {
				res = await uniID.bindMobile({
					uid: params.uid,
					mobile: univerifyRes.phoneNumber
				})
				res.mobile = univerifyRes.phoneNumber
			}
			break;
		case 'bind_mobile_by_sms':
			console.log({
				uid: params.uid,
				mobile: params.mobile,
				code: params.code
			});
127 128 129 130
			res = await uniID.bindMobile({
				uid: params.uid,
				mobile: params.mobile,
				code: params.code
131
			})
DCloud_JSON's avatar
DCloud_JSON 已提交
132
			console.log(res);
133
			break;
DCloud_JSON's avatar
DCloud_JSON 已提交
134 135
		case 'register':
			let {
136
				username, password, nickname
DCloud_JSON's avatar
DCloud_JSON 已提交
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
			} = params
			if (/^1\d{10}$/.test(username)) {
				return {
					code: 401,
					msg: '用户名不能是手机号'
				}
			};
			if (/^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/.test(username)) {
				return {
					code: 401,
					msg: '用户名不能是邮箱'
				}
			}
			res = await uniID.register({
				username,
				password,
153
				nickname
DCloud_JSON's avatar
DCloud_JSON 已提交
154 155
			});
			if (res.code === 0) {
156
				await registerSuccess(res.uid)
DCloud_JSON's avatar
DCloud_JSON 已提交
157
			}
L
123  
linju 已提交
158 159 160 161
			break;
		case 'login':
			let passed = false;
			let needCaptcha = await getNeedCaptcha();
162
			console.log('needCaptcha',needCaptcha);
L
123  
linju 已提交
163
			if (needCaptcha) {
164
				res = await uniCaptcha.verify({...params,scene:'login'})
L
123  
linju 已提交
165 166
				if (res.code === 0) passed = true;
			}
DCloud_JSON's avatar
DCloud_JSON 已提交
167

L
123  
linju 已提交
168
			if (!needCaptcha || passed) {
DCloud_JSON's avatar
DCloud_JSON 已提交
169 170 171
				res = await uniID.login({
					...params,
					queryField: ['username', 'email', 'mobile']
L
123  
linju 已提交
172
				});
L
123  
linju 已提交
173 174 175
				await loginLog(res);
				needCaptcha = await getNeedCaptcha();
			}
DCloud_JSON's avatar
DCloud_JSON 已提交
176

L
123  
linju 已提交
177
			res.needCaptcha = needCaptcha;
DCloud_JSON's avatar
DCloud_JSON 已提交
178 179 180 181 182 183
			break;
		case 'login_by_weixin':
			res = await uniID.loginByWeixin(params);
			await uniID.updateUser({
				uid: res.uid,
				username: "微信用户"
184
			});
DCloud_JSON's avatar
DCloud_JSON 已提交
185
			res.userInfo.username = "微信用户"
186
			await loginLog(res)
DCloud_JSON's avatar
DCloud_JSON 已提交
187 188
			break;
		case 'login_by_univerify':
189
			res = await uniID.loginByuniverify(params)
190
			await loginLog(res)
DCloud_JSON's avatar
DCloud_JSON 已提交
191 192
			break;
		case 'login_by_apple':
193 194
			res = await uniID.loginByApple(params)
			await loginLog(res)
L
123  
linju 已提交
195 196 197 198 199 200 201
			break;
		case 'checkToken':
			res = await uniID.checkToken(event.uniIdToken);
			break;
		case 'logout':
			res = await uniID.logout(event.uniIdToken)
			break;
202
		case 'sendSmsCode':
203 204
			
			// 测试期间短信统一用 123456 正式项目删除即可
205 206 207 208 209 210
			return uniID.setVerifyCode({
				mobile: params.mobile,
				code:'123456',
				type: params.type
			})
		
211
		
L
123  
linju 已提交
212 213 214 215 216 217 218 219 220 221 222
			// 简单限制一下客户端调用频率
			const ipLimit = await db.collection('uni-verify').where({
				ip: context.CLIENTIP,
				created_at: dbCmd.gt(Date.now() - 60000)
			}).get()
			if (ipLimit.data.length > 0) {
				return {
					code: 429,
					msg: '请求过于频繁'
				}
			}
L
123  
linju 已提交
223
			const templateId = '11753' // 替换为自己申请的模板id
L
123  
linju 已提交
224 225 226 227 228 229 230 231 232 233 234 235 236
			if (!templateId) {
				return {
					code: 500,
					msg: 'sendSmsCode需要传入自己的templateId,参考https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=sendsmscode'
				}
			}
			const randomStr = '00000' + Math.floor(Math.random() * 1000000)
			const code = randomStr.substring(randomStr.length - 6)
			res = await uniID.sendSmsCode({
				mobile: params.mobile,
				code,
				type: params.type,
				templateId
237 238
			})
			await loginLog(res)
L
123  
linju 已提交
239 240 241 242 243 244 245 246 247 248 249 250 251 252
			break;
		case 'loginBySms':
			if (!params.code) {
				return {
					code: 500,
					msg: '请填写验证码'
				}
			}
			if (!/^1\d{10}$/.test(params.mobile)) {
				return {
					code: 500,
					msg: '手机号码填写错误'
				}
			}
253 254
			res = await uniID.loginBySms(params)
			await loginLog(res)
L
123  
linju 已提交
255 256 257 258 259 260 261 262 263 264 265
			break;
		case 'inviteLogin':
			if (!params.code) {
				return {
					code: 500,
					msg: '请填写验证码'
				}
			}
			res = await uniID.loginBySms({
				...params,
				type: 'register'
266
			})
DCloud_JSON's avatar
DCloud_JSON 已提交
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
			break;
		case 'resetPwdBySmsCode':
			if (!params.code) {
				return {
					code: 500,
					msg: '请填写验证码'
				}
			}
			if (!/^1\d{10}$/.test(params.mobile)) {
				return {
					code: 500,
					msg: '手机号码填写错误'
				}
			}
			let loginBySmsRes = await uniID.loginBySms(params)
			console.log(loginBySmsRes);
			if (loginBySmsRes.code === 0) {
				res = await uniID.resetPwd({
					password: params.password,
					"uid": loginBySmsRes.uid
				})
			} else {
				return loginBySmsRes
			}
L
123  
linju 已提交
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
			break;
		case 'getInviteCode':
			res = await uniID.getUserInfo({
				uid: params.uid,
				field: ['my_invite_code']
			})
			if (res.code === 0) {
				res.myInviteCode = res.userInfo.my_invite_code
				delete res.userInfo
			}
			break;
		case 'getInvitedUser':
			res = await uniID.getInvitedUser(params)
			break;
		case 'updatePwd':
			res = await uniID.updatePwd({
				uid: params.uid,
				...params
			})
			break;
		case 'createCaptcha':
			res = await uniCaptcha.create(params)
			break;
		case 'refreshCaptcha':
			res = await uniCaptcha.refresh(params)
DCloud_JSON's avatar
DCloud_JSON 已提交
316
			break;
L
123  
linju 已提交
317 318 319 320 321 322 323 324 325 326
		default:
			res = {
				code: 403,
				msg: '非法访问'
			}
			break;
	}

	//返回数据给客户端
	return res
327
};