add an example for sessions + view data as requested

This commit is contained in:
Gerasimos (Makis) Maropoulos 2020-11-02 18:46:38 +02:00
parent f1ebddb6d9
commit ed38047385
No known key found for this signature in database
GPG Key ID: 5DBE766BD26A54E7
9 changed files with 241 additions and 12 deletions

View File

@ -221,6 +221,7 @@
* [Badger](sessions/database/badger/main.go)
* [BoltDB](sessions/database/boltdb/main.go)
* [Redis](sessions/database/redis/main.go)
* [View Data](sessions/viewdata)
* Websocket
* [Gorilla FileWatch (3rd-party)](websocket/gorilla-filewatch/main.go)
* [Basic](websocket/basic)

View File

@ -1,7 +1,6 @@
package main
import (
"context"
"time"
"github.com/kataras/iris/v12"
@ -62,14 +61,6 @@ func main() {
app.Listen(":8080")
}
// generateID optionally to set the value for `jwt.ID` on Sign,
// which sets the standard claims value "jti".
// If you use a blocklist with the default Blocklist.GetKey you have to set it.
var generateID = func(*context.Context) string {
id, _ := uuid.NewRandom()
return id.String()
}
func authenticate(ctx iris.Context) {
claims := userClaims{
Username: "kataras",

View File

@ -0,0 +1,25 @@
package main
import "github.com/kataras/iris/v12"
func loginView(ctx iris.Context) {
}
func login(ctx iris.Context) {
}
func logout(ctx iris.Context) {
ctx.Logout()
ctx.Redirect("/", iris.StatusTemporaryRedirect)
}
func createTodo(ctx iris.Context) {
}
func getTodo(ctx iris.Context) {
}

View File

@ -0,0 +1,10 @@
module myapp
go 1.15
require (
github.com/kataras/iris/v12 v12.2.0-alpha.0.20201031040657-23d4c411cadb
github.com/google/uuid v1.1.2
)
replace github.com/kataras/iris/v12 => ../../../../

View File

@ -0,0 +1,89 @@
package main
import (
"time"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/middleware/jwt"
"github.com/kataras/iris/v12/middleware/jwt/blocklist/redis"
// Optionally to set token identifier.
"github.com/google/uuid"
)
var (
signatureSharedKey = []byte("sercrethatmaycontainch@r32length")
signer = jwt.NewSigner(jwt.HS256, signatureSharedKey, 15*time.Minute)
verifier = jwt.NewVerifier(jwt.HS256, signatureSharedKey)
)
func main() {
app := iris.New()
blocklist := redis.NewBlocklist()
verifier.Blocklist = blocklist
verifyMiddleware := verifier.Verify(func() interface{} {
return new(userClaims)
})
app.Get("/", loginView)
api := app.Party("/api")
{
api.Post("/login", login)
api.Post("/logout", verifyMiddleware, logout)
todoAPI := api.Party("/todos", verifyMiddleware)
{
todoAPI.Post("/", createTodo)
todoAPI.Get("/", listTodos)
todoAPI.Get("/{id:uint64}", getTodo)
}
}
protectedAPI := app.Party("/protected", verifyMiddleware)
protectedAPI.Get("/", protected)
protectedAPI.Get("/logout", logout)
// GET http://localhost:8080
// POST http://localhost:8080/api/login
// POST http://localhost:8080/api/logout
// POST http://localhost:8080/api/todos
// GET http://localhost:8080/api/todos
// GET http://localhost:8080/api/todos/{id}
app.Listen(":8080")
}
func authenticate(ctx iris.Context) {
claims := userClaims{
Username: "kataras",
}
// Generate JWT ID.
random, err := uuid.NewRandom()
if err != nil {
ctx.StopWithError(iris.StatusInternalServerError, err)
return
}
id := random.String()
// Set the ID with the jwt.ID.
token, err := signer.Sign(claims, jwt.ID(id))
if err != nil {
ctx.StopWithError(iris.StatusInternalServerError, err)
return
}
ctx.Write(token)
}
func protected(ctx iris.Context) {
claims := jwt.Get(ctx).(*userClaims)
// To the standard claims, e.g. the generated ID:
// jwt.GetVerifiedToken(ctx).StandardClaims.ID
ctx.WriteString(claims.Username)
}

View File

@ -0,0 +1,63 @@
package main
import "golang.org/x/crypto/bcrypt"
func init() {
generateSampleUsers()
}
// User represents our User model.
type User struct {
ID uint64 `json:"id"`
Username string `json:"username"`
HashedPassword []byte `json:"-"`
}
// Users represents a user database.
// For the sake of the tutorial we use a simple slice of users.
var Users []User
func generateSampleUsers() {
Users = []User{
{ID: 1, Username: "vasiliki", HashedPassword: mustGeneratePassword("vasiliki_pass")}, // my grandmother.
{ID: 2, Username: "kataras", HashedPassword: mustGeneratePassword("kataras_pass")}, // me.
{ID: 3, Username: "george", HashedPassword: mustGeneratePassword("george_pass")}, // my young brother.
{ID: 4, Username: "kwstas", HashedPassword: mustGeneratePassword("kwstas_pass")}, // my youngest brother.
}
}
func fetchUser(username, password string) (User, bool) {
for _, u := range Users { // our example uses a static slice.
if u.Username == username {
// we compare the user input and the stored hashed password.
ok := ValidatePassword(password, u.HashedPassword)
if ok {
return u, true
}
}
}
return User{}, false
}
// mustGeneratePassword same as GeneratePassword but panics on errors.
func mustGeneratePassword(userPassword string) []byte {
hashed, err := GeneratePassword(userPassword)
if err != nil {
panic(err)
}
return hashed
}
// GeneratePassword will generate a hashed password for us based on the
// user's input.
func GeneratePassword(userPassword string) ([]byte, error) {
return bcrypt.GenerateFromPassword([]byte(userPassword), bcrypt.DefaultCost)
}
// ValidatePassword will check if passwords are matched.
func ValidatePassword(userPassword string, hashed []byte) bool {
err := bcrypt.CompareHashAndPassword(hashed, []byte(userPassword))
return err == nil
}

View File

@ -0,0 +1,42 @@
package main
import (
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/sessions"
)
func main() {
app := iris.New()
app.RegisterView(iris.HTML("./views", ".html"))
sess := sessions.New(sessions.Config{Cookie: "session_cookie", AllowReclaim: true})
app.Use(sess.Handler())
// ^ use app.UseRouter instead to access sessions on HTTP errors too.
// Register our custom middleware, after the sessions middleware.
app.Use(setSessionViewData)
app.Get("/", index)
app.Listen(":8080")
}
func setSessionViewData(ctx iris.Context) {
session := sessions.Get(ctx)
ctx.ViewData("session", session)
ctx.Next()
}
func index(ctx iris.Context) {
session := sessions.Get(ctx)
session.Set("username", "kataras")
ctx.View("index")
/* OR without middleware:
ctx.View("index", iris.Map{
"session": session,
// {{.session.Get "username"}}
// OR to pass only the 'username':
// "username": session.Get("username"),
// {{.username}}
})
*/
}

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sessions View Data</title>
</head>
<body>
Hello {{.session.Get "username"}}
</body>
</html>

View File

@ -4,7 +4,6 @@ import (
"context"
"io"
"sync/atomic"
"time"
"github.com/kataras/iris/v12/core/host"
"github.com/kataras/iris/v12/middleware/jwt"
@ -30,7 +29,6 @@ type Client interface {
// Blocklist is a jwt.Blocklist backed by Redis.
type Blocklist struct {
Clock func() time.Time // Required. Defaults to time.Now.
// GetKey is a function which can be used how to extract
// the unique identifier for a token.
// Required. By default the token key is extracted through the claims.ID ("jti").
@ -67,7 +65,6 @@ var _ jwt.Blocklist = (*Blocklist)(nil)
// verifier.Blocklist = blocklist
func NewBlocklist() *Blocklist {
return &Blocklist{
Clock: time.Now,
GetKey: defaultGetKey,
Prefix: "",
ClientOptions: Options{