3
\$\begingroup\$

This is a token generating library for Go that runs on top of Redis. I'm using it as part of a larger projects. The library needs to be able to generate and validate tokens and return the associated user IDs.

If you see any bugs or obvious glaring issues, please let me know.

// auth project auth.go
package token

import (
    "crypto/rand"
    "errors"
    "fmt"
    "gopkg.in/redis.v3"
    "time"
)

type Token struct {
    str    string
    expire time.Time
    id     int64
}

func NewToken(l time.Duration, id int) (Token, error) {
    b := make([]byte, 32)
    _, err := rand.Read(b)
    if err != nil {
        return Token{}, err
    }
    t := Token{str: fmt.Sprintf("%x", b), expire: time.Now().Add(l).UTC(), id: int64(id)}
    return t, t.Validate()
}

func (t *Token) SetToken(s string) error {
    t.str = s
    return t.Validate()
}

func (t *Token) GetID() int {
    return int(t.id)
}

func (t *Token) GetExpire() time.Time {
    return t.expire
}

func (t *Token) Validate() error {
    if time.Since(t.expire) >= 0 || t.id == 0 {
        return errors.New("TOKEN_EXPIRED")
    }
    if t.id < 0 {
        return errors.New("TOKEN_INVALID_ID")
    }
    if len(t.str) != 64 {
        return errors.New("TOKEN_INVALID_LENGTH")
    }
    return nil
}

func (t *Token) Store(r *redis.Client) error {
    if t.Validate() != nil {
        return t.Validate()
    }
    flag, err := r.SetNX(t.str, t.id, -time.Since(t.expire)).Result()
    if !flag {
        return errors.New("duplicate stored token")
    }
    return err
}

func (t *Token) Load(r *redis.Client) error {
    id, err := r.Get(t.str).Int64()
    t.id = id
    if t.Validate() != nil {
        return t.Validate()
    }
    return err
}
\$\endgroup\$
  • 1
    \$\begingroup\$ Why are you asking if there are any bugs? Have you not tested your code? \$\endgroup\$ – SirPython Sep 28 '15 at 23:07
  • \$\begingroup\$ I see no issue after doing my unit and functional tests but, as I'm the one writing the tests, I'm interested in the hearing the review of my code by others (in case I'm missing something glaringly obvious). \$\endgroup\$ – James G Sep 28 '15 at 23:42
  • \$\begingroup\$ I don't see any glaring errors, but the code has a distinct feel of Java being written in Go. \$\endgroup\$ – SnoProblem Sep 30 '15 at 7:53
  • \$\begingroup\$ I'm finding as I go along that I want the functionality that this library is intended to provide to be available as a service in and of itself instead of something I import into projects. I'm probably going to create a small account api service and then write my actual project to talk to that. \$\endgroup\$ – James G Oct 3 '15 at 23:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.