Skip to content

Integration with gin gonic

kenng edited this page May 28, 2016 · 3 revisions

Integration With Gin-Gonic

Following example is work in progress, and it may not be the best practice, but it's just working! To build it:

  • replace the content in authboss-sample/blog.go with the following.
  • create a folder resources/views/gin-gonic and put your header.tmpl, footer.tmpl, layout.tmpl etc here
    Then go build and run it
package main

import (
	"encoding/base64"
	"html/template"
	"log"
	"net/http"
	"os"
	"time"
	"github.com/gin-gonic/gin/render"
	"path/filepath"

	// plugin package
	"github.com/gin-gonic/gin"
	"github.com/gorilla/securecookie"
	"github.com/gorilla/sessions"
	"github.com/justinas/nosurf"
	"gopkg.in/authboss.v0"
	// register authboss register module
	_ "gopkg.in/authboss.v0/register"
	// register authboss login module
	_ "gopkg.in/authboss.v0/auth"
	// to confirm authboss
	_ "gopkg.in/authboss.v0/confirm"
	// to lock user after N authentication failures
	_ "gopkg.in/authboss.v0/lock"
	_ "gopkg.in/authboss.v0/recover"
	_ "gopkg.in/authboss.v0/remember"
)

var funcs = template.FuncMap{
	"formatDate": func(date time.Time) string {
		return date.Format("2006/01/02 03:04pm")
	},
	"yield": func() string { return "" },
}

var ab *authboss.Authboss

func layoutData(w http.ResponseWriter, r *http.Request) authboss.HTMLData {
	currentUserName := ""
	userInter, err := ab.CurrentUser(w, r)
	if userInter != nil && err == nil {
		currentUserName = userInter.(*User).Name
	}

	return authboss.HTMLData{
		"loggedin":               userInter != nil,
		"username":               "username",
		authboss.FlashSuccessKey: ab.FlashSuccess(w, r),
		authboss.FlashErrorKey:   ab.FlashError(w, r),
		"current_user_name":      currentUserName,
	}
}

func initAuthBossPolicy(ab *authboss.Authboss)  {
	ab.Policies = []authboss.Validator{
		authboss.Rules{
			FieldName:       "email",
			Required:        true,
			AllowWhitespace: false,
		},
		authboss.Rules{
			FieldName:       "password",
			Required:        true,
			MinLength:       4,
			MaxLength:       8,
			AllowWhitespace: false,
		},
	}
}

func initAuthBossLayout(ab *authboss.Authboss, r *gin.Engine) {
	if os.Getenv(gin.ENV_GIN_MODE) == gin.ReleaseMode {
		ab.Layout = r.HTMLRender.(render.HTMLProduction).Template.Funcs(funcs).Lookup("authboss.tmpl")
	} else {
		html := r.HTMLRender.(render.HTMLDebug).Instance("authboss.tmpl", nil).(render.HTML)
		ab.Layout = html.Template.Funcs(template.FuncMap(funcs)).Lookup("authboss.tmpl")
		// ab.Layout.ExecuteTemplate(os.Stdout, "layout.html.tpl", nil)
	}
}

var database = NewMemStorer()

func initAuthBossParam(r *gin.Engine) *authboss.Authboss {
	ab := authboss.New()
	ab.Storer = database
	ab.CookieStoreMaker = NewCookieStorer
	ab.SessionStoreMaker = NewSessionStorer
	ab.ViewsPath = filepath.Join("ab_views")
	//ab.RootURL = `http://localhost:5567`

	ab.LayoutDataMaker = layoutData

	ab.MountPath = "/auth"
	ab.LogWriter = os.Stdout

	ab.XSRFName = "csrf_token"
	ab.XSRFMaker = func(_ http.ResponseWriter, r *http.Request) string {
		return nosurf.Token(r)
	}

	initAuthBossLayout(ab, r)
	ab.Mailer = authboss.LogMailer(os.Stdout)
	initAuthBossPolicy(ab)

	if err := ab.Init(); err != nil {
		// Handle error, don't let program continue to run
		log.Fatalln(err)
	}
	return ab
}

func initAuthBossRoute(r *gin.Engine) {
	cookieStoreKey, _ := base64.StdEncoding.DecodeString(`NpEPi8pEjKVjLGJ6kYCS+VTCzi6BUuDzU0wrwXyf5uDPArtlofn2AG6aTMiPmN3C909rsEWMNqJqhIVPGP3Exg==`)
	sessionStoreKey, _ := base64.StdEncoding.DecodeString(`AbfYwmmt8UCwUuhd9qvfNA9UCuN1cVcKJN1ofbiky6xCyyBj20whe40rJa3Su0WOWLWcPpO1taqJdsEI/65+JA==`)
	cookieStore = securecookie.New(cookieStoreKey, nil)
	sessionStore = sessions.NewCookieStore(sessionStoreKey)
	ab = initAuthBossParam(r)
	r.Any("/auth/*w", gin.WrapH(ab.NewRouter()))
}

func main()  {

    r := gin.Default()

    r.Static("resources", "./resources")

    r.LoadHTMLGlob("resources/views/gin-gonic/*")

    r.GET("/", func(c *gin.Context) {
        data := layoutData(c.Writer, c.Request)
        c.HTML(http.StatusOK, "index.tmpl", data)
    })

    initAuthBossRoute(r)

    r.Run(":3000")
}
  • authboss.tmpl
{{template "header" .}}

	{{with .flash_success}}<div class="alert alert-success">{{.}}</div>{{end}}
	{{with .flash_error}}<div class="alert alert-danger">{{.}}</div>{{end}}
	{{template "yield" .}}
	{{template "authboss" .}}

</body>
</html>
{{define "pagetitle"}}{{end}}
{{define "yield"}}{{end}}
{{define "authboss"}}{{end}}
  • header.tmpl
{{define "header"}}
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">

	<title>{{template "pagetitle" .}}</title>

	<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" />
	<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" />

	<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
	<script type="text/javascript" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
</head>
<body class="container-fluid" style="padding-top: 15px;">
	<nav class="navbar navbar-default">
		<div class="container-fluid">
			<div class="navbar-header">
				<a class="navbar-brand" href="/">Auth-Blog</a>
			</div>

			<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
				<ul class="nav navbar-nav navbar-right">
					{{if not .loggedin}}
					<li><a href="/auth/register">Register</a></li>
					<li><a href="/auth/login"><i class="fa fa-sign-in"></i> Login</a></li>
					{{else}}
					<li class="dropdown">
						<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Welcome {{.current_user_name}}! <span class="caret"></span></a>
						<ul class="dropdown-menu" role="menu">
							<li>
								<a href="/auth/logout">
									<i class="fa fa-sign-out"></i> Logout
								</a>
							</li>
						</ul>
					</li>
					{{end}}
				</ul>
			</div>
		</div>
	</nav>

{{end}}
  • index.tmpl
{{ template "header" .}}

<h1>This is Authboss Home</h1>

</body>
</html>