oauth2

package module
v4.5.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 3, 2023 License: MIT Imports: 6 Imported by: 216

README

Golang OAuth 2.0 Server

An open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop applications.

Build Codecov ReportCard GoDoc License

Protocol Flow

     +--------+                               +---------------+
     |        |--(A)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(B)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(C)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(D)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(E)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(F)--- Protected Resource ---|               |
     +--------+                               +---------------+

Quick Start

Download and install
go get -u -v github.com/go-oauth2/oauth2/v4/...
Create file server.go
package main

import (
	"log"
	"net/http"

	"github.com/go-oauth2/oauth2/v4/errors"
	"github.com/go-oauth2/oauth2/v4/manage"
	"github.com/go-oauth2/oauth2/v4/models"
	"github.com/go-oauth2/oauth2/v4/server"
	"github.com/go-oauth2/oauth2/v4/store"
)

func main() {
	manager := manage.NewDefaultManager()
	// token memory store
	manager.MustTokenStorage(store.NewMemoryTokenStore())

	// client memory store
	clientStore := store.NewClientStore()
	clientStore.Set("000000", &models.Client{
		ID:     "000000",
		Secret: "999999",
		Domain: "http://localhost",
	})
	manager.MapClientStorage(clientStore)

	srv := server.NewDefaultServer(manager)
	srv.SetAllowGetAccessRequest(true)
	srv.SetClientInfoHandler(server.ClientFormHandler)

	srv.SetInternalErrorHandler(func(err error) (re *errors.Response) {
		log.Println("Internal Error:", err.Error())
		return
	})

	srv.SetResponseErrorHandler(func(re *errors.Response) {
		log.Println("Response Error:", re.Error.Error())
	})

	http.HandleFunc("/authorize", func(w http.ResponseWriter, r *http.Request) {
		err := srv.HandleAuthorizeRequest(w, r)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
		}
	})

	http.HandleFunc("/token", func(w http.ResponseWriter, r *http.Request) {
		srv.HandleTokenRequest(w, r)
	})

	log.Fatal(http.ListenAndServe(":9096", nil))
}

Build and run
go build server.go

./server
Open in your web browser

Authorization Request: http://localhost:9096/authorize?client_id=000000&response_type=code

Grant Token Request: http://localhost:9096/token?grant_type=client_credentials&client_id=000000&client_secret=999999&scope=read

{
  "access_token": "J86XVRYSNFCFI233KXDL0Q",
  "expires_in": 7200,
  "scope": "read",
  "token_type": "Bearer"
}

Features

  • Easy to use
  • Based on the RFC 6749 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

A complete example of simulation authorization code model

Simulation examples of authorization code model, please check example

Use jwt to generate access tokens

import (
	"github.com/go-oauth2/oauth2/v4/generates"
	"github.com/dgrijalva/jwt-go"
)

// ...
manager.MapAccessGenerate(generates.NewJWTAccessGenerate("", []byte("00000000"), jwt.SigningMethodHS512))

// Parse and verify jwt access token
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
})
if err != nil {
	// panic(err)
}

claims, ok := token.Claims.(*generates.JWTAccessClaims)
if !ok || !token.Valid {
	// panic("invalid token")
}

Store Implements

Handy Utilities

MIT License

Copyright (c) 2016 Lyric

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AccessGenerate

type AccessGenerate interface {
	Token(ctx context.Context, data *GenerateBasic, isGenRefresh bool) (access, refresh string, err error)
}

AccessGenerate generate the access and refresh tokens interface

type AuthorizeGenerate

type AuthorizeGenerate interface {
	Token(ctx context.Context, data *GenerateBasic) (code string, err error)
}

AuthorizeGenerate generate the authorization code interface

type ClientInfo

type ClientInfo interface {
	GetID() string
	GetSecret() string
	GetDomain() string
	IsPublic() bool
	GetUserID() string
}

ClientInfo the client information model interface

type ClientPasswordVerifier

type ClientPasswordVerifier interface {
	VerifyPassword(string) bool
}

ClientPasswordVerifier the password handler interface

type ClientStore

type ClientStore interface {
	// according to the ID for the client information
	GetByID(ctx context.Context, id string) (ClientInfo, error)
}

ClientStore the client information storage interface

type CodeChallengeMethod added in v4.2.0

type CodeChallengeMethod string

CodeChallengeMethod PCKE method

const (
	// CodeChallengePlain PCKE Method
	CodeChallengePlain CodeChallengeMethod = "plain"
	// CodeChallengeS256 PCKE Method
	CodeChallengeS256 CodeChallengeMethod = "S256"
)

func (CodeChallengeMethod) String added in v4.2.0

func (ccm CodeChallengeMethod) String() string

func (CodeChallengeMethod) Validate added in v4.2.0

func (ccm CodeChallengeMethod) Validate(cc, ver string) bool

Validate code challenge

type GenerateBasic

type GenerateBasic struct {
	Client    ClientInfo
	UserID    string
	CreateAt  time.Time
	TokenInfo TokenInfo
	Request   *http.Request
}

GenerateBasic provide the basis of the generated token data

type GrantType

type GrantType string

GrantType authorization model

const (
	AuthorizationCode   GrantType = "authorization_code"
	PasswordCredentials GrantType = "password"
	ClientCredentials   GrantType = "client_credentials"
	Refreshing          GrantType = "refresh_token"
	Implicit            GrantType = "__implicit"
)

define authorization model

func (GrantType) String

func (gt GrantType) String() string

type Manager

type Manager interface {
	// get the client information
	GetClient(ctx context.Context, clientID string) (cli ClientInfo, err error)

	// generate the authorization token(code)
	GenerateAuthToken(ctx context.Context, rt ResponseType, tgr *TokenGenerateRequest) (authToken TokenInfo, err error)

	// generate the access token
	GenerateAccessToken(ctx context.Context, gt GrantType, tgr *TokenGenerateRequest) (accessToken TokenInfo, err error)

	// refreshing an access token
	RefreshAccessToken(ctx context.Context, tgr *TokenGenerateRequest) (accessToken TokenInfo, err error)

	// use the access token to delete the token information
	RemoveAccessToken(ctx context.Context, access string) (err error)

	// use the refresh token to delete the token information
	RemoveRefreshToken(ctx context.Context, refresh string) (err error)

	// according to the access token for corresponding token information
	LoadAccessToken(ctx context.Context, access string) (ti TokenInfo, err error)

	// according to the refresh token for corresponding token information
	LoadRefreshToken(ctx context.Context, refresh string) (ti TokenInfo, err error)
}

Manager authorization management interface

type ResponseType

type ResponseType string

ResponseType the type of authorization request

const (
	Code  ResponseType = "code"
	Token ResponseType = "token"
)

define the type of authorization request

func (ResponseType) String

func (rt ResponseType) String() string

type TokenGenerateRequest

type TokenGenerateRequest struct {
	ClientID            string
	ClientSecret        string
	UserID              string
	RedirectURI         string
	Scope               string
	Code                string
	CodeChallenge       string
	CodeChallengeMethod CodeChallengeMethod
	Refresh             string
	CodeVerifier        string
	AccessTokenExp      time.Duration
	Request             *http.Request
}

TokenGenerateRequest provide to generate the token request parameters

type TokenInfo

type TokenInfo interface {
	New() TokenInfo

	GetClientID() string
	SetClientID(string)
	GetUserID() string
	SetUserID(string)
	GetRedirectURI() string
	SetRedirectURI(string)
	GetScope() string
	SetScope(string)

	GetCode() string
	SetCode(string)
	GetCodeCreateAt() time.Time
	SetCodeCreateAt(time.Time)
	GetCodeExpiresIn() time.Duration
	SetCodeExpiresIn(time.Duration)
	GetCodeChallenge() string
	SetCodeChallenge(string)
	GetCodeChallengeMethod() CodeChallengeMethod
	SetCodeChallengeMethod(CodeChallengeMethod)

	GetAccess() string
	SetAccess(string)
	GetAccessCreateAt() time.Time
	SetAccessCreateAt(time.Time)
	GetAccessExpiresIn() time.Duration
	SetAccessExpiresIn(time.Duration)

	GetRefresh() string
	SetRefresh(string)
	GetRefreshCreateAt() time.Time
	SetRefreshCreateAt(time.Time)
	GetRefreshExpiresIn() time.Duration
	SetRefreshExpiresIn(time.Duration)
}

TokenInfo the token information model interface

type TokenStore

type TokenStore interface {
	// create and store the new token information
	Create(ctx context.Context, info TokenInfo) error

	// delete the authorization code
	RemoveByCode(ctx context.Context, code string) error

	// use the access token to delete the token information
	RemoveByAccess(ctx context.Context, access string) error

	// use the refresh token to delete the token information
	RemoveByRefresh(ctx context.Context, refresh string) error

	// use the authorization code for token information data
	GetByCode(ctx context.Context, code string) (TokenInfo, error)

	// use the access token for token information data
	GetByAccess(ctx context.Context, access string) (TokenInfo, error)

	// use the refresh token for token information data
	GetByRefresh(ctx context.Context, refresh string) (TokenInfo, error)
}

TokenStore the token information storage interface

Directories

Path Synopsis
example

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL