Skip to content

Commit

Permalink
Merge pull request #376 from gofr-dev/development
Browse files Browse the repository at this point in the history
Release v1.1.0
  • Loading branch information
vipul-rawat authored Mar 12, 2024
2 parents fd52bcd + 67ee4ff commit 38f1294
Show file tree
Hide file tree
Showing 33 changed files with 2,705 additions and 304 deletions.
178 changes: 178 additions & 0 deletions docs/advanced-guide/http-authentication/page.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# HTTP Authentication
Authentication is a crucial aspect of web applications, controlling access to resources based on user roles or permissions.
It is the process of verifying a user's identity to grant access to protected resources. It ensures only
authenticated users can perform actions or access data within an application.

GoFr offer various approaches to implement authorization.

## 1. HTTP Basic Auth
*Basic Authentication* is a simple HTTP authentication scheme where the user's credentials (username and password) are
transmitted in the request header in a Base64-encoded format.

Basic auth is the simplest way to authenticate your APIs. It's built on
[HTTP protocol authentication scheme](https://datatracker.ietf.org/doc/html/rfc7617). It involves sending the term
`Basic` trailed by the Base64-encoded `<username>:<password>` within the standard `Authorization` header.

### Basic Authentication in GoFr

GoFr offers two ways to implement basic authentication:

**1. Predefined Credentials**

Use `EnableBasicAuth(username, password)` to configure Gofr with pre-defined credentials.

```go
func main() {
app := gofr.New()

app.EnableBasicAuth("admin", "secret_password") // Replace with your credentials

app.GET("/protected-resource", func(c *gofr.Context) (interface{}, error) {
// Handle protected resource access
return nil, nil
})

app.Run()
}
```

**2. Custom Validation Function**

Use `EnableBasicAuthWithFunc(validationFunc)` to implement your own validation logic for credentials. The `validationFunc` takes the username and password as arguments and returns true if valid, false otherwise.

```go
func validateUser(username string, password string) bool {
// Implement your credential validation logic here
// This example uses hardcoded credentials for illustration only
return username == "john" && password == "doe123"
}

func main() {
app := gofr.New()

app.EnableBasicAuthWithFunc(validateUser)

app.GET("/secure-data", func(c *gofr.Context) (interface{}, error) {
// Handle access to secure data
return nil, nil
})

app.Run()
}
```

### Adding Basic Authentication to HTTP Services

This code snippet demonstrates how to add basic authentication to an HTTP service in GoFr and make a request with the appropriate Authorization header:

```go
app.AddHTTPService("order", "https://localhost:2000",
&service.Authentication{UserName: "abc", Password: "pass"},
)
```

## 2. API Keys Auth
Users include a unique API key in the request header for validation against a store of authorized keys.

### Usage:
GoFr offers two ways to implement API Keys authentication.

**1. Framework Default Validation**
- Users can select the framework's default validation using **_EnableAPIKeyAuth(apiKeys ...string)_**

```go
package main

func main() {
// initialise gofr object
app := gofr.New()

app.EnableAPIKeyAuth("9221e451-451f-4cd6-a23d-2b2d3adea9cf", "0d98ecfe-4677-48aa-b463-d43505766915")

app.GET("/customer", Customer)

app.Run()
}
```

**2. Custom Validation Function**
- Users can create their own validator function `apiKeyValidator(apiKey string) bool` for validating APIKeys and pass the func in **_EnableAPIKeyAuthWithFunc(validator)_**

```go
package main

func apiKeyValidator(apiKey string) bool {
validKeys := []string{"f0e1dffd-0ff0-4ac8-92a3-22d44a1464e4", "d7e4b46e-5b04-47b2-836c-2c7c91250f40"}

return slices.Contains(validKeys, apiKey)
}

func main() {
// initialise gofr object
app := gofr.New()

app.EnableAPIKeyAuthWithFunc(apiKeyValidator)

app.GET("/customer", Customer)

app.Run()
}
```

### Adding API-KEY Authentication to HTTP Services
This code snippet demonstrates how to add API Key authentication to an HTTP service in GoFr and make a request with the appropriate Authorization header:

```go
app.AddHTTPService("http-server-using-redis", "http://localhost:8000", &service.APIKeyConfig{APIKey: "9221e451-451f-4cd6-a23d-2b2d3adea9cf"})
```

## 3. OAuth 2.0
OAuth 2.0 is the industry-standard protocol for authorization.
It focuses on client developer simplicity while providing specific authorization flows for web applications, desktop applications, mobile phones, and living room devices.
To know more about it refer [here](https://www.rfc-editor.org/rfc/rfc6749)

It involves sending the term `Bearer` trailed by the encoded token within the standard `Authorization` header.

### OAuth Authentication in GoFr

GoFr supports authenticating tokens encoded by algorithm `RS256/384/512`.

### App level Authentication
Enable OAuth 2.0 with three-legged flow to authenticate requests

Use `EnableOAuth(jwks-endpoint,refresh_interval)` to configure Gofr with pre-defined credentials.

```go
func main() {
app := gofr.New()

app.EnableOAuth("http://jwks-endpoint", 20)

app.GET("/protected-resource", func(c *gofr.Context) (interface{}, error) {
// Handle protected resource access
return nil, nil
})

app.Run()
}
```

### Adding OAuth Authentication to HTTP Services
For server-to-server communication it follows two-legged OAuth, also known as "client credentials" flow,
where the client application directly exchanges its own credentials (ClientID and ClientSecret)
for an access token without involving any end-user interaction.

This code snippet demonstrates how two-legged OAuth authentication is added to an HTTP service in GoFr and make a request with the appropriate Authorization header.

```go
a.AddHTTPService("orders", "http://localhost:9000",
&service.OAuthConfig{ // Replace with your credentials
ClientID: "0iyeGcLYWudLGqZfD6HvOdZHZ5TlciAJ",
ClientSecret: "GQXTY2f9186nUS3C9WWi7eJz8-iVEsxq7lKxdjfhOJbsEPPtEszL3AxFn8k_NAER",
TokenURL: "https://dev-zq6tvaxf3v7p0g7j.us.auth0.com/oauth/token",
Scopes: []string{"read:order"},
EndpointParams: map[string][]string{
"audience": {"https://dev-zq6tvaxf3v7p0g7j.us.auth0.com/api/v2/"},
},
})
```
30 changes: 30 additions & 0 deletions docs/advanced-guide/using-publisher-subscriber/page.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,36 @@ docker run --name=gcloud-emulator -d -p 8086:8086 \
> **Note**: In Google PubSub only one subscription name can access one topic, framework appends the topic name and subscription name to form the
> unique subscription name on the Google client.
### Mqtt

#### Configs
```dotenv
PUBSUB_BACKEND=MQTT // using Mqtt as pubsub
MQTT_HOST=localhost // broker host url
MQTT_PORT=1883 // broker port
MQTT_CLIENT_ID_SUFFIX=test // suffix to a random generated client-id(uuid v4)
#some additional configs(optional)
MQTT_PROTOCOL=tcp // protocol for connecting to broker can be tcp, tls, ws or wss
MQTT_MESSAGE_ORDER=true // config to maintain/retain message publish order, by defualt this is false
MQTT_USER=username // authentication username
MQTT_PASSWORD=password // authentication password
```
> **Note** : If `MQTT_HOST` config is not provided, the application will connect to a public broker
> [HiveMQ](https://www.hivemq.com/mqtt/public-mqtt-broker/)
#### Docker setup
```shell
docker run -d \
--name mqtt \
-p 8883:8883 \
-v <path-to>/mosquitto.conf:/mosquitto/config/mosquitto.conf \
eclipse-mosquitto:latest
```
> **Note**: find the default mosquitto config file [here](https://github.com/eclipse/mosquitto/blob/master/mosquitto.conf)


## Subscribing to Pub/Sub
Adding a subscriber is similar to adding an HTTP handler, which makes it easier to develop scalable applications,
as it decoupled from the Sender/Publisher.
Expand Down
2 changes: 2 additions & 0 deletions docs/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ export const navigation = [
{ title: 'Publishing Custom Metrics', href: '/docs/advanced-guide/publishing-custom-metrics' },
{ title: 'Custom Spans in Tracing', href: '/docs/advanced-guide/custom-spans-in-tracing' },
{ title: 'HTTP Communication', href: '/docs/advanced-guide/http-communication' },
{ title: 'HTTP Authentication', href: '/docs/advanced-guide/http-authentication' },
{ title: 'Circuit Breaker Support', href: '/docs/advanced-guide/circuit-breaker' },
{ title: 'Monitoring Service Health', href: '/docs/advanced-guide/monitoring-service-health' },
{ title: 'Handling Data Migrations', href: '/docs/advanced-guide/handling-data-migrations' },
{ title: 'Writing gRPC Server', href: '/docs/advanced-guide/grpc' },
{ title: 'Using Publisher and Subscriber', href: '/docs/advanced-guide/using-publisher-subscriber' }
// { title: 'Dealing with Remote Files', href: '/docs/advanced-guide/remote-files' },
// { title: 'Supporting OAuth', href: '/docs/advanced-guide/oauth' },
// { title: 'Creating a Static File Server', href: '/docs/advanced-guide/static-file-server' },
Expand Down
5 changes: 3 additions & 2 deletions examples/http-server-using-redis/configs/.env
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
APP_NAME=sample-api
HTTP_PORT=8000

LOG_LEVEL=DEBUG

REDIS_HOST=localhost
REDIS_PORT=2002

LOG_LEVEL=DEBUG


9 changes: 8 additions & 1 deletion examples/using-publisher/configs/.env
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
APP_NAME=sample-api
HTTP_PORT=8100

LOG_LEVEL=DEBUG

PUBSUB_BACKEND=KAFKA
PUBSUB_BROKER=localhost:9092
CONSUMER_ID=test

LOG_LEVEL=DEBUG
# For using MQTT uncomment these configs
#PUBSUB_BACKEND=MQTT
#MQTT_PROTOCOL=tcp
#MQTT_HOST=localhost
#MQTT_PORT=8883
#MQTT_CLIENT_ID_SUFFIX=test-publisher
9 changes: 8 additions & 1 deletion examples/using-subscriber/configs/.env
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
APP_NAME=sample-api
HTTP_PORT=8200

LOG_LEVEL=DEBUG

PUBSUB_BACKEND=KAFKA
PUBSUB_BROKER=localhost:9092
CONSUMER_ID=test
PUBSUB_OFFSET=-2

LOG_LEVEL=DEBUG
# For using MQTT uncomment these configs
#PUBSUB_BACKEND=MQTT
#MQTT_PROTOCOL=tcp
#MQTT_HOST=localhost
#MQTT_PORT=8883
#MQTT_CLIENT_ID_SUFFIX=test-subscriber
10 changes: 7 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ require (
cloud.google.com/go/pubsub v1.36.2
github.com/DATA-DOG/go-sqlmock v1.5.2
github.com/alicebob/miniredis/v2 v2.31.1
github.com/eclipse/paho.mqtt.golang v1.4.3
github.com/go-redis/redismock/v9 v9.2.0
github.com/go-sql-driver/mysql v1.7.1
github.com/gogo/protobuf v1.3.2
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/google/uuid v1.6.0
github.com/gorilla/mux v1.8.1
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/joho/godotenv v1.5.1
Expand All @@ -28,6 +31,7 @@ require (
go.opentelemetry.io/otel/sdk/metric v1.24.0
go.opentelemetry.io/otel/trace v1.24.0
go.uber.org/mock v0.4.0
golang.org/x/oauth2 v0.17.0
golang.org/x/term v0.18.0
google.golang.org/api v0.166.0
google.golang.org/grpc v1.61.1
Expand All @@ -53,6 +57,7 @@ require (
github.com/google/s2a-go v0.1.7 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/klauspost/compress v1.16.6 // indirect
github.com/openzipkin/zipkin-go v0.4.2 // indirect
github.com/pierrec/lz4/v4 v4.1.17 // indirect
Expand All @@ -67,9 +72,8 @@ require (
go.einride.tech/aip v0.66.0 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0 // indirect
golang.org/x/crypto v0.19.0 // indirect
golang.org/x/net v0.21.0 // indirect
golang.org/x/oauth2 v0.17.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
Expand Down
14 changes: 10 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQNCyp70xik=
github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
Expand All @@ -67,6 +69,8 @@ github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
Expand Down Expand Up @@ -106,6 +110,8 @@ github.com/googleapis/gax-go/v2 v2.12.1 h1:9F8GV9r9ztXyAi00gsMQHNoF51xPZm8uj1dpY
github.com/googleapis/gax-go/v2 v2.12.1/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
Expand Down Expand Up @@ -223,8 +229,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
Expand All @@ -248,8 +254,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ=
golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA=
Expand Down
Loading

0 comments on commit 38f1294

Please sign in to comment.