// 获取 Session, 如果找不到返回 frontend.ErrNotFound. func SessionGet(token *SessionToken) (*Session, error) { if token == nil { return nil, errors.New("nil SessionToken") } var ( memcacheClient *memcache.Client memcacheItemKey string ) if token.Authenticated { memcacheClient = mc.Client() memcacheItemKey = mc.SessionCacheKey(token.SessionId) } else { memcacheClient = secondarymc.Client() memcacheItemKey = secondarymc.SessionCacheKey(token.SessionId) } item, err := memcacheClient.Get(memcacheItemKey) if err != nil { if err == memcache.ErrCacheMiss { err = frontend.ErrNotFound } return nil, err } var ss Session if err = json.Unmarshal(item.Value, &ss); err != nil { return nil, err } return &ss, nil }
func removeFromCache(userId int64) (err error) { if err = mc.Client().Delete(mc.UserKey(userId)); err != nil { if err == memcache.ErrCacheMiss { err = nil } return } return }
// 从缓存里获取 user 信息, 如果没有找到返回 ErrNotFound. func getFromCache(userId int64, user *User) (err error) { item, err := mc.Client().Get(mc.UserKey(userId)) if err != nil { if err == memcache.ErrCacheMiss { err = ErrNotFound } return } return json.Unmarshal(item.Value, user) }
func putToCache(user *User) (err error) { userBytes, err := json.Marshal(user) if err != nil { return } mcItem := memcache.Item{ Key: mc.UserKey(user.Id), Value: userBytes, } return mc.Client().Set(&mcItem) }
// 生成 email 对应的 code, 6位随机数字, 有效期为 300 秒. func NewCode(email string) ([]byte, error) { item := memcache.Item{ Key: key(email), Value: authcode.NewCode(), Expiration: 300, } if err := mc.Client().Set(&item); err != nil { return nil, err } return item.Value, nil }
// 无条件设置 sid-Session func Set(sid string, ss *Session) (err error) { SessionBytes, err := json.Marshal(ss) if err != nil { return } item := memcache.Item{ Key: mc.SessionKey(sid), Value: SessionBytes, } return mc.Client().Set(&item) }
// 设置 sid-Session, 该 Session 是通过 Get 获取的, // 如果在 Get 之后该 sid 对应的 Session 发生改变, 则返回错误. func CompareAndSwap(sid string, ss *Session) (err error) { item := ss.memcacheItem if item == nil || item.Key != mc.SessionKey(sid) { return fmt.Errorf("参数 Session 不是通过 sid:%q 获取的", sid) } SessionBytes, err := json.Marshal(ss) if err != nil { return } item.Value = SessionBytes return mc.Client().CompareAndSwap(item) }
// 删除 Session, 如果没有匹配则返回 frontend.ErrNotFound. func SessionDelete(token *SessionToken) (err error) { if token == nil { return errors.New("nil SessionToken") } if token.Authenticated { err = mc.Client().Delete(mc.SessionCacheKey(token.SessionId)) } else { err = secondarymc.Client().Delete(secondarymc.SessionCacheKey(token.SessionId)) } if err == memcache.ErrCacheMiss { err = frontend.ErrNotFound } return }
// 获取 Session, 如果找不到返回 errors.ErrNotFound. func Get(sid string) (ss *Session, err error) { item, err := mc.Client().Get(mc.SessionKey(sid)) if err != nil { if err == memcache.ErrCacheMiss { err = errors.ErrNotFound } return } ss = &Session{} if err = json.Unmarshal(item.Value, ss); err != nil { return } ss.memcacheItem = item return }
// 验证 code func AuthCode(email string, code []byte) (bool, error) { item, err := mc.Client().Get(key(email)) if err != nil && err != memcache.ErrCacheMiss { // 出错, 直接返回错误 return false, err } if err == memcache.ErrCacheMiss { if !security.SecureCompare(compareByteSlice, compareByteSlice) { return false, nil } return false, nil } if !security.SecureCompare(code, item.Value) { return false, nil } return true, nil }
func SessionSet(ss *Session) (err error) { if ss == nil { return errors.New("nil Session") } SessionBytes, err := json.Marshal(ss) if err != nil { return } if ss.SessionTokenCopy.Authenticated { item := memcache.Item{ Key: mc.SessionCacheKey(ss.SessionTokenCopy.SessionId), Value: SessionBytes, } return mc.Client().Set(&item) } else { item := memcache.Item{ Key: secondarymc.SessionCacheKey(ss.SessionTokenCopy.SessionId), Value: SessionBytes, } return secondarymc.Client().Set(&item) } }
// 删除 Session, 如果没有匹配则返回 errors.ErrNotFound. func Delete(sid string) (err error) { if err = mc.Client().Delete(mc.SessionKey(sid)); err == memcache.ErrCacheMiss { err = errors.ErrNotFound } return }