【本文正在参与“100%有奖|我的Serverless 实战”征稿活动】,活动地址:
使用腾讯云SCF构建小型服务端并结合uni-app()小程序
我们这里手写了一个nodejs环境下的用户体系
使用了之前写的一个数据库连接插件dmhq-mysql-pool比较垃圾 凑合用
文档地址为 .md
也使用了md5 npm install js-md5
这里使用邮箱发送验证码
先在本地写好 再上传云函数
安装 npm install dmhsq-mysql-pool
新建一个文件db.js
const database = require("dmhsq-mysql-pool");
const configs = {host: 'xxxx',port: 'xxxx',user: 'xxxx',password: 'xxxx',database: "xxxx"
}
let user = new database(configs).table("user")
let codes = new database(configs).table("email")
ports = {user,codes
};
用户数据表名 user
验证码表 名email 由于只用到邮箱验证码
这里的user 和 pass 为STMP获取 在各大邮箱的设置可以找到
邮箱转发服务 npm install nodemailer
nodemailer文档
const nodemailer = require('nodemailer')const transporter = ateTransport({service: 'qq', // no need to set host or port etc.auth: {user: 'xxxxx@qq',pass: 'xxxxxxx'}
});const sendCode = async (email,code,time) => {let message = {from: "验证码<xxxxx@qq>",to: email,subject: "验证码服务",html: `<html><head><meta charset="utf-8"><title></title></head><body><div><p style="font-size: 20px;">欢迎您使用,您的验证码为 <span style="color: blue;font-size: 30px;font-weight: 800;">${code}</span> ,有效时间为${time/60}分钟, 请勿泄露并及时验证</p><div style="margin-top: 50px;"></div><p style="color: red;font-size: 25px;">请勿回复</p></div></body></html>`};await transporter.sendMail(message)return {code:0,msg:"邮件已发送,如果没有收到,请检查邮箱"}
}ports = {sendCode};
const {user,codes
} = require("./db.js");
const {sendCode
} = require("./email.js");
const md5 = require("js-md5")//注册模块
const sign = async (username, password) => {const dfp = passwordpassword = md5(password);let isH = await user.where({username}).get();if(isH.data.length>0){return {code: 5742,msg: "用户名已被占用",}}const _id = md5(Math.random().toString(36)).substr(0, 10);let res = await user.add({username,password,_id}).get();let rsp = {code: 5741,msg: "注册失败",}if (de == 0) {let userRes = await login(username, dfp);rsp = {code: 0,msg: "注册成功"}if (de == 0) {rsp.data = userRes.userInfo}}return rsp;
}//登陆模块
const login = async (username, password) => {password = md5(password)let res = await user.where({username,password}).get()if (!res.data.length) {return {code: 9001,msg: "用户名或者密码错误"}} else {let token = md5(md5(Math.random().toString(36)) + md5(Math.random().toString(36)));const tokenExpired = parseInt(Date.parse(new Date()).toString().substr(0, 10)) + 72000;const last_login_time = parseInt(Date.parse(new Date()).toString().substr(0, 10));let qres = await user.updata({token_expired: tokenExpired,token,last_login_time}).where({username}).get();if (de == 0) {return {code: 0,userInfo: {token,tokenExpired,username}}} else {return {code: 9002,msg: "登陆失败",data: qres}}}
}//邮箱发送模块
const sendEmailCode = async (email, type) => {const randomStr = '00000' + Math.floor(Math.random() * 1000000)const code = randomStr.substring(randomStr.length - 6);let time = 3600const check_time = parseInt(Date.parse(new Date()).toString().substr(0, 10)) + time;let res = {}res = await sendCode(email, code, time)if (de == 0) {await codes.add({email,code,check_time,state: 0,type}).get();} else {res = {code: 4046,msg: "发送失败"}}return res
}//验证码校验
const checkCode = async (email, code, type) => {let result = await codes.where({email,code,type}).sort({check_time: "DESC"}).get();let data = result.data;let res = {}if (data.length == 0) {res = {code: 4048,msg: "验证码错误"}} else {data = data[0]const check_times = parseInt(Date.parse(new Date()).toString().substr(0, 10));if (data.state == 0 & data.check_time > check_times) {await codes.updata({state: 1}).where({email}).get()res = {code: 0,msg: "验证通过"}} else if (data.check_time < check_times) {res = {code: 4044,msg: "验证码失效"}} else if (data.state == 1) {res = {code: 4045,msg: "验证码已经验证"}} else {res = {code: 4048,msg: "验证码错误"}}}return res;
}//邮箱绑定
const bind = async (username, email, code) => {const check_code = await checkCode(email, code, "bind");const check_user = await user.where({username,email}).get();let res = {}if (check_user.data.length > 0) {res = {code: 74174,msg: "用户已经绑定邮箱"}} else {if (de == 0) {const datas = await user.updata({email}).where({username}).get();if (de == 0) {res = {code: 0,msg: "绑定成功"}}}else{res = check_code}}return res;
}//邮箱解除绑定
const unbind = async (username, email, code) => {const check_code = await checkCode(email, code, "unbind");const check_user = await user.where({username,email}).get();let res = {}if (check_user.data.length == 0) {res = {code: 74175,msg: "用户还未绑定邮箱"}} else {if (de == 0) {const datas = await user.updata({email: ""}).where({username}).get();if (de == 0) {res = {code: 0,msg: "解除绑定成功"}}}else{res = check_code}}return res;
}//邮箱校检登录
const checkCodeLogin = async (email, code) => {const ress = await checkCode(email, code, "login")const isH = await user.where({email}).get();if(isH.data.length==0){return {code:9003,msg:"非法邮箱(邮箱未绑定用户)"}}if (de == 0) {let token = md5(md5(Math.random().toString(36)) + md5(Math.random().toString(36)));const tokenExpired = parseInt(Date.parse(new Date()).toString().substr(0, 10)) + 72000;const last_login_time = parseInt(Date.parse(new Date()).toString().substr(0, 10));let qres = await user.updata({token_expired: tokenExpired,token,last_login_time}).where({email}).get();if (de == 0) {res = {code: 0,userInfo: {token,tokenExpired,email}}} else {res = {code: 9002,msg: "登陆失败",data: qres}}}return res;
}//token校检
const checkToken = async (token) => {const reqs = await user.where({token}).get();let res = {}if (reqs.data.length > 0) {const userInfos = reqs.data[0]const check_time = ken_expired;const now_time = parseInt(Date.parse(new Date()).toString().substr(0, 10));if (check_time > now_time) {res = {code: 0,userInfo: {username: userInfos.username}}} else {res = {code: 7412,msg: "token过期"}}} else {res = {code: 7417,msg: "token非法"}}return res;
}ports = {sign,login,sendEmailCode,checkCode,bind,unbind,checkCodeLogin,checkToken
}
const userCenter = require("./user.js")index.main_handler = async (event, context) => {let noCheckAction = ['sign', 'checkToken', 'login', 'checkCode', 'loginByEmail', 'emailCode']let params = event.queryString;let res = {}const {action} = paramsif (noCheckAction.indexOf(action) === -1) {if (!ken) {res = {code: 401,msg: '缺少token'}return res;}else{let datas = await userCenter.ken)if (de != 0) {res = datasreturn res;}else{params.username = datas.userInfo.username;}}}switch (action) {case "sign": {const {username,password} = params;res = await userCenter.sign(username, password);break;}case "login": {const {username,password} = params;res = await userCenter.login(username, password)break;}case "emailCode": {const {email,type} = params;res = await userCenter.sendEmailCode(email, type)break;}case "checkCode": {const {email,code,type} = params;res = await userCenter.checkCode(email, code, type)break;}case "bind": {const {username,email,code} = params;res = await userCenter.bind(username, email, code)break;}case "unbind": {const {username,email,code} = params;res = await userCenter.unbind(username, email, code)break;}case "loginByEmail": {const {email,code} = params;res = await userCenter.checkCodeLogin(email, code)break;}case "checkToken": {const {token} = params;res = await userCenter.checkToken(token)break;}default: {res = {code: 403,msg: "非法访问"};break;}}return res;
}
注意这里的执行方法
选择我们的项目文件夹
上传文件夹
部署
点击api名称管理
编辑触发器
关闭集成响应
触发器 拿到请求地址
测试注册
这里使用 uni-app做微信小程序
由于我们只用了 用户模块 那么我们就整合用户模块
页面很简单 登录 注册 邮箱登录 邮箱绑定 邮箱解绑
页面代码
<template><view class="content"><view v-if="is_us"><input v-model="username" placeholder="用户名" /><input v-model="password" type="password" placeholder="密码" /><text @click="is_us=false">邮箱验证码登录</text><button @click="login()">登录</button><button @click="register()">注册</button></view><view v-if="!is_us"><input v-model="email" placeholder="邮箱" /><input v-model="code" placeholder="验证码" /><text @click="is_us=true">账号密码登录</text><button @click="sendEmail('login')">发送验证码</button><button @click="loginEm()">登录</button></view><view><view>用户名:{{userInfo.username}}</view><view>token过期时间:{{kenExpired | timeDel }}</view><view>token:{{ken}}</view></view><view v-if=ken!=''"><input v-model="email" placeholder="邮箱" /><input v-model="code" placeholder="验证码" /><button @click="sendEmail('bind')">发送绑定验证码</button><button @click="sendEmail('unbind')">发送解绑验证码</button><button @click="bindEm()">绑定</button><button @click="unbindEm()">解绑</button></view><view><view>{{userInfoG}}</view><button @click="getUserInfo()">获取信息</button></view></view>
</template><script>export default {data() {return {title: 'Hello',is_us: true,username:"",password:"",email:"",code:"",userInfo: {username: "未登录",token:"",tokenExpired:""},userInfoG:{}}},filters:{timeDel(val) {if(!val){return ""}var date = new Date(val*1000); //时间戳为10位需*1000,时间戳为13位的话不需乘1000var Y = FullYear() + '-';var M = (Month() + 1 < 10 ? '0' + (Month() + 1) : Month() + 1) + '-';var D = (Date() < 10 ? '0' + Date() : Date()) + ' ';var h = (Hours() < 10 ? '0' + Hours() : Hours()) + ':';var m = (Minutes() < 10 ? '0' + Minutes() : Minutes()) + ':';var s = Seconds() < 10 ? '0' + Seconds() : Seconds();return Y + M + D + h + m + s;}},onLoad() {},methods: {req(action,other){return new Promise(resolve=>{quest({method:'POST',url:`xxx/userCenter?action=${action}&${other}`,success:res=>{resolve(res.data)}})})},getUserInfo(){let tokens = StorageSync('token')q('checkToken',`token=${tokens}`).then(res=>{uni.showToast({title:res.msg,icon:'none'})this.userInfoG = JSON.stringify(res)})},register(){q('sign',`username=${this.username}&password=${this.password}`).then(res=>{uni.showToast({title:res.msg,icon:'none'})de==0){let userInfo = res.datauni.setStorageSync("token",ken)uni.setStorageSync("tokenExpired",kenExpired)this.userInfo = userInfo}})},login(){q('login',`username=${this.username}&password=${this.password}`).then(res=>{console.log(res)uni.showToast({title:res.msg,icon:'none'})de==0){let userInfo = res.userInfouni.setStorageSync("token",ken)uni.setStorageSync("tokenExpired",kenExpired)this.userInfo = userInfo}})},sendEmail(type){q('emailCode',`email=${ail}&type=${type}`).then(res=>{uni.showToast({title:res.msg,icon:'none'})})},loginEm(){q('loginByEmail',`email=${ail}&code=${de}`).then(res=>{console.log(res)uni.showToast({title:res.msg,icon:'none'})de==0){let userInfo = res.userInfouni.setStorageSync("token",ken)uni.setStorageSync("tokenExpired",kenExpired)this.userInfo = userInfo}})},bindEm(){let tokens = StorageSync('token')q('bind',`username=${this.username}&email=${ail}&code=${de}&token=${tokens}`).then(res=>{console.log(res)uni.showToast({title:res.msg,icon:'none'})})},unbindEm(){let tokens = StorageSync('token')q('unbind',`username=${this.username}&email=${ail}&code=${de}&token=${tokens}`).then(res=>{console.log(res)uni.showToast({title:res.msg,icon:'none'})})}}}
</script><style>.content {display: flex;flex-direction: column;align-items: center;justify-content: center;}.logo {height: 200rpx;width: 200rpx;margin-top: 200rpx;margin-left: auto;margin-right: auto;margin-bottom: 50rpx;}.text-area {display: flex;justify-content: center;}.title {font-size: 36rpx;color: #8f8f94;}
</style>
没有绑定则邮箱非法
【本文正在参与“100%有奖|我的Serverless 实战”征稿活动】,活动地址:
本文发布于:2024-01-28 21:42:20,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170644934710474.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |