Saturday, August 29, 2015

Day 18 - How to get a token from a JWT server

There is a wonderful middleware for ant0ine/go-json-rest to implement JWT for go: go-json-rest-middleware-jwt

The problem I had is that the docu seems not to be working for curl on windows, the go code is alright, only the curl command line is a problem:

So here is a windows example of how to make a test call with curl to get a JWT token:

-- snip
curl -X POST --data "{\"username\": \"admin\", \"password\": \"admin\"}" -H "Content-Type:application/json" http://localhost:8080/login
 -- snip

-- output should be something like this:
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NDA4NjAzMzgsImlkIjoiYWRtaW4iLCJvcmlnX2lhdCI6MTQ0MDg1NjczOH0.cIIACBWOFCMZI4vBgSdQXkUsm8f7WpRoSoFtmoOtceQ"
--output

Docu of jwt with json-rest
https://github.com/ant0ine/go-json-rest#jwt

Full source of my example app:
intogooglego/restPostServer


--- demo ---


    i.jwt_middleware = &jwt.JWTMiddleware{
        Key:        []byte("secret key"),
        Realm:      "jwt auth",
        Timeout:    time.Hour,
        MaxRefresh: time.Hour * 24,
        Authenticator: func(userId string, password string) bool {
            if debugLevel > 2 {
                fmt.Printf("Authenticator: '%s' - '%s'\n", userId, password)
            }
            return userId == "admin" && password == "admin"
        },
    }

    api := rest.NewApi()

    var MiddleWareStack = []rest.Middleware{
        &rest.AccessLogApacheMiddleware{},
        &rest.TimerMiddleware{},
        &rest.RecorderMiddleware{},
        //&rest.PoweredByMiddleware{},
        &rest.RecoverMiddleware{
            EnableResponseStackTrace: true,
        },
        &rest.JsonIndentMiddleware{},
        &rest.ContentTypeCheckerMiddleware{},
    }
    statusMw := &rest.StatusMiddleware{}

    api.Use(statusMw)

    api.Use(MiddleWareStack...)

    api.Use(&rest.IfMiddleware{
        Condition: func(request *rest.Request) bool {
            if debugLevel > 2 {
                fmt.Printf("AUTH Request.URL.Path: '%s' returning '%b'\n", request.URL.Path, request.URL.Path != "/login")
            }
            return request.URL.Path != "/login"
        },
        IfTrue: i.jwt_middleware,
    })

    router, err := rest.MakeRouter(

        // JSON
        rest.Get("/j/t/:postid", i.JsonGetPostThreadComments),
        rest.Get("/j/p/:orderby", i.JsonGetPosts),

        // HTML
        rest.Get("/", i.SendStaticMainHtml),
        rest.Get("/t/:postid", i.SendStaticCommentsHtml),

        // Auth JWT
        rest.Post("/login", i.jwt_middleware.LoginHandler),
        rest.Get("/jwttest", i.JwtTest),
        rest.Post("/jwtposttest", i.JwtPostTest),
        rest.Get("/refresh_token", i.jwt_middleware.RefreshHandler),

        // JSON Depricated
        rest.Get("/p/:orderby", i.JsonGetAllPosts),
        rest.Get("/p", i.JsonGetAllPosts),

        // HTML, Images, CSS and JS
        rest.Get("/img/#filename", i.SendStaticImage),
        rest.Get("/css", i.SendStaticCss),
        rest.Get("/css/#cssfile", i.SendStaticCss),
        rest.Get("/js/#jsfile", i.SendStaticJS),
        rest.Get("/js", i.SendStaticJS),

        rest.Get("/html/*filename", i.GetHtmlFile),
        rest.Get("/test/*filename", i.GetTestFile),

        rest.Get("/.status", func(w rest.ResponseWriter, r *rest.Request) {
            w.WriteJson(statusMw.GetStatus())
        }),
    )
    if err != nil {
        log.Fatal(err)
    }
    api.SetApp(router)

    //http.Handle("/static/", http.StripPrefix("/static", http.FileServer(http.Dir("."))))
    http.Handle("/api/", http.StripPrefix("/api", api.MakeHandler()))
    http.Handle("/", api.MakeHandler())

    if debugLevel > 2 {
        fmt.Println("Starting http.ListenAndServe :8080")
    }
    //log.Fatal(http.ListenAndServe(":8080", api.MakeHandler()))
    log.Fatal(http.ListenAndServe(":8080", nil))
}
--- demo ---