需求大纲
源码地址:https://github.com/saurfang587/xxvote
视频地址:https://space.bilibili.com/3493125102241833/channel/collectiondetail?sid=2310915&ctype=0
2023/10/1大约 2 分钟
源码地址:https://github.com/saurfang587/xxvote
视频地址:https://space.bilibili.com/3493125102241833/channel/collectiondetail?sid=2310915&ctype=0
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
func main() {
fmt.Print("香香编程喵喵喵!")
g := gin.Default()
g.GET("/login", func(context *gin.Context) {
fmt.Print("香香编程喵喵喵!")
})
if err := g.Run(":8080"); err != nil {
fmt.Print("启动失败!")
}
}
html css js ->** jquery** -> angularjs->** vue **(dva) react -> uniapp
gin-vue-admin
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>香香编程-投票项目</title>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<main class="main">
<input type="text" name="name" id="name" placeholder="Your name">
<input type="password" name="password" id="password" placeholder="Password">
<button type="submit" id="login_sub">Sign in</button>
</main>
<script>
$(document).ready(function(){
$("#login_sub").on("click",function () {
$.ajax({
//请求资源路径
url:"/login",
//请求参数
data:{
name:$("#name").val(),
password:$("#password").val()
},
//请求方式
type:"post",
//数据形式
dataType:"json",
//请求成功后调用的回调函数
success:function (data) {
console.log(data)
if (data.code !== 0){
alert(data.message)
}else{
alert("已登录")
setTimeout("pageRedirect()", 3000);
}
},
//请求失败后调用的回调函数
error:function () {
alert("登录成功")
}
});
});
});
function pageRedirect() {
window.location.replace("/index"); //实现跳转
}
</script>
</body>
</html>
参数校验:
引入正则表达式,字符串长度,是否是数字,是否是身份证,是否是邮箱,是否是abc开头
func CreateUser(context *gin.Context) {
var user reUser
if err := context.ShouldBind(&user); err != nil {
context.JSON(http.StatusOK, tools.ECode{
Code: 10001,
Message: err.Error(), //这里有风险
})
return
}
//对数据进行校验
if user.Name == "" || user.Password == "" || user.Password2 == "" {
context.JSON(http.StatusOK, tools.ECode{
Code: 10003,
Message: "账号或者密码不能为空", //这里有风险
})
return
}
//校验密码
if user.Password != user.Password2 {
context.JSON(http.StatusOK, tools.ECode{
Code: 10003,
Message: "两次密码不同!", //这里有风险
})
return
}
//校验用户是否存在,这种写法非常不安全。有严重的并发风险
if oldUser := model.GetUser(user.Name); oldUser.Id > 0 {
context.JSON(http.StatusOK, tools.ECode{
Code: 10004,
Message: "用户名已存在", //这里有风险
})
return
}
//判断位数
lenName := len(user.Name)
lenPwd := len(user.Password)
if lenName < 8 || lenName > 16 || lenPwd < 8 || lenPwd > 16 {
context.JSON(http.StatusOK, tools.ECode{
Code: 10005,
Message: "用户名或者密码要大于等于8,小于等于16!", //这里有风险
})
return
}
//密码不能是纯数字
regex := regexp.MustCompile(`^[0-9]+$`)
if regex.MatchString(user.Password) {
context.JSON(http.StatusOK, tools.ECode{
Code: 10006,
Message: "密码不能为纯数字", //这里有风险
})
return
}
//开始添加用户
newUser := model.User{
Name: user.Name,
Password: user.Password,
CreatedTime: time.Now(),
UpdatedTime: time.Now(),
}
if err := model.CreateUser(&newUser); err != nil {
context.JSON(http.StatusOK, tools.ECode{
Code: 10006,
Message: "用户创建失败", //这里有风险
})
return
}
//返回添加成功
context.JSON(http.StatusOK, tools.OK)
return
}
uuid 有什么特性。全局唯一性,唯一ID,用户ID
B站,uid 2 208259 3493125102241833
qq 10000 10001 10002 10003 10007
把主键ID 作为一个用户ID 放出去,合适么?
从产品和运维还有架构等多方面角度 思考一下这个问题。
大意:一个用户X秒内请求超过Y次封Z秒,用户已登录,我能到uid;用户未登录,ip+ua
ip 就不用解释了,计算机网络最基本的知识
ua 指的是 user-agent 用户代理。里面有一些硬件数据。
问题:IP+UA 会出现什么问题?
假如,在你们有个人跟你同款手机,手机系统完全一样,用同一个版本的浏览器,访问同一个网站。ip相同,ua也相同。