Go使用Cookie实现简单的登录认证1.0(原生Go,不使用框架)

499 阅读2分钟

说明

 一个简单的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)
}