Skip to content

Commit

Permalink
add jwt to generate access tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
LyricTian committed Sep 4, 2018
1 parent e975862 commit 2ec5169
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 7 deletions.
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Golang OAuth 2.0
# Golang OAuth 2.0 Server

> An open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop applications.
Expand Down Expand Up @@ -116,12 +116,13 @@ go build server.go

## Features

* easy to use
* based on the [RFC 6749](https://tools.ietf.org/html/rfc6749) implementation
* token storage support TTL
* support custom expiration time of the access token
* support custom extension field
* support custom scope
* Easy to use
* Based on the [RFC 6749](https://tools.ietf.org/html/rfc6749) implementation
* Token storage support TTL
* Support custom expiration time of the access token
* Support custom extension field
* Support custom scope
* Support jwt to generate access tokens

## Example

Expand Down
63 changes: 63 additions & 0 deletions generates/jwt_access.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package generates

import (
"encoding/base64"
"strings"
"time"

"github.com/dgrijalva/jwt-go"
uuid "github.com/satori/go.uuid"
"gopkg.in/oauth2.v3"
"gopkg.in/oauth2.v3/errors"
)

// JWTAccessClaims jwt claims
type JWTAccessClaims struct {
ClientID string `json:"client_id,omitempty"`
UserID string `json:"user_id,omitempty"`
ExpiredAt int64 `json:"expired_at,omitempty"`
}

// Valid claims verification
func (a *JWTAccessClaims) Valid() error {
if time.Unix(a.ExpiredAt, 0).Before(time.Now()) {
return errors.ErrInvalidAccessToken
}
return nil
}

// NewJWTAccessGenerate create to generate the jwt access token instance
func NewJWTAccessGenerate(key []byte, method jwt.SigningMethod) *JWTAccessGenerate {
return &JWTAccessGenerate{
SignedKey: key,
SignedMethod: method,
}
}

// JWTAccessGenerate generate the jwt access token
type JWTAccessGenerate struct {
SignedKey []byte
SignedMethod jwt.SigningMethod
}

// Token based on the UUID generated token
func (a *JWTAccessGenerate) Token(data *oauth2.GenerateBasic, isGenRefresh bool) (access, refresh string, err error) {
claims := &JWTAccessClaims{
ClientID: data.Client.GetID(),
UserID: data.UserID,
ExpiredAt: data.TokenInfo.GetAccessCreateAt().Add(data.TokenInfo.GetAccessExpiresIn()).Unix(),
}

token := jwt.NewWithClaims(a.SignedMethod, claims)
access, err = token.SignedString(a.SignedKey)
if err != nil {
return
}

if isGenRefresh {
refresh = base64.URLEncoding.EncodeToString(uuid.NewV5(uuid.Must(uuid.NewV4()), access).Bytes())
refresh = strings.ToUpper(strings.TrimRight(refresh, "="))
}

return
}
51 changes: 51 additions & 0 deletions generates/jwt_access_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package generates_test

import (
"fmt"
"testing"
"time"

"github.com/dgrijalva/jwt-go"

"gopkg.in/oauth2.v3"
"gopkg.in/oauth2.v3/generates"
"gopkg.in/oauth2.v3/models"

. "github.com/smartystreets/goconvey/convey"
)

func TestJWTAccess(t *testing.T) {
Convey("Test JWT Access Generate", t, func() {
data := &oauth2.GenerateBasic{
Client: &models.Client{
ID: "123456",
Secret: "123456",
},
UserID: "000000",
TokenInfo: &models.Token{
AccessCreateAt: time.Now(),
AccessExpiresIn: time.Second * 120,
},
}

gen := generates.NewJWTAccessGenerate([]byte("00000000"), jwt.SigningMethodHS512)
access, refresh, err := gen.Token(data, true)
So(err, ShouldBeNil)
So(access, ShouldNotBeEmpty)
So(refresh, ShouldNotBeEmpty)

token, err := jwt.ParseWithClaims(access, &generates.JWTAccessClaims{}, func(t *jwt.Token) (interface{}, error) {
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("parse error")
}
return []byte("00000000"), nil
})
So(err, ShouldBeNil)

claims, ok := token.Claims.(*generates.JWTAccessClaims)
So(ok, ShouldBeTrue)
So(token.Valid, ShouldBeTrue)
So(claims.ClientID, ShouldEqual, "123456")
So(claims.UserID, ShouldEqual, "000000")
})
}

0 comments on commit 2ec5169

Please sign in to comment.