Skip to content

Commit 38f1294

Browse files
author
Vipul Rawat
authored
Merge pull request #376 from gofr-dev/development
Release v1.1.0
2 parents fd52bcd + 67ee4ff commit 38f1294

File tree

33 files changed

+2705
-304
lines changed

33 files changed

+2705
-304
lines changed
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# HTTP Authentication
2+
Authentication is a crucial aspect of web applications, controlling access to resources based on user roles or permissions.
3+
It is the process of verifying a user's identity to grant access to protected resources. It ensures only
4+
authenticated users can perform actions or access data within an application.
5+
6+
GoFr offer various approaches to implement authorization.
7+
8+
## 1. HTTP Basic Auth
9+
*Basic Authentication* is a simple HTTP authentication scheme where the user's credentials (username and password) are
10+
transmitted in the request header in a Base64-encoded format.
11+
12+
Basic auth is the simplest way to authenticate your APIs. It's built on
13+
[HTTP protocol authentication scheme](https://datatracker.ietf.org/doc/html/rfc7617). It involves sending the term
14+
`Basic` trailed by the Base64-encoded `<username>:<password>` within the standard `Authorization` header.
15+
16+
### Basic Authentication in GoFr
17+
18+
GoFr offers two ways to implement basic authentication:
19+
20+
**1. Predefined Credentials**
21+
22+
Use `EnableBasicAuth(username, password)` to configure Gofr with pre-defined credentials.
23+
24+
```go
25+
func main() {
26+
app := gofr.New()
27+
28+
app.EnableBasicAuth("admin", "secret_password") // Replace with your credentials
29+
30+
app.GET("/protected-resource", func(c *gofr.Context) (interface{}, error) {
31+
// Handle protected resource access
32+
return nil, nil
33+
})
34+
35+
app.Run()
36+
}
37+
```
38+
39+
**2. Custom Validation Function**
40+
41+
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.
42+
43+
```go
44+
func validateUser(username string, password string) bool {
45+
// Implement your credential validation logic here
46+
// This example uses hardcoded credentials for illustration only
47+
return username == "john" && password == "doe123"
48+
}
49+
50+
func main() {
51+
app := gofr.New()
52+
53+
app.EnableBasicAuthWithFunc(validateUser)
54+
55+
app.GET("/secure-data", func(c *gofr.Context) (interface{}, error) {
56+
// Handle access to secure data
57+
return nil, nil
58+
})
59+
60+
app.Run()
61+
}
62+
```
63+
64+
### Adding Basic Authentication to HTTP Services
65+
66+
This code snippet demonstrates how to add basic authentication to an HTTP service in GoFr and make a request with the appropriate Authorization header:
67+
68+
```go
69+
app.AddHTTPService("order", "https://localhost:2000",
70+
&service.Authentication{UserName: "abc", Password: "pass"},
71+
)
72+
```
73+
74+
## 2. API Keys Auth
75+
Users include a unique API key in the request header for validation against a store of authorized keys.
76+
77+
### Usage:
78+
GoFr offers two ways to implement API Keys authentication.
79+
80+
**1. Framework Default Validation**
81+
- Users can select the framework's default validation using **_EnableAPIKeyAuth(apiKeys ...string)_**
82+
83+
```go
84+
package main
85+
86+
func main() {
87+
// initialise gofr object
88+
app := gofr.New()
89+
90+
app.EnableAPIKeyAuth("9221e451-451f-4cd6-a23d-2b2d3adea9cf", "0d98ecfe-4677-48aa-b463-d43505766915")
91+
92+
app.GET("/customer", Customer)
93+
94+
app.Run()
95+
}
96+
```
97+
98+
**2. Custom Validation Function**
99+
- Users can create their own validator function `apiKeyValidator(apiKey string) bool` for validating APIKeys and pass the func in **_EnableAPIKeyAuthWithFunc(validator)_**
100+
101+
```go
102+
package main
103+
104+
func apiKeyValidator(apiKey string) bool {
105+
validKeys := []string{"f0e1dffd-0ff0-4ac8-92a3-22d44a1464e4", "d7e4b46e-5b04-47b2-836c-2c7c91250f40"}
106+
107+
return slices.Contains(validKeys, apiKey)
108+
}
109+
110+
func main() {
111+
// initialise gofr object
112+
app := gofr.New()
113+
114+
app.EnableAPIKeyAuthWithFunc(apiKeyValidator)
115+
116+
app.GET("/customer", Customer)
117+
118+
app.Run()
119+
}
120+
```
121+
122+
### Adding API-KEY Authentication to HTTP Services
123+
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:
124+
125+
```go
126+
app.AddHTTPService("http-server-using-redis", "http://localhost:8000", &service.APIKeyConfig{APIKey: "9221e451-451f-4cd6-a23d-2b2d3adea9cf"})
127+
```
128+
129+
## 3. OAuth 2.0
130+
OAuth 2.0 is the industry-standard protocol for authorization.
131+
It focuses on client developer simplicity while providing specific authorization flows for web applications, desktop applications, mobile phones, and living room devices.
132+
To know more about it refer [here](https://www.rfc-editor.org/rfc/rfc6749)
133+
134+
It involves sending the term `Bearer` trailed by the encoded token within the standard `Authorization` header.
135+
136+
### OAuth Authentication in GoFr
137+
138+
GoFr supports authenticating tokens encoded by algorithm `RS256/384/512`.
139+
140+
### App level Authentication
141+
Enable OAuth 2.0 with three-legged flow to authenticate requests
142+
143+
Use `EnableOAuth(jwks-endpoint,refresh_interval)` to configure Gofr with pre-defined credentials.
144+
145+
```go
146+
func main() {
147+
app := gofr.New()
148+
149+
app.EnableOAuth("http://jwks-endpoint", 20)
150+
151+
app.GET("/protected-resource", func(c *gofr.Context) (interface{}, error) {
152+
// Handle protected resource access
153+
return nil, nil
154+
})
155+
156+
app.Run()
157+
}
158+
```
159+
160+
### Adding OAuth Authentication to HTTP Services
161+
For server-to-server communication it follows two-legged OAuth, also known as "client credentials" flow,
162+
where the client application directly exchanges its own credentials (ClientID and ClientSecret)
163+
for an access token without involving any end-user interaction.
164+
165+
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.
166+
167+
```go
168+
a.AddHTTPService("orders", "http://localhost:9000",
169+
&service.OAuthConfig{ // Replace with your credentials
170+
ClientID: "0iyeGcLYWudLGqZfD6HvOdZHZ5TlciAJ",
171+
ClientSecret: "GQXTY2f9186nUS3C9WWi7eJz8-iVEsxq7lKxdjfhOJbsEPPtEszL3AxFn8k_NAER",
172+
TokenURL: "https://dev-zq6tvaxf3v7p0g7j.us.auth0.com/oauth/token",
173+
Scopes: []string{"read:order"},
174+
EndpointParams: map[string][]string{
175+
"audience": {"https://dev-zq6tvaxf3v7p0g7j.us.auth0.com/api/v2/"},
176+
},
177+
})
178+
```

docs/advanced-guide/using-publisher-subscriber/page.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,36 @@ docker run --name=gcloud-emulator -d -p 8086:8086 \
7373
> **Note**: In Google PubSub only one subscription name can access one topic, framework appends the topic name and subscription name to form the
7474
> unique subscription name on the Google client.
7575
76+
### Mqtt
77+
78+
#### Configs
79+
```dotenv
80+
PUBSUB_BACKEND=MQTT // using Mqtt as pubsub
81+
MQTT_HOST=localhost // broker host url
82+
MQTT_PORT=1883 // broker port
83+
MQTT_CLIENT_ID_SUFFIX=test // suffix to a random generated client-id(uuid v4)
84+
85+
#some additional configs(optional)
86+
MQTT_PROTOCOL=tcp // protocol for connecting to broker can be tcp, tls, ws or wss
87+
MQTT_MESSAGE_ORDER=true // config to maintain/retain message publish order, by defualt this is false
88+
MQTT_USER=username // authentication username
89+
MQTT_PASSWORD=password // authentication password
90+
```
91+
> **Note** : If `MQTT_HOST` config is not provided, the application will connect to a public broker
92+
> [HiveMQ](https://www.hivemq.com/mqtt/public-mqtt-broker/)
93+
94+
#### Docker setup
95+
```shell
96+
docker run -d \
97+
--name mqtt \
98+
-p 8883:8883 \
99+
-v <path-to>/mosquitto.conf:/mosquitto/config/mosquitto.conf \
100+
eclipse-mosquitto:latest
101+
```
102+
> **Note**: find the default mosquitto config file [here](https://github.com/eclipse/mosquitto/blob/master/mosquitto.conf)
103+
104+
105+
76106
## Subscribing to Pub/Sub
77107
Adding a subscriber is similar to adding an HTTP handler, which makes it easier to develop scalable applications,
78108
as it decoupled from the Sender/Publisher.

docs/navigation.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ export const navigation = [
1616
{ title: 'Publishing Custom Metrics', href: '/docs/advanced-guide/publishing-custom-metrics' },
1717
{ title: 'Custom Spans in Tracing', href: '/docs/advanced-guide/custom-spans-in-tracing' },
1818
{ title: 'HTTP Communication', href: '/docs/advanced-guide/http-communication' },
19+
{ title: 'HTTP Authentication', href: '/docs/advanced-guide/http-authentication' },
1920
{ title: 'Circuit Breaker Support', href: '/docs/advanced-guide/circuit-breaker' },
2021
{ title: 'Monitoring Service Health', href: '/docs/advanced-guide/monitoring-service-health' },
2122
{ title: 'Handling Data Migrations', href: '/docs/advanced-guide/handling-data-migrations' },
2223
{ title: 'Writing gRPC Server', href: '/docs/advanced-guide/grpc' },
24+
{ title: 'Using Publisher and Subscriber', href: '/docs/advanced-guide/using-publisher-subscriber' }
2325
// { title: 'Dealing with Remote Files', href: '/docs/advanced-guide/remote-files' },
2426
// { title: 'Supporting OAuth', href: '/docs/advanced-guide/oauth' },
2527
// { title: 'Creating a Static File Server', href: '/docs/advanced-guide/static-file-server' },
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
APP_NAME=sample-api
22
HTTP_PORT=8000
33

4-
LOG_LEVEL=DEBUG
5-
64
REDIS_HOST=localhost
75
REDIS_PORT=2002
86

7+
LOG_LEVEL=DEBUG
8+
9+
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
APP_NAME=sample-api
22
HTTP_PORT=8100
33

4+
LOG_LEVEL=DEBUG
5+
46
PUBSUB_BACKEND=KAFKA
57
PUBSUB_BROKER=localhost:9092
68
CONSUMER_ID=test
79

8-
LOG_LEVEL=DEBUG
10+
# For using MQTT uncomment these configs
11+
#PUBSUB_BACKEND=MQTT
12+
#MQTT_PROTOCOL=tcp
13+
#MQTT_HOST=localhost
14+
#MQTT_PORT=8883
15+
#MQTT_CLIENT_ID_SUFFIX=test-publisher
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
APP_NAME=sample-api
22
HTTP_PORT=8200
33

4+
LOG_LEVEL=DEBUG
5+
46
PUBSUB_BACKEND=KAFKA
57
PUBSUB_BROKER=localhost:9092
68
CONSUMER_ID=test
79
PUBSUB_OFFSET=-2
810

9-
LOG_LEVEL=DEBUG
11+
# For using MQTT uncomment these configs
12+
#PUBSUB_BACKEND=MQTT
13+
#MQTT_PROTOCOL=tcp
14+
#MQTT_HOST=localhost
15+
#MQTT_PORT=8883
16+
#MQTT_CLIENT_ID_SUFFIX=test-subscriber

go.mod

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ require (
66
cloud.google.com/go/pubsub v1.36.2
77
github.com/DATA-DOG/go-sqlmock v1.5.2
88
github.com/alicebob/miniredis/v2 v2.31.1
9+
github.com/eclipse/paho.mqtt.golang v1.4.3
910
github.com/go-redis/redismock/v9 v9.2.0
1011
github.com/go-sql-driver/mysql v1.7.1
1112
github.com/gogo/protobuf v1.3.2
13+
github.com/golang-jwt/jwt/v5 v5.2.1
14+
github.com/google/uuid v1.6.0
1215
github.com/gorilla/mux v1.8.1
1316
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
1417
github.com/joho/godotenv v1.5.1
@@ -28,6 +31,7 @@ require (
2831
go.opentelemetry.io/otel/sdk/metric v1.24.0
2932
go.opentelemetry.io/otel/trace v1.24.0
3033
go.uber.org/mock v0.4.0
34+
golang.org/x/oauth2 v0.17.0
3135
golang.org/x/term v0.18.0
3236
google.golang.org/api v0.166.0
3337
google.golang.org/grpc v1.61.1
@@ -53,6 +57,7 @@ require (
5357
github.com/google/s2a-go v0.1.7 // indirect
5458
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
5559
github.com/googleapis/gax-go/v2 v2.12.1 // indirect
60+
github.com/gorilla/websocket v1.5.0 // indirect
5661
github.com/klauspost/compress v1.16.6 // indirect
5762
github.com/openzipkin/zipkin-go v0.4.2 // indirect
5863
github.com/pierrec/lz4/v4 v4.1.17 // indirect
@@ -67,9 +72,8 @@ require (
6772
go.einride.tech/aip v0.66.0 // indirect
6873
go.opencensus.io v0.24.0 // indirect
6974
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0 // indirect
70-
golang.org/x/crypto v0.19.0 // indirect
71-
golang.org/x/net v0.21.0 // indirect
72-
golang.org/x/oauth2 v0.17.0 // indirect
75+
golang.org/x/crypto v0.21.0 // indirect
76+
golang.org/x/net v0.22.0 // indirect
7377
golang.org/x/sync v0.6.0 // indirect
7478
golang.org/x/sys v0.18.0 // indirect
7579
golang.org/x/text v0.14.0 // indirect

go.sum

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
4343
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4444
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
4545
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
46+
github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQNCyp70xik=
47+
github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE=
4648
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
4749
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
4850
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -67,6 +69,8 @@ github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9
6769
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
6870
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
6971
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
72+
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
73+
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
7074
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
7175
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
7276
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
@@ -106,6 +110,8 @@ github.com/googleapis/gax-go/v2 v2.12.1 h1:9F8GV9r9ztXyAi00gsMQHNoF51xPZm8uj1dpY
106110
github.com/googleapis/gax-go/v2 v2.12.1/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc=
107111
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
108112
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
113+
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
114+
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
109115
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
110116
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
111117
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
@@ -223,8 +229,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
223229
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
224230
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
225231
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
226-
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
227-
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
232+
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
233+
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
228234
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
229235
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
230236
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -248,8 +254,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
248254
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
249255
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
250256
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
251-
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
252-
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
257+
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
258+
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
253259
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
254260
golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ=
255261
golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA=

0 commit comments

Comments
 (0)