在 revel 中,session 仅支持字符串类型值,但可通过 json 序列化/反序列化安全地存储和还原结构体(如 oauth.token),既保持类型完整性,又避免手动拆解字段。
在使用 OAuth 认证(例如 code.google.com/p/goauth2/oauth)时,oauth.Token 等结构体通常包含多个关键字段(如 AccessToken、RefreshToken、Expiry 等)。若按原始方式逐字段存入 Session(如 c.Session["AccessToken"] = t.Token.AccessToken),不仅代码冗余、易出错,还丧失结构体的封装性与可维护性,且后续重建 Token 需手动赋值,极易遗漏字段或类型不匹配。
更优方案是利用 Go 标准库的 encoding/json 包,将整个结构体序列化为 JSON 字符串后存入 Session,读取时再反序列化还原。由于 oauth.Token 的所有字段均为导出字段(首字母大写),完全兼容 JSON 编码规则。
✅ 存储结构体到 Session 示例:
import "encoding/json"
// 假设 t 是包含 oauth.Token 的变量
if data, err := json.Marshal(t.Token); err == nil {
c.Session["OAuthToken"] = string(data) // 存为字符串
} else {
c.Result = c.RenderError("Failed to serialize token: " + err.Error())
return
}✅ 从 Session 还原结构体示例:
var token oauth.Token
if jsonStr, exists := c.Session["OAuthToken"]; exists && jsonStr != "" {
if err := json.Unmarshal([]byte(jsonStr), &token); err != nil {
c.Result = c.RenderError("Failed to deserialize token: " + err.Error())
return
}
// 此时 token 已完整还原,可直接用于构建 HTTP 客户端
client := t.Client(&token) // 或调用 token.Client() 等方法
} else {
c.Result = c.Redirect(LoginController.Login)
return
}⚠️ 注意事项:

通过 JSON 序列化,你既能保持 OAuth 流程的类型安全与逻辑清晰,又完全契合 Revel 的 Session 设计约束——简洁、可靠、符合 Go 语言惯用法。