GoWeb之会话控制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/TDCQZD/article/details/82634214

一、基本介绍

HTTP是无状态协议,服务器不能记录浏览器的访问状态,也就是说服务器不能区分中两次请求是否由一个客户端发出。这样的设计严重阻碍的Web程序的设计。如:在我们进行网购时,买了一条裤子,又买了一个手机。由于http协议是无状态的,如果不通过其他手段,服务器是不能知道用户到底买了什么。而Cookie就是解决方案之一。

二、Cookie

1、 简介
Cookie实际上就是服务器保存在浏览器上的一段信息。浏览器有了Cookie之后,每次向服务器发送请求时都会同时将该信息发送给服务器,服务器收到请求后,就可以根据该信息处理请求。

2、Cookie的运行原理
1) 第一次向服务器发送请求时在服务器端创建Cookie
2) 将在服务器端创建的Cookie以响应头的方式发送给浏览器
3) 以后再发送请求浏览器就会携带着该Cookie
4) 服务器得到Cookie之后根据Cookie的信息来区分不同的用户

3、 创建Cookie并将它发送给浏览器
1) 在服务器创建Cookie并将它发送给浏览器
服务器端代码

func handler(w http.ResponseWriter, r *http.Request) {
    cookie1 := http.Cookie{
        Name:     "user1",
        Value:    "admin",
        HttpOnly: true,
    }

    cookie2 := http.Cookie{
        Name:     "user2",
        Value:    "superAdmin",
        HttpOnly: true,
    }

    //将Cookie发送给浏览器,即添加第一个Cookie
    w.Header().Set("Set-Cookie", cookie1.String())
    //再添加一个Cookie
    w.Header().Add("Set-Cookie", cookie2.String())
}

浏览器响应报文中的内容

HTTP/1.1 200 OK
Set-Cookie: user1=admin; HttpOnly
Set-Cookie: user2=superAdmin; HttpOnly
Date: Sun, 12 Aug 2018 07:24:49 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8

2) 以后每次发送请求浏览器都会携带着Cookie

GET /cookie HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: user1=admin; user2=superAdmin

3) 除了Set和Add方法之外,Go还提供了一种更快捷的设置Cookie的方式,就是通过net/http库中的SetCookie方法

将1)中的代码进行修改

func handler(w http.ResponseWriter, r *http.Request) {
    cookie1 := http.Cookie{
        Name:     "user1",
        Value:    "admin",
        HttpOnly: true,
    }

    cookie2 := http.Cookie{
        Name:     "user2",
        Value:    "superAdmin",
        HttpOnly: true,
    }

    http.SetCookie(w, &cookie1)
    http.SetCookie(w, &cookie2)
}

4 读取Cookie
由于我们在发送请求时Cookie在请求头中,所以我们可以通过Request结构中的Header字段来获取Cookie

1) 处理器端代码

func handler(w http.ResponseWriter, r *http.Request) {
    //获取请求头中的Cookie
    cookies := r.Header["Cookie"]
    fmt.Fprintln(w, cookies)
}

2) 浏览器中的结果

[user1=admin; user2=superAdmin]

5 、设置Cookie的有效时间

Cookie默认是会话级别的,当关闭浏览器之后Cookie将失效,我们可以通过Cookie结构的MaxAge字段设置Cookie的有效时间
1) 处理器端代码

func handler(w http.ResponseWriter, r *http.Request) {

    cookie := http.Cookie{
        Name:     "user",
        Value:    "persistAdmin",
        HttpOnly: true,
        MaxAge:   60,
    }

    //将Cookie发送给浏览器
    w.Header().Set("Set-Cookie", cookie.String())
}

2) 浏览器响应报文中的内容

HTTP/1.1 200 OK
Set-Cookie: user=persistAdmin; Max-Age=60; HttpOnly
Date: Sun, 12 Aug 2018 07:32:57 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8

6、代码示例:

package utils

import (
    "fmt"
    "net/http"
)

// Set和Add方法 创建Cookie
func handlerCookie(w http.ResponseWriter, r *http.Request) {
    cookie1 := http.Cookie{
        Name:     "lskd",
        Value:    "nshlz",
        HttpOnly: true,
    }

    cookie2 := http.Cookie{
        Name:     "yexiaochai",
        Value:    "HeartSword",
        HttpOnly: true,
    }

    //将Cookie发送给浏览器,即添加第一个Cookie
    w.Header().Set("Set-Cookie", cookie1.String())
    //再添加一个Cookie
    w.Header().Add("Set-Cookie", cookie2.String())

}

//SetCookie方法创建Cookie
func handlerSetCookie(w http.ResponseWriter, r *http.Request) {
    cookie1 := http.Cookie{
        Name:     "rpm",
        Value:    "pmjf",
        HttpOnly: true,
    }

    cookie2 := http.Cookie{
        Name:     "ngh",
        Value:    "wjsg",
        HttpOnly: true,
    }

    http.SetCookie(w, &cookie1)
    http.SetCookie(w, &cookie2)

}

// 读取Cookie
func handlerReadCookie(w http.ResponseWriter, r *http.Request) {
    //获取请求头中的Cookie
    cookies := r.Header["Cookie"]
    //获取一个具体Cookie
    rpmCookie, _ := r.Cookie("rpm")
    fmt.Fprintln(w, cookies)
    fmt.Fprintln(w, rpmCookie)

}

// 设置Cookie的有效时间
func handlerMaxAge(w http.ResponseWriter, r *http.Request) {
    cookie := http.Cookie{
        Name:     "yiyeshu",
        Value:    "bjwj",
        HttpOnly: true,
        MaxAge:   10,
    }

    http.SetCookie(w, &cookie)

}

// Session
func handlerSession(w http.ResponseWriter, r *http.Request) {
    cookie := http.Cookie{
        Name:     "session",
        Value:    "bjwj",
        HttpOnly: true,
        MaxAge:   10,
    }

    http.SetCookie(w, &cookie)

}

func CookieDemo() {
    http.HandleFunc("/cookie", handlerCookie)
    http.HandleFunc("/setcookie", handlerSetCookie)
    http.HandleFunc("/readcookie", handlerReadCookie)
    http.HandleFunc("/maxage", handlerMaxAge)

    http.HandleFunc("/session", handlerSession)

    http.ListenAndServe(":8080", nil)
}

三、Session

1 、简介
使用Cookie有一个非常大的局限,就是如果Cookie很多,则无形的增加了客户端与服务端的数据传输量。而且由于浏览器对Cookie数量的限制,注定我们不能再Cookie中保存过多的信息,于是Session出现。

Session的作用就是在服务器端保存一些用户的数据,然后传递给用户一个特殊的Cookie,这个Cookie对应着这个服务器中的一个Session,通过它就可以获取到保存用户信息的Session,进而就知道是那个用户再发送请求。

2 Session的运行原理
1) 第一次向服务器发送请求时创建Session,给它设置一个全球唯一的ID(可以通过UUID生成)
2) 创建一个Cookie,将Cookie的Value设置为Session的ID值,并将Cookie发送给浏览器
3) 以后再发送请求浏览器就会携带着该Cookie
4) 服务器获取Cookie并根据它的Value值找到服务器中对应的Session,也就知道了请求是那个用户发的

3.Session实例

package model

type Seesion struct {
    UUID     string
    UserID   string
    UserName string
    CartInfor *Cart
}


    uuid := getUUID(user, r)
        /*设置Cookie*/
        cookie := http.Cookie{
            Name:     "usersession",
            Value:    uuid,
            HttpOnly: true,
        }
    http.SetCookie(w, &cookie)
func getUUID(user *model.Users, r *http.Request) string {
    /*组装Session*/

    uuid := utils.CreateUUID()
    session := model.Seesion{
        UUID:     uuid,
        UserName: user.Username,
        UserID:   user.ID,
    }

    //获取Cookie
    userCookie, _ := r.Cookie("usersession")

    if UserStatue.IsLogin { //已登录状态
        uuid = userCookie.Value
    } else {
        modelDao.AddSession(&session)
    }
    return uuid
}

猜你喜欢

转载自blog.csdn.net/TDCQZD/article/details/82634214