You signed in with another tab or window.Reload to refresh your session.You signed out in another tab or window.Reload to refresh your session.You switched accounts on another tab or window.Reload to refresh your session.Dismiss alert
Support multi web service share session token, which can keep union state in many diff service.
Now session token can store in:
Single mode Redis.
Sentinel mode Redis.
Usage
simple get it by:
go get -v github.com/hunterhug/gosession
core api:
// token manage// token will be put in cache database such redis and user info relate with that token will cache tootypeTokenManageinterface {SetToken(idstring,tokenValidTimesint64) (tokenstring,errerror)// Set token, expire after some secondRefreshToken(tokenstring,tokenValidTimesint64)error// Refresh token,token expire will be again after some secondDeleteToken(tokenstring)error// Delete token when you do action such logoutCheckToken(tokenstring) (user*User,existbool,errerror)// Check the token, but not refresh user info cacheCheckTokenOrUpdateUser(tokenstring,userInfoValidTimesint64) (user*User,existbool,errerror)// Check the token, when cache database exist return user info directly, others hit the persistent database and save newest user in cache database then return. such redis check, not check load from mysql.ListUserToken(idstring) ([]string,error)// List all token of one userDeleteUserToken(idstring)error// Delete all token of this userRefreshUser(id []string,userInfoValidTimesint64)error// Refresh cache of user info batchDeleteUser(idstring)error// Delete user info in cacheAddUser(idstring,userInfoValidTimesint64) (user*User,existbool,errerror)// Add the user info to cache,expire after some secondConfigTokenKeyPrefix(tokenKeystring)TokenManage// Config chain, just cache key prefixConfigUserKeyPrefix(userKeystring)TokenManage// Config chain, just cache key prefixConfigExpireTime(secondint64)TokenManage// Config chain, token expire after secondConfigGetUserInfoFunc(fnGetUserInfoFunc)TokenManage// Config chain, when cache not found user info, will load from this funcSetSingleMode()TokenManage// Can set single mode, before one new token gen, will destroy other token}// core user info, it's Id will be the primary key store in cache database such redistypeUserstruct {Idstring`json:"id"`// unique markTokenRemainLiveTimeint64`json:"-"`// token remain live time in cacheDetailinterface{}`json:"detail"`// can diy your real user info by config ConfigGetUserInfoFunc()}
one simple example:
package mainimport ("fmt""github.com/hunterhug/gosession")funcmain() {tokenManage,err:=gosession.NewRedisSessionSimple("127.0.0.1:6379",0,"hunterhug")iferr!=nil {fmt.Println(err.Error())return}userId:="000001"token,err:=tokenManage.SetToken(userId,20)iferr!=nil {fmt.Println("set token err:",err.Error())return}fmt.Println("set token:",userId,token)user,exist,err:=tokenManage.CheckToken(token)iferr!=nil {fmt.Println("check token err:",err.Error())return}ifexist {fmt.Printf("check token exist: %#v\n",user)}else {fmt.Println("check token not exist")}err=tokenManage.DeleteToken(token)iferr!=nil {fmt.Println("delete token err:",err.Error())return}else {fmt.Println("delete token:",token)}user,exist,err=tokenManage.CheckToken(token)iferr!=nil {fmt.Println("after delete check token err:",err.Error())return}ifexist {fmt.Printf("after delete check delete token exist: %#v\n",user)}else {fmt.Println("after delete check delete token not exist")}tokenManage.SetToken(userId,20)tokenManage.SetToken(userId,20)tokenManage.SetToken(userId,20)tokenManage.SetToken(userId,20)tokenList,err:=tokenManage.ListUserToken(userId)iferr!=nil {fmt.Println("list token err:",err.Error())return}for_,v:=rangetokenList {fmt.Println("list token:",v)}err=tokenManage.DeleteUserToken(userId)iferr!=nil {fmt.Println("delete user all token err:",err.Error())return}else {fmt.Println("delete user all token")}tokenList,err=tokenManage.ListUserToken(userId)iferr!=nil {fmt.Println("after delete user all list token err:",err.Error())return}iflen(tokenList)==0 {fmt.Println("user token empty")}}
another example:
package mainimport ("fmt""github.com/hunterhug/gosession""time")funcmain() {// 1. config redisredisHost:="127.0.0.1:6379"redisDb:=0redisPass:="hunterhug"// may redis has passwordredisConfig:=gosession.NewRedisSessionSingleModeConfig(redisHost,redisDb,redisPass)// or//gosession.NewRedisSessionSentinelModeConfig(":26379,:26380,:26381",0,"mymaster")// 2. connect redis sessiontokenManage,err:=gosession.NewRedisSession(redisConfig)iferr!=nil {fmt.Println(err.Error())return}// 3. config token managetokenManage.ConfigDefaultExpireTime(600)tokenManage.ConfigUserKeyPrefix("go-user")tokenManage.ConfigTokenKeyPrefix("go-token")fn:=func(idstring) (user*gosession.User,errerror) {return&gosession.User{Id:id,Detail:map[string]string{"detail":id},},nil}// get user func diy, you can set it niltokenManage.ConfigGetUserInfoFunc(fn)//tokenManage.SetSingleMode()// 4. set tokenid:="000001"vartokenExpireTimeAloneint64=2token,err:=tokenManage.SetToken(id,tokenExpireTimeAlone)iferr!=nil {fmt.Println("set token err:",err.Error())return}fmt.Println("token:",token)// can set a lot tokentokenManage.SetToken(id,100)tokenManage.SetToken(id,100)tokenManage.SetToken(id,100)// 5. list all tokentokenList,err:=tokenManage.ListUserToken(id)iferr!=nil {fmt.Println("list token err:",err.Error())return}fmt.Println("list token:",tokenList)// 6. check tokenvaruserExpireTimeAloneint64=10// if ConfigGetUserInfoFunc!=nil, will load user info from func if not exist in redis cacheu,exist,err:=tokenManage.CheckTokenOrUpdateUser(token,userExpireTimeAlone)iferr!=nil {fmt.Println("check token err:",err.Error())return}fmt.Printf("check token:%#v, %#v,%#v\n",token,u,exist)err=tokenManage.RefreshToken(token,5)iferr!=nil {fmt.Println("refresh token err:",err.Error())return}u,exist,err=tokenManage.CheckTokenOrUpdateUser(token,userExpireTimeAlone)iferr!=nil {fmt.Println("after refresh check token err:",err.Error())return}fmt.Printf("after refresh token:%#v, %#v,%#v\n",token,u,exist)// 7. sleep to see token is exist?time.Sleep(10*time.Second)u,exist,err=tokenManage.CheckTokenOrUpdateUser(token,userExpireTimeAlone)iferr!=nil {fmt.Println("sleep check token err:",err.Error())return}fmt.Printf("sleep check token:%#v, %#v,%#v\n",token,u,exist)// you can delete all token of one usertokenList,err=tokenManage.ListUserToken(id)iferr!=nil {fmt.Println("sleep list token err:",err.Error())return}fmt.Println("sleep token:",tokenList)err=tokenManage.DeleteUserToken(id)iferr!=nil {fmt.Println("delete user token err:",err.Error())return}tokenList,err=tokenManage.ListUserToken(id)iferr!=nil {fmt.Println("after delete user token list err:",err.Error())return}fmt.Println("after delete user token list:",tokenList)}
TODO
Support JWT token, that will enable token verify in client side to find the token expire early, also we can filter in server side.
Support Other Db such MySQL or Mongo.
Support Feature of multiple clients single sign on.
License
Copyright [2019-2021] [github.com/hunterhug]Licensed under the Apache License, Version 2.0 (the "License");you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions andlimitations under the License.