captcha.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. const {
  2. ERROR
  3. } = require('../../common/error')
  4. async function getNeedCaptcha ({
  5. uid,
  6. username,
  7. mobile,
  8. email,
  9. type = 'login',
  10. limitDuration = 7200000, // 两小时
  11. limitTimes = 3 // 记录次数
  12. } = {}) {
  13. const db = uniCloud.database()
  14. const dbCmd = db.command
  15. // 当用户最近“2小时内(limitDuration)”登录失败达到3次(limitTimes)时。要求用户提交验证码
  16. const now = Date.now()
  17. const uniIdLogCollection = db.collection('uni-id-log')
  18. const userIdentifier = {
  19. user_id: uid,
  20. username,
  21. mobile,
  22. email
  23. }
  24. let totalKey = 0; let deleteKey = 0
  25. for (const key in userIdentifier) {
  26. totalKey++
  27. if (!userIdentifier[key] || typeof userIdentifier[key] !== 'string') {
  28. deleteKey++
  29. delete userIdentifier[key]
  30. }
  31. }
  32. if (deleteKey === totalKey) {
  33. throw new Error('System error') // 正常情况下不会进入此条件,但是考虑到后续会有其他开发者修改此云对象,在此处做一个判断
  34. }
  35. const {
  36. data: recentRecord
  37. } = await uniIdLogCollection.where({
  38. ip: this.getClientInfo().clientIP,
  39. ...userIdentifier,
  40. type,
  41. create_date: dbCmd.gt(now - limitDuration)
  42. })
  43. .orderBy('create_date', 'desc')
  44. .limit(limitTimes)
  45. .get()
  46. return recentRecord.length === limitTimes && recentRecord.every(item => item.state === 0)
  47. }
  48. async function verifyCaptcha (params = {}) {
  49. const {
  50. captcha,
  51. scene
  52. } = params
  53. if (!captcha) {
  54. throw {
  55. errCode: ERROR.CAPTCHA_REQUIRED
  56. }
  57. }
  58. const payload = await this.uniCaptcha.verify({
  59. deviceId: this.getClientInfo().deviceId,
  60. captcha,
  61. scene
  62. })
  63. if (payload.errCode) {
  64. throw payload
  65. }
  66. }
  67. module.exports = {
  68. getNeedCaptcha,
  69. verifyCaptcha
  70. }