jwt,cookie,session的异同,以及在golang中的实现
·
jwt,cookie,session的异同,以及在golang中的实现
概要
JWT、Cookie、Session 的异同点
存储位置与结构
JWT (JSON Web Token)
- 存储在客户端(如LocalStorage或Cookie中),由三部分组成:Header(算法类型)、Payload(数据)、Signature(签名验证)。
- 数据以Base64编码的JSON形式存在,可自包含用户信息,无需服务端存储。
Cookie
- 由服务端生成并存储在客户端(浏览器),通过HTTP头部(
Set-Cookie)传递。 - 键值对形式,可设置过期时间、域名限制等属性。
Session
- 服务端存储用户状态(如内存、Redis),通过唯一的Session ID标识,ID通常通过Cookie传递到客户端。
- 数据存储在服务端,客户端仅持有ID。
安全性与验证机制
JWT
- 依赖签名(如HMAC或RSA)验证完整性,需防范密钥泄露。Payload可被解码但不可篡改。
- 无状态,但需处理令牌撤销问题(如黑名单)。
Cookie
- 可设置
HttpOnly(防XSS)、Secure(仅HTTPS)、SameSite(防CSRF)。 - 需防范会话劫持,若泄露则攻击者可冒充用户。
Session
- 服务端可控会话生命周期,可即时失效。
- 需防范Session Fixation攻击,需定期更换Session ID。
性能与扩展性
JWT
- 无状态,适合分布式系统,减少服务端存储开销。
- 但令牌体积较大,增加网络开销。
Cookie
- 轻量级,但每次请求自动携带,可能包含不必要的数据。
- 受浏览器同源策略限制。
Session
- 服务端存储压力大,需共享存储(如Redis)以支持横向扩展。
- 高频访问时可能成为瓶颈。
典型应用场景
JWT
- API认证(如OAuth 2.0)、跨域单点登录(SSO)、无服务端状态的移动端应用。
Cookie
- 传统Web应用会话管理、跟踪用户行为(如分析工具)。
Session
- 需服务端控制会话的Web应用(如银行系统),敏感操作需短会话超时。
关键差异总结
- 存储:JWT和Cookie在客户端,Session数据在服务端。
- 状态:JWT无状态,Session有状态。
- 安全:JWT依赖签名,Session依赖服务端管理,Cookie需属性加固。
- 扩展:JWT适合分布式,Session需集中存储。### 使用Golang实现并发模式
以下是一个使用Golang实现并发模式的示例代码,展示如何使用goroutines和channels进行并发编程:
package main
import (
"fmt"
"time"
)
func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
fmt.Println("worker", id, "started job", j)
time.Sleep(time.Second)
fmt.Println("worker", id, "finished job", j)
results <- j * 2
}
}
func main() {
const numJobs = 5
jobs := make(chan int, numJobs)
results := make(chan int, numJobs)
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
for j := 1; j <= numJobs; j++ {
jobs <- j
}
close(jobs)
for a := 1; a <= numJobs; a++ {
<-results
}
}
Golang中的错误处理
Golang使用显式错误处理,以下是一个错误处理的示例:
package main
import (
"errors"
"fmt"
)
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Result:", result)
}
Golang接口实现
Golang的接口是隐式实现的,以下是一个接口示例:
package main
import (
"fmt"
"math"
)
type Shape interface {
Area() float64
}
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return math.Pi * c.Radius * c.Radius
}
type Rectangle struct {
Width, Height float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
func printArea(s Shape) {
fmt.Println("Area:", s.Area())
}
func main() {
c := Circle{Radius: 5}
r := Rectangle{Width: 3, Height: 4}
printArea(c)
printArea(r)
}
Golang中的JSON处理
Golang提供了内置的JSON支持,以下是JSON处理的示例:
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
// JSON编码
p := Person{Name: "John", Age: 30}
jsonData, err := json.Marshal(p)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(string(jsonData))
// JSON解码
var p2 Person
err = json.Unmarshal(jsonData, &p2)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("%+v\n", p2)
}
Golang中的HTTP服务器
以下是一个简单的HTTP服务器实现:
package main
import (
"fmt"
"net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
}
func main() {
http.HandleFunc("/", helloHandler)
fmt.Println("Server starting on port 8080...")
http.ListenAndServe(":8080", nil)
}
理解代码的上下文
要准确判断代码属于JWT、Session还是Cookie,需要分析代码的具体功能和结构。以下是对这三种技术的简要区分:
- JWT (JSON Web Token):通常用于无状态身份验证,由三部分组成(头部、载荷、签名),以
xxxxx.yyyyy.zzzzz形式传输,存储在客户端(如LocalStorage或Cookie)。 - Session:服务器端存储的用户会话数据,依赖Session ID(通常通过Cookie传递),服务器维护会话状态。
- Cookie:存储在客户端的小型数据片段,由服务器通过
Set-Cookie响应头设置,随请求自动发送到服务器。
常见代码特征
JWT相关代码
- 生成/签名JWT:
const token = jwt.sign({ userId: 123 }, 'secret_key', { expiresIn: '1h' }); - 验证JWT:
const decoded = jwt.verify(token, 'secret_key');
Session相关代码
- Express-Session配置:
app.use(session({ secret: 'keyboard_cat', resave: false, saveUninitialized: true }));
Cookie相关代码
- 设置Cookie:
res.cookie('username', 'john', { maxAge: 900000 }); - 读取Cookie:
const username = req.cookies.username;
如何判断代码类型
-
检查依赖库:
- 使用
jsonwebtoken库的代码属于JWT。 - 使用
express-session或类似中间件的代码属于Session。 - 直接操作
req.cookies或res.cookie的代码属于Cookie。
- 使用
-
观察数据结构:
- JWT通常为长字符串且包含点分隔的三部分(如
eyJhbGciOi...)。 - Session操作通常涉及
req.session对象。 - Cookie表现为键值对,通过HTTP头传输。
- JWT通常为长字符串且包含点分隔的三部分(如
-
传输方式:
- JWT可通过请求头(如
Authorization: Bearer <token>)、URL或Cookie发送。 - Session ID默认通过Cookie传递。
- Cookie通过
Cookie请求头自动发送。
- JWT可通过请求头(如
更多推荐




所有评论(0)