说明
一个简单的GoWeb登陆验证程序,适合初学或复习GoWeb的人群,本程序使用到的知识点有:
- Cookie的设置与获取
- go编写简单的中间件
一、登录处理器函数
创建一个Login处理器函数,当接受GET请求时返回登录页面,页面编写如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<h1>用户登录</h1>
<form action="/login" method="post">
<div>账号:</div>
<div>
<input type="text" name="account" placeholder="请输入账号"/>
</div>
<br/>
<div>登录密码</div>
<div>
<input type="password" name="password" placeholder="请输入密码"/>
</div>
<br/>
<div>
<input type="submit" value="登录"/>
</div>
</form>
</body>
</html>
当用户点击登录按钮,发送POST请求到Login处理器函数,然后进行账号密码的判断。
账号密码匹配时,首先设置cookie:
cookie := http.Cookie{
Name: "sessionid",
Value: url.QueryEscape("1234567abc"),
}
user_cookie = cookie.String()
w.Header().Add("Set-Cookie", cookie.String())
w.Write([]byte("登陆成功!"))
设置cookie名和值,将生成的cookie赋值给全局变量user_cookie,在响应头设置Set-Cookie。
func Login(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
t, err := template.ParseFiles("./resource/template/login.html")
if err != nil {
panic(errors.New("解析模板失败"))
}
t.Execute(w, nil)
} else if r.Method == "POST" {
//获取用户输入
ac := r.FormValue("account")
pwd := r.FormValue("password")
//账号密码判断
if ac == "account" && pwd == "1234" {
//设置cookie
cookie := http.Cookie{
Name: "sessionid",
Value: url.QueryEscape("1234567abc"),
}
user_cookie = cookie.String()
w.Header().Add("Set-Cookie", cookie.String())
w.Write([]byte("登陆成功!"))
} else {
w.Header().Set("Location", "/login")
w.WriteHeader(302)
}
}
}
二、自定义中间件
自定义中间件来拦截用户请求,对请求进行登陆验证。
通过Cookie方法从请求中拿到cookie,判断是否匹配,根据匹配结果继续访问或者跳转登陆。
func middleware(f http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
//登陆验证
cookie, _ := r.Cookie("sessionid")
if cookie != nil {
if cookie.String() == user_cookie {
log.Println("cookie信息匹配")
f(w, r)
} else {
log.Println("登录信息不匹配,返回登录,user_cookie:", user_cookie)
log.Println("cookie.String():", cookie.String())
http.Redirect(w, r, "/login", 302)
}
} else {
log.Println("无cookie信息,返回登录")
http.Redirect(w, r, "/login", 302)
}
}
}
全部代码
package main
import (
"errors"
"html/template"
"log"
"net/http"
"net/url"
)
// Cookie实现登录认证
var user_cookie string
func Login(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
t, err := template.ParseFiles("./resource/template/login.html")
if err != nil {
panic(errors.New("解析模板失败"))
}
t.Execute(w, nil)
} else if r.Method == "POST" {
//获取用户输入
ac := r.FormValue("account")
pwd := r.FormValue("password")
//账号密码判断
if ac == "account" && pwd == "1234" {
//设置cookie
cookie := http.Cookie{
Name: "sessionid",
Value: url.QueryEscape("1234567abc"),
}
user_cookie = cookie.String()
w.Header().Add("Set-Cookie", cookie.String())
w.Write([]byte("登陆成功!"))
} else {
w.Header().Set("Location", "/login")
w.WriteHeader(302)
}
}
}
// 自定义中间件
func middleware(f http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
//登陆验证
cookie, _ := r.Cookie("sessionid")
if cookie != nil {
if cookie.String() == user_cookie {
log.Println("cookie信息匹配")
f(w, r)
} else {
log.Println("登录信息不匹配,返回登录,user_cookie:", user_cookie)
log.Println("cookie.String():", cookie.String())
http.Redirect(w, r, "/login", 302)
}
} else {
log.Println("无cookie信息,返回登录")
http.Redirect(w, r, "/login", 302)
}
}
}
func Index(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("./resource/template/index.html")
if err != nil {
log.Println("解析模板失败")
return
}
t.Execute(w, nil)
}
func main() {
http.HandleFunc("/", middleware(Index))
http.HandleFunc("/login", Login)
http.ListenAndServe(":9000", nil)
}