From 549cce375671be7ea7c91d8cd1793a4b27c17281 Mon Sep 17 00:00:00 2001 From: UnicodingUnicorn <7555ic@gmail.com> Date: Sun, 10 Feb 2019 18:43:02 +0800 Subject: [PATCH] Initial commit --- .gitignore | 12 +++++++++++ README.md | 26 ++++++++++++++++++++++- main.go | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 main.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f2dd955 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out diff --git a/README.md b/README.md index f187868..b373cbe 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,27 @@ # backend-login -Beep backend handling login. \ No newline at end of file +Beep backend handling login. For now, just a POST endpoint returning a JWT. In the furture, SMS-based perpetual login. + +## API (temporary) + +``` +POST /login +``` + +### Body + +| Name | Type | Description | Required | +| ---- | ---- | ----------- | -------- | +| user | String | User's ID. | ✓ | +| device | String | Device's ID. Must be unique to the device. I suggest something based on MAC address. | ✓ | + +### Success (200 OK) + +JWT token. + +### Errors + +| Code | Description | +| ---- | ----------- | +| 400 | Required fields in body were not supplied | +| 500 | Error creating the JWT | diff --git a/main.go b/main.go new file mode 100644 index 0000000..2a5da04 --- /dev/null +++ b/main.go @@ -0,0 +1,60 @@ +package main + +import ( + "encoding/json" + "flag" + "log" + "net/http" + + "github.com/julienschmidt/httprouter" + "github.com/dgrijalva/jwt-go" +) + +var listen string +var secret []byte + +func main() { + var s string + // Parse flags + flag.StringVar(&listen, "listen", ":8080", "host and port to listen on") + flag.StringVar(&s, "secret", "secret", "JWT secret") + flag.Parse() + + secret = []byte(s) + + // Routes + router := httprouter.New() + + router.POST("/login", Login); + + // Start server + log.Printf("starting server on %s", listen) + log.Fatal(http.ListenAndServe(listen, router)) +} + +type LoginData struct { + ID string `json:"id"` + Client string `json:"client"` +} + +func Login(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + login := LoginData {} + decoder := json.NewDecoder(r.Body) + err := decoder.Decode(&login) + if err != nil { + http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + return + } + + token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims { + "id": login.ID, + "client": login.Client, + }) + + tokenString, err := token.SignedString(secret) + if err != nil { + http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + } + + w.Write([]byte(tokenString)) +}