mirror of
https://github.com/kataras/iris.git
synced 2025-02-02 15:30:36 +01:00
add an example for sessions + view data as requested
This commit is contained in:
parent
f1ebddb6d9
commit
ed38047385
|
@ -221,6 +221,7 @@
|
||||||
* [Badger](sessions/database/badger/main.go)
|
* [Badger](sessions/database/badger/main.go)
|
||||||
* [BoltDB](sessions/database/boltdb/main.go)
|
* [BoltDB](sessions/database/boltdb/main.go)
|
||||||
* [Redis](sessions/database/redis/main.go)
|
* [Redis](sessions/database/redis/main.go)
|
||||||
|
* [View Data](sessions/viewdata)
|
||||||
* Websocket
|
* Websocket
|
||||||
* [Gorilla FileWatch (3rd-party)](websocket/gorilla-filewatch/main.go)
|
* [Gorilla FileWatch (3rd-party)](websocket/gorilla-filewatch/main.go)
|
||||||
* [Basic](websocket/basic)
|
* [Basic](websocket/basic)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kataras/iris/v12"
|
"github.com/kataras/iris/v12"
|
||||||
|
@ -62,14 +61,6 @@ func main() {
|
||||||
app.Listen(":8080")
|
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) {
|
func authenticate(ctx iris.Context) {
|
||||||
claims := userClaims{
|
claims := userClaims{
|
||||||
Username: "kataras",
|
Username: "kataras",
|
||||||
|
|
25
_examples/auth/jwt/tutorial/api.go
Normal file
25
_examples/auth/jwt/tutorial/api.go
Normal 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) {
|
||||||
|
|
||||||
|
}
|
10
_examples/auth/jwt/tutorial/go.mod
Normal file
10
_examples/auth/jwt/tutorial/go.mod
Normal 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 => ../../../../
|
89
_examples/auth/jwt/tutorial/main.go
Normal file
89
_examples/auth/jwt/tutorial/main.go
Normal 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)
|
||||||
|
}
|
63
_examples/auth/jwt/tutorial/user.go
Normal file
63
_examples/auth/jwt/tutorial/user.go
Normal 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
|
||||||
|
}
|
42
_examples/sessions/viewdata/main.go
Normal file
42
_examples/sessions/viewdata/main.go
Normal 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}}
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
}
|
11
_examples/sessions/viewdata/views/index.html
Normal file
11
_examples/sessions/viewdata/views/index.html
Normal 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>
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/kataras/iris/v12/core/host"
|
"github.com/kataras/iris/v12/core/host"
|
||||||
"github.com/kataras/iris/v12/middleware/jwt"
|
"github.com/kataras/iris/v12/middleware/jwt"
|
||||||
|
@ -30,7 +29,6 @@ type Client interface {
|
||||||
|
|
||||||
// Blocklist is a jwt.Blocklist backed by Redis.
|
// Blocklist is a jwt.Blocklist backed by Redis.
|
||||||
type Blocklist struct {
|
type Blocklist struct {
|
||||||
Clock func() time.Time // Required. Defaults to time.Now.
|
|
||||||
// GetKey is a function which can be used how to extract
|
// GetKey is a function which can be used how to extract
|
||||||
// the unique identifier for a token.
|
// the unique identifier for a token.
|
||||||
// Required. By default the token key is extracted through the claims.ID ("jti").
|
// 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
|
// verifier.Blocklist = blocklist
|
||||||
func NewBlocklist() *Blocklist {
|
func NewBlocklist() *Blocklist {
|
||||||
return &Blocklist{
|
return &Blocklist{
|
||||||
Clock: time.Now,
|
|
||||||
GetKey: defaultGetKey,
|
GetKey: defaultGetKey,
|
||||||
Prefix: "",
|
Prefix: "",
|
||||||
ClientOptions: Options{
|
ClientOptions: Options{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user