decode userId from jwt token
This commit is contained in:
parent
7543dae153
commit
ff2bbb543e
4 changed files with 64 additions and 12 deletions
|
@ -3,17 +3,33 @@ package api
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"regexp"
|
||||||
"weather-data/config"
|
"weather-data/config"
|
||||||
"weather-data/storage"
|
"weather-data/storage"
|
||||||
"weather-data/weathersource"
|
"weather-data/weathersource"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/gorilla/handlers"
|
"github.com/gorilla/handlers"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var userIdHeader = "userid"
|
||||||
|
|
||||||
|
var bearerTokenRegexPattern = "^(?i:Bearer\\s+)([A-Za-z0-9-_=]+\\.[A-Za-z0-9-_=]+\\.?[A-Za-z0-9-_.+\\/=]*)$"
|
||||||
|
|
||||||
|
var bearerTokenRegex *regexp.Regexp = regexp.MustCompile(bearerTokenRegexPattern)
|
||||||
|
|
||||||
|
type UserClaims struct {
|
||||||
|
Uid string `json:"uid"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Roles []string `json:"role"`
|
||||||
|
jwt.StandardClaims
|
||||||
|
}
|
||||||
|
|
||||||
type weatherRestApi struct {
|
type weatherRestApi struct {
|
||||||
connection string
|
connection string
|
||||||
config config.RestConfig
|
config config.RestConfig
|
||||||
|
@ -66,9 +82,7 @@ func (api *weatherRestApi) handleRequests() *mux.Router {
|
||||||
sensorRouter.HandleFunc("/{id}", api.getWeatherSensorHandler).Methods("GET")
|
sensorRouter.HandleFunc("/{id}", api.getWeatherSensorHandler).Methods("GET")
|
||||||
sensorRouter.HandleFunc("/{id}", api.updateWeatherSensorHandler).Methods("PUT")
|
sensorRouter.HandleFunc("/{id}", api.updateWeatherSensorHandler).Methods("PUT")
|
||||||
sensorRouter.HandleFunc("/{id}", api.deleteWeatherSensorHandler).Methods("DELETE")
|
sensorRouter.HandleFunc("/{id}", api.deleteWeatherSensorHandler).Methods("DELETE")
|
||||||
|
sensorRouter.HandleFunc("/{name}", api.registerWeatherSensorHandler).Methods("POST")
|
||||||
//registration
|
|
||||||
router.HandleFunc("/{_dummy:(?i)register/sensor}/{name}", api.registerWeatherSensorHandler).Methods("POST")
|
|
||||||
|
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
|
@ -161,22 +175,22 @@ func (api *weatherRestApi) registerWeatherSensorHandler(w http.ResponseWriter, r
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sensor.UserId = r.Header.Get(userIdHeader)
|
||||||
|
err = api.sensorRegistry.UpdateSensor(sensor)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
w.Header().Add("content-type", "application/json")
|
w.Header().Add("content-type", "application/json")
|
||||||
w.WriteHeader(http.StatusCreated)
|
w.WriteHeader(http.StatusCreated)
|
||||||
json.NewEncoder(w).Encode(sensor)
|
json.NewEncoder(w).Encode(sensor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *weatherRestApi) getAllWeatherSensorHandler(w http.ResponseWriter, r *http.Request) {
|
func (api *weatherRestApi) getAllWeatherSensorHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
var weatherSensors []*storage.WeatherSensor
|
userId := r.Header.Get(userIdHeader)
|
||||||
var err error
|
|
||||||
|
|
||||||
userId := r.URL.Query().Get("userId")
|
weatherSensors, err := api.sensorRegistry.GetSensorsOfUser(userId)
|
||||||
|
|
||||||
if len(userId) == 0 {
|
|
||||||
weatherSensors, err = api.sensorRegistry.GetSensors()
|
|
||||||
} else {
|
|
||||||
weatherSensors, err = api.sensorRegistry.GetSensorsOfUser(userId)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
http.Error(w, "", http.StatusNotFound)
|
||||||
|
@ -225,6 +239,8 @@ func (api *weatherRestApi) updateWeatherSensorHandler(w http.ResponseWriter, r *
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
http.Error(w, "", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sensor.UserId = r.Header.Get(userIdHeader)
|
||||||
sensor.Id = sensorId
|
sensor.Id = sensorId
|
||||||
|
|
||||||
exist, err := api.sensorRegistry.ExistSensor(sensorId)
|
exist, err := api.sensorRegistry.ExistSensor(sensorId)
|
||||||
|
@ -288,6 +304,12 @@ func (api *weatherRestApi) IsAuthorized(next http.Handler) http.Handler {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, err = api.parseToken(r.Header)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if resp.StatusCode == http.StatusOK {
|
if resp.StatusCode == http.StatusOK {
|
||||||
next.ServeHTTP(w, r)
|
next.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
|
@ -297,6 +319,31 @@ func (api *weatherRestApi) IsAuthorized(next http.Handler) http.Handler {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *weatherRestApi) parseToken(header http.Header) (*UserClaims, error) {
|
||||||
|
authorizationHeader, exists := header["Authorization"]
|
||||||
|
if !exists {
|
||||||
|
return nil, errors.New("missing authorization token")
|
||||||
|
}
|
||||||
|
|
||||||
|
jwtFromHeader := bearerTokenRegex.FindStringSubmatch(authorizationHeader[0])[1]
|
||||||
|
|
||||||
|
claims := new(UserClaims)
|
||||||
|
|
||||||
|
_, err := jwt.ParseWithClaims(
|
||||||
|
jwtFromHeader,
|
||||||
|
claims,
|
||||||
|
func(token *jwt.Token) (interface{}, error) {
|
||||||
|
return []byte(api.config.JwtTokenSecret), nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
header.Add(userIdHeader, claims.Uid)
|
||||||
|
}
|
||||||
|
|
||||||
|
return claims, err
|
||||||
|
}
|
||||||
|
|
||||||
//AddNewWeatherDataCallback adds a new callbackMethod for incoming weather data
|
//AddNewWeatherDataCallback adds a new callbackMethod for incoming weather data
|
||||||
func (api *weatherRestApi) AddNewWeatherDataCallback(callback weathersource.NewWeatherDataCallbackFunc) {
|
func (api *weatherRestApi) AddNewWeatherDataCallback(callback weathersource.NewWeatherDataCallbackFunc) {
|
||||||
api.weatherSource.AddNewWeatherDataCallback(callback)
|
api.weatherSource.AddNewWeatherDataCallback(callback)
|
||||||
|
|
|
@ -34,6 +34,7 @@ type RestConfig struct {
|
||||||
AccessControlAllowOriginHeader string
|
AccessControlAllowOriginHeader string
|
||||||
UseTokenAuthorization bool
|
UseTokenAuthorization bool
|
||||||
ValidateTokenUrl string
|
ValidateTokenUrl string
|
||||||
|
JwtTokenSecret string
|
||||||
}
|
}
|
||||||
|
|
||||||
var MongoConfiguration = MongoConfig{
|
var MongoConfiguration = MongoConfig{
|
||||||
|
@ -64,6 +65,7 @@ var RestConfiguration = RestConfig{
|
||||||
AccessControlAllowOriginHeader: getEnv("ACCESS_CONTROL_ALLOW_ORIGIN_HEADER", "*"),
|
AccessControlAllowOriginHeader: getEnv("ACCESS_CONTROL_ALLOW_ORIGIN_HEADER", "*"),
|
||||||
UseTokenAuthorization: getEnvBool("USE_TOKEN_AUTHORIZATION", false),
|
UseTokenAuthorization: getEnvBool("USE_TOKEN_AUTHORIZATION", false),
|
||||||
ValidateTokenUrl: getEnv("JWT_TOKEN_VALIDATION_URL", "https://api.swablab.de/ldap/validateToken"),
|
ValidateTokenUrl: getEnv("JWT_TOKEN_VALIDATION_URL", "https://api.swablab.de/ldap/validateToken"),
|
||||||
|
JwtTokenSecret: getEnv("JWT_TOKEN_SECRET", "my_token_string"),
|
||||||
}
|
}
|
||||||
|
|
||||||
var AllowUnregisteredSensors = getEnvBool("ALLOW_UNREGISTERED_SENSORS", false)
|
var AllowUnregisteredSensors = getEnvBool("ALLOW_UNREGISTERED_SENSORS", false)
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -4,6 +4,7 @@ go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/eclipse/paho.mqtt.golang v1.3.5
|
github.com/eclipse/paho.mqtt.golang v1.3.5
|
||||||
|
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
github.com/gorilla/handlers v1.5.1
|
github.com/gorilla/handlers v1.5.1
|
||||||
github.com/gorilla/mux v1.8.0
|
github.com/gorilla/mux v1.8.0
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -41,6 +41,8 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe
|
||||||
github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
|
github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
|
||||||
github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
|
github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
|
||||||
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
|
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
|
||||||
|
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||||
|
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y=
|
github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y=
|
||||||
|
|
Loading…
Add table
Reference in a new issue