added blacklist storage interface
This commit is contained in:
parent
339d6de8bd
commit
4c14116a41
3 changed files with 92 additions and 23 deletions
37
jwt.go
37
jwt.go
|
|
@ -46,16 +46,15 @@ type JWT struct {
|
|||
|
||||
// protects list
|
||||
sync.RWMutex
|
||||
blacklist bool
|
||||
list map[string]int64
|
||||
stop chan struct{}
|
||||
blacklist Blacklist
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
// New returns a new JWT object with the given expiry timeout.
|
||||
// If the timeout is less or equal to zero the default expiry (12 hours) is used.
|
||||
// If blacklisting is enabled, the JWT object leaks a goroutine to garbage-collect expired blacklisted tokens.
|
||||
// Call the Stop() method to exit the goroutine.
|
||||
func New(expiry time.Duration, blacklist bool) *JWT {
|
||||
func New(expiry time.Duration, blacklist Blacklist) *JWT {
|
||||
if expiry <= 0 {
|
||||
expiry = DefaultExpiry
|
||||
}
|
||||
|
|
@ -66,9 +65,8 @@ func New(expiry time.Duration, blacklist bool) *JWT {
|
|||
expiry: expiry,
|
||||
blacklist: blacklist,
|
||||
}
|
||||
if blacklist {
|
||||
jwt.list = make(map[string]int64)
|
||||
jwt.stop = make(chan struct{})
|
||||
if blacklist != nil {
|
||||
jwt.done = make(chan struct{})
|
||||
go jwt.clean()
|
||||
}
|
||||
return jwt
|
||||
|
|
@ -83,7 +81,7 @@ func (jwt *JWT) sum(token string, h Hash) []byte {
|
|||
// Invalidate checks if a token is already blacklisted
|
||||
// If the token is not blacklisted, it will get blacklisted
|
||||
func (jwt *JWT) Invalidate(t *Token) error {
|
||||
if !jwt.blacklist {
|
||||
if jwt.blacklist == nil {
|
||||
return ErrBlacklistNotEnabled
|
||||
}
|
||||
if t == nil {
|
||||
|
|
@ -111,7 +109,7 @@ func (jwt *JWT) Invalidate(t *Token) error {
|
|||
}
|
||||
jwt.Lock()
|
||||
defer jwt.Unlock()
|
||||
jwt.list[t.Sig()] = exp
|
||||
jwt.blacklist.Add(t.Sig(), exp)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -122,28 +120,27 @@ func (jwt *JWT) blacklisted(sig string) error {
|
|||
}
|
||||
jwt.RLock()
|
||||
defer jwt.RUnlock()
|
||||
_, ok := jwt.list[sig]
|
||||
if ok {
|
||||
if jwt.blacklist.Check(sig) {
|
||||
return ErrBlacklisted
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// clean will look for expired blacklisted tokens and removes them
|
||||
// clean looks for expired blacklisted tokens and removes them
|
||||
func (jwt *JWT) clean() {
|
||||
for {
|
||||
t := time.NewTimer(time.Hour)
|
||||
select {
|
||||
case <-t.C:
|
||||
case <-jwt.stop:
|
||||
case <-jwt.done:
|
||||
t.Stop()
|
||||
return
|
||||
}
|
||||
now := time.Now().UTC().Unix()
|
||||
jwt.Lock()
|
||||
for k, v := range jwt.list {
|
||||
for k, v := range jwt.blacklist.Map() {
|
||||
if now > v {
|
||||
delete(jwt.list, k)
|
||||
jwt.blacklist.Remove(k)
|
||||
}
|
||||
}
|
||||
jwt.Unlock()
|
||||
|
|
@ -243,7 +240,7 @@ func (jwt *JWT) Verify(t *Token) error {
|
|||
nbf = int64(n)
|
||||
nbfOK = true
|
||||
}
|
||||
if expOK && jwt.blacklist {
|
||||
if jwt.blacklist != nil {
|
||||
err := jwt.blacklisted(t.Sig())
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -264,14 +261,10 @@ func (jwt *JWT) Verify(t *Token) error {
|
|||
// Stop will end the cleaner goroutinge execution
|
||||
// Calling Stop twice or more will panic
|
||||
func (jwt *JWT) Stop() error {
|
||||
if !jwt.blacklist {
|
||||
if jwt.blacklist == nil {
|
||||
return ErrBlacklistNotEnabled
|
||||
}
|
||||
select {
|
||||
case jwt.stop <- struct{}{}:
|
||||
close(jwt.stop)
|
||||
default:
|
||||
}
|
||||
close(jwt.done)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue