package helper import ( "net/http" "strconv" "time" "github.com/golang-jwt/jwt/v4" ) // WARNING this key should be secret and constant between deployments. // If you use this software in the wild, at the very least change this value! // https://www.sohamkamani.com/golang/jwt-authentication/ var jwt_key = []byte("iph7noo1ohQuam5sou5wa2aeChixo7") func IssueToken(uid int, writer http.ResponseWriter) error { expiration := time.Now().Add(60 * time.Minute) token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.RegisteredClaims{ Subject: strconv.Itoa(uid), ExpiresAt: jwt.NewNumericDate(expiration), Issuer: "react-go-forum", }) token_string, err := token.SignedString(jwt_key) if err != nil { return err } http.SetCookie(writer, &http.Cookie{ Name: "token", Value: token_string, Expires: expiration, SameSite: http.SameSiteStrictMode, Path: "/", }) return nil } // Returns a non-nil RegisteredClaims if valid, nil otherwise. Handles responding to bad tokens. func GetValidClaims(writer http.ResponseWriter, request *http.Request) *jwt.RegisteredClaims { cookie, err := request.Cookie("token") if err != nil { if err == http.ErrNoCookie { WriteErrorJson("access denied", writer, http.StatusUnauthorized) return nil } WriteInternalErrorJson(err, writer) return nil } claims := &jwt.RegisteredClaims{} token, err := jwt.ParseWithClaims(cookie.Value, claims, func(token *jwt.Token) (interface{}, error) { return jwt_key, nil }) if err != nil { WriteInternalErrorJson(err, writer) return nil } if !token.Valid { WriteErrorJson("access denied", writer, http.StatusUnauthorized) return nil } return claims }