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

L
123  
linju 已提交
17
	//防止黑客恶意破解登陆,连续登陆失败一定次数后,需要用户提供验证码
DCloud_JSON's avatar
DCloud_JSON 已提交
18
	const getNeedCaptcha = async () => {
L
123  
linju 已提交
19
		//当用户最近“2小时内(recordDate)”登陆失败达到2次(recordSize)时。要求用户提交验证码
DCloud_JSON's avatar
DCloud_JSON 已提交
20 21 22
		const now = Date.now(),
			recordDate = 120 * 60 * 1000,
			recordSize = 2;
L
123  
linju 已提交
23 24 25 26 27 28 29 30 31 32 33
		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 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46

	//注册成功后为用户执行相关操作,如创建该用户的积分表等
	function registerSuccess(uid) {
		await db.collection('uni-id-scores').add({
			user_id: uid,
			score: 1,
			type: 1,
			balance: 1,
			comment: "",
			create_date: Date.now()
		})
	}

L
123  
linju 已提交
47
	//设置某些模块不需要token(也就是登陆成功后)才能操作,如果需要token就获取当前操作账户的uid
L
123  
linju 已提交
48
	let noCheckAction = [
DCloud_JSON's avatar
DCloud_JSON 已提交
49 50 51 52 53
		'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 已提交
54 55
	console.log(event.action);
	if (!noCheckAction.includes(event.action)) {
L
123  
linju 已提交
56 57 58 59 60
		if (!event.uniIdToken) {
			return {
				code: 403,
				msg: '缺少token'
			}
DCloud_JSON's avatar
DCloud_JSON 已提交
61
		}
L
123  
linju 已提交
62
		payload = await uniID.checkToken(event.uniIdToken)
L
123  
linju 已提交
63 64 65 66 67
		if (payload.code && payload.code > 0) {
			return payload
		}
		params.uid = payload.uid
	}
DCloud_JSON's avatar
DCloud_JSON 已提交
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93


	//记录成功登陆的日志
	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
			})

		return uniIdLogCollection.add(logData)
	}


L
123  
linju 已提交
94 95 96

	let res = {}
	switch (event.action) {
DCloud_JSON's avatar
DCloud_JSON 已提交
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
		case 'register':
			let {
				username, password, gender, nickname
			} = 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,
				gender,
				nickname,
				password
			});
			if (res.code === 0) {
				registerSuccess(res.uid)
			}
L
123  
linju 已提交
123 124 125 126
			break;
		case 'login':
			let passed = false;
			let needCaptcha = await getNeedCaptcha();
DCloud_JSON's avatar
DCloud_JSON 已提交
127

L
123  
linju 已提交
128 129 130 131
			if (needCaptcha) {
				res = await uniCaptcha.verify(params)
				if (res.code === 0) passed = true;
			}
DCloud_JSON's avatar
DCloud_JSON 已提交
132

L
123  
linju 已提交
133
			if (!needCaptcha || passed) {
DCloud_JSON's avatar
DCloud_JSON 已提交
134 135 136
				res = await uniID.login({
					...params,
					queryField: ['username', 'email', 'mobile']
L
123  
linju 已提交
137
				});
L
123  
linju 已提交
138
				await loginLog(res);
DCloud_JSON's avatar
DCloud_JSON 已提交
139 140 141 142
				if (res.code == 0 && res.type == 'register') {
					registerSuccess(res.uid)
				}

L
123  
linju 已提交
143 144
				needCaptcha = await getNeedCaptcha();
			}
DCloud_JSON's avatar
DCloud_JSON 已提交
145

L
123  
linju 已提交
146
			res.needCaptcha = needCaptcha;
DCloud_JSON's avatar
DCloud_JSON 已提交
147 148 149 150 151 152
			break;
		case 'login_by_weixin':
			res = await uniID.loginByWeixin(params);
			await uniID.updateUser({
				uid: res.uid,
				username: "微信用户"
L
123  
linju 已提交
153
			});
DCloud_JSON's avatar
DCloud_JSON 已提交
154 155 156 157 158 159 160
			if (res.code == 0 && res.type == 'register') {
				registerSuccess(res.uid)
			}
			res.userInfo.username = "微信用户"
			loginLog(res)
			break;
		case 'login_by_univerify':
L
123  
linju 已提交
161
			res = await uniID.loginByUniverify(params)
DCloud_JSON's avatar
DCloud_JSON 已提交
162 163 164 165 166
			if (res.code == 0 && res.type == 'register') {
				registerSuccess(res.uid)
			}
			break;
		case 'login_by_apple':
L
123  
linju 已提交
167
			res = await uniID.loginByApple(params)
DCloud_JSON's avatar
DCloud_JSON 已提交
168 169 170 171
			if (res.code == 0 && res.type == 'register') {
				registerSuccess(res.uid)
			}
			loginLog(res)
L
123  
linju 已提交
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
			break;
		case 'checkToken':
			res = await uniID.checkToken(event.uniIdToken);
			break;
		case 'logout':
			res = await uniID.logout(event.uniIdToken)
			break;
		case 'sendSmsCode':
			// 简单限制一下客户端调用频率
			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 已提交
191
			const templateId = '11753' // 替换为自己申请的模板id
L
123  
linju 已提交
192 193 194 195 196 197 198 199 200 201 202 203 204
			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
DCloud_JSON's avatar
DCloud_JSON 已提交
205 206 207 208
			})
			if (res.code == 0 && res.type == 'register') {
				registerSuccess(res.uid)
			}
L
123  
linju 已提交
209 210 211 212 213 214 215 216 217 218 219 220 221 222
			break;
		case 'loginBySms':
			if (!params.code) {
				return {
					code: 500,
					msg: '请填写验证码'
				}
			}
			if (!/^1\d{10}$/.test(params.mobile)) {
				return {
					code: 500,
					msg: '手机号码填写错误'
				}
			}
DCloud_JSON's avatar
DCloud_JSON 已提交
223 224 225 226
			res = await uniID.loginBySms(params)
			if (res.code == 0 && res.type == 'register') {
				registerSuccess(res.uid)
			}
L
123  
linju 已提交
227 228 229 230 231 232 233 234 235 236 237 238
			loginLog(res)
			break;
		case 'inviteLogin':
			if (!params.code) {
				return {
					code: 500,
					msg: '请填写验证码'
				}
			}
			res = await uniID.loginBySms({
				...params,
				type: 'register'
DCloud_JSON's avatar
DCloud_JSON 已提交
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
			})
			if (res.code == 0 && res.type == 'register') {
				registerSuccess(res.uid)
			}
			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 已提交
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
			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 已提交
292
			break;
L
123  
linju 已提交
293 294 295 296 297 298 299 300 301 302
		default:
			res = {
				code: 403,
				msg: '非法访问'
			}
			break;
	}

	//返回数据给客户端
	return res
芊里 已提交
303
};