func Login(w http.ResponseWriter, r *http.Request, urlValues map[string]string, db *xorm.Engine) { //handle the input var input struct { Email string `json:"email" validate:"required"` Password string `json:"password" validate:"required"` } if err := httputil.Bind(r.Body, &input); err != nil { middleware.Send(w, http.StatusBadRequest, map[string]string{"error": err.Error()}) return } user := model.User{} found, err := db.Where("email = ?", input.Email).Get(&user) if err != nil { middleware.Send(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } if found == false || bcrypt.CompareHashAndPassword([]byte(user.PasswordDigest), []byte(input.Password)) != nil { middleware.Send(w, http.StatusUnauthorized, map[string]string{"error": "Incorrect Email / Password"}) return } if newToken, err := auth.Sign(user.Id); err != nil { middleware.Send(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) } else { // update JWT Token w.Header().Add("Authorization", newToken) //allow CORS w.Header().Set("Access-Control-Expose-Headers", "Authorization") middleware.Send(w, http.StatusOK, map[string]string{"userId": user.Id}) } }
func UserCreate(w http.ResponseWriter, r *http.Request, urlValues map[string]string, db *xorm.Engine) { user := struct { model.User `xorm:"extends"` Password string `xorm:"-" json:"password" validate:"required"` }{} if err := httputil.Bind(r.Body, &user); err != nil { middleware.Send(w, http.StatusBadRequest, map[string]string{"error": err.Error()}) return } user.Id = uuid.NewV4().String() if digest, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost); err != nil { middleware.Send(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } else { user.PasswordDigest = string(digest) } session := db.NewSession() if err := session.Begin(); err != nil { middleware.Send(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } defer session.Close() if statusCode, err := createRecord(&user, session); err != nil { middleware.Send(w, statusCode, map[string]string{"error": err.Error()}) return } if err := session.Commit(); err != nil { middleware.Send(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } if newToken, err := auth.Sign(user.Id); err != nil { middleware.Send(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) } else { // update JWT Token w.Header().Add("Authorization", newToken) //allow CORS w.Header().Set("Access-Control-Expose-Headers", "Authorization") middleware.Send(w, http.StatusOK, map[string]string{"userId": user.Id}) } }
// a middleware to handle user authorization func Auth(f Handler) http.HandlerFunc { return func(res http.ResponseWriter, req *http.Request) { userId, err := auth.Verify(req.Header.Get("Authorization")) if err != nil { Send(res, http.StatusUnauthorized, map[string]string{"error": err.Error()}) return } else { if newToken, err := auth.Sign(userId); err != nil { Send(res, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } else { res.Header().Add("Authorization", newToken) // update JWT Token } } //everything seems fine, goto the business logic handler if statusCode, err, output := f(req, mux.Vars(req), db, userId); err == nil { Send(res, statusCode, output) } else { Send(res, statusCode, map[string]string{"error": err.Error()}) } } }
// a middleware to handle user authorization func AuthAndTx(f HandlerWithTx) http.HandlerFunc { return func(res http.ResponseWriter, req *http.Request) { userId, err := auth.Verify(req.Header.Get("Authorization")) if err != nil { Send(res, http.StatusUnauthorized, map[string]string{"error": err.Error()}) return } else { if newToken, err := auth.Sign(userId); err != nil { Send(res, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } else { res.Header().Add("Authorization", newToken) // update JWT Token } } //prepare a database session for the handler session := db.NewSession() if err := session.Begin(); err != nil { Send(res, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } defer session.Close() //everything seems fine, goto the business logic handler if statusCode, err, output := f(req, mux.Vars(req), session, userId); err == nil { //the business logic handler return no error, then try to commit the db session if err := session.Commit(); err != nil { Send(res, http.StatusInternalServerError, map[string]string{"error": err.Error()}) } else { Send(res, statusCode, output) } } else { session.Rollback() Send(res, statusCode, map[string]string{"error": err.Error()}) } } }