Skip to content

Commit

Permalink
add: cookie / session example
Browse files Browse the repository at this point in the history
  • Loading branch information
vincentLiuxiang committed May 23, 2017
1 parent 59a8d38 commit 26eb993
Show file tree
Hide file tree
Showing 11 changed files with 295 additions and 1 deletion.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
context.go
*.log
coverage.out
example
50 changes: 50 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
### A login example

`cookie and session`


```go
package main

import (
"lu/example/controller"
"lu/example/lib"

"github.com/lugolang/static"

"github.com/vincentLiuxiang/lu"
)

func main() {
app := lu.New()
// get a redis conn
redis := lib.NewRedis("tcp", "localhost:6379", 60*60)
// get a session middleware instance
// sid is the key-value pair's key stored in cookie
sessionMw := controller.NewSessionMiddleware("sid")
// get a login middleware instance
loginMw := controller.NewLoginMiddleware("sid")
// init a static file middleware
fs := static.DefaultFS
Static := static.New(fs)

// login page /static/login/index.html
app.Get("/static/login", Static)
// Post, pass password, username to the server, check the truth and sign cookie / session, this is a restful api
app.Post("/login", loginMw.Check(redis))
/**
* app.Get("/getName", ...)
* app.Post("/register", ...)
*/
// sign session to any request via ctx.UserValue["session"]
app.Use("/", sessionMw.Middleware(redis))
// judge if a request really has session info via cookie
// if ctx.UserValue["session"] == nil, redirect to /static/login/
app.Use("/", loginMw.Middleware())
// if ctx.UserValue["session"] != nil, visi home page
app.Get("/static/home", Static)

app.Listen(":8080")
}
```

66 changes: 66 additions & 0 deletions example/controller/login.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package controller

import (
"encoding/json"
"fmt"
"lu/example/lib"

"github.com/valyala/fasthttp"
)

type LoginMiddleware struct {
cookieKey string
}

type Login struct {
username string
}

type _loginBody struct {
Username string `json:username`
Password string `json:password`
}

func NewLoginMiddleware(cookieKey string) *LoginMiddleware {
return &LoginMiddleware{cookieKey}
}

func (mw *LoginMiddleware) Middleware() func(ctx *fasthttp.RequestCtx, next func(error)) {
return func(ctx *fasthttp.RequestCtx, next func(error)) {
sid := string(ctx.Request.Header.Cookie(mw.cookieKey))
session := ctx.UserValue(sid)
if session == nil {
ctx.Redirect("/static/login/", 302)
return
}
next(nil)
}
}

func (mw *LoginMiddleware) Check(redis *lib.Redis) func(ctx *fasthttp.RequestCtx, next func(error)) {
return func(ctx *fasthttp.RequestCtx, next func(error)) {
ctx.SetStatusCode(200)
loginBody := &_loginBody{}
err := json.Unmarshal(ctx.PostBody(), &loginBody)

if err != nil {
ctx.SetBodyString("{\"success\": false,\"noteMsg\":\"post body error\"}")
return
}

fmt.Println(loginBody.Password, loginBody.Username)

username := loginBody.Username
password := loginBody.Password

if username != "lu" || password != "fasthttp" {
ctx.SetBodyString("{\"success\": false,\"noteMsg\":\"username or password invalid\"}")
return
}

sid := "xhxhh3h8xhjs92jsj2qz==="
ctx.Response.Header.Set("Set-Cookie", "sid="+sid+"; max-age=10000;")
redis.Set(sid, "liuxiang")
ctx.SetBodyString("{\"success\": true, \"redirect\":\"/static/home/index.html\"}")
}
}
30 changes: 30 additions & 0 deletions example/controller/session.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package controller

import "github.com/valyala/fasthttp"

import "lu/example/lib"

type SessionMiddleware struct {
cookieKey string
}

type Session struct {
username string
}

func NewSessionMiddleware(cookieKey string) *SessionMiddleware {
return &SessionMiddleware{cookieKey}
}

func (mw *SessionMiddleware) Middleware(redis *lib.Redis) func(ctx *fasthttp.RequestCtx, next func(error)) {
return func(ctx *fasthttp.RequestCtx, next func(error)) {
sid := string(ctx.Request.Header.Cookie(mw.cookieKey))
val, _ := redis.Get(sid)
if val == nil {
next(nil)
return
}
ctx.SetUserValue(sid, val)
next(nil)
}
}
46 changes: 46 additions & 0 deletions example/lib/redis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package lib

import "github.com/garyburd/redigo/redis"

type Redis struct {
redisConn redis.Conn
lifeTime int64
}

func (s *Redis) SetExpire(key, value interface{}, lifeTime int64) error {
var err error = nil
if lifeTime <= 0 {
_, err = s.redisConn.Do("SET", key, value)
} else {
_, err = s.redisConn.Do("SET", key, value, "EX", lifeTime)
}
return err
}

func (s *Redis) Set(key, value interface{}) error {
var err error = nil
if s.lifeTime <= 0 {
_, err = s.redisConn.Do("SET", key, value)
} else {
_, err = s.redisConn.Do("SET", key, value, "EX", s.lifeTime)
}
return err
}

func (s *Redis) Get(key interface{}) (interface{}, error) {
return s.redisConn.Do("GET", key)
}

func (s *Redis) Delete(key interface{}) error {
_, err := s.redisConn.Do("DEL", key)
return err
}

func NewRedis(protocol, hostPort string, lifeTime int64) *Redis {
c, err := redis.Dial(protocol, hostPort)
if err != nil {
panic(err)
return nil
}
return &Redis{redisConn: c, lifeTime: lifeTime}
}
Binary file added example/server
Binary file not shown.
27 changes: 27 additions & 0 deletions example/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"lu/example/controller"
"lu/example/lib"

"github.com/lugolang/static"

"github.com/vincentLiuxiang/lu"
)

func main() {
app := lu.New()
redis := lib.NewRedis("tcp", "localhost:6379", 60*60)
sessionMw := controller.NewSessionMiddleware("sid")
loginMw := controller.NewLoginMiddleware("sid")
fs := static.DefaultFS
Static := static.New(fs)

app.Use("/static/login", Static)
app.Post("/login", loginMw.Check(redis))
app.Use("/", sessionMw.Middleware(redis))
app.Use("/", loginMw.Middleware())
app.Use("/static/home", Static)

app.Listen(":8080")
}
12 changes: 12 additions & 0 deletions example/static/home/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>hello, my friends! you login !</h1>
</body>
</html>
Binary file added example/static/home/index.html.fasthttp.gz
Binary file not shown.
64 changes: 64 additions & 0 deletions example/static/login/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
span {
display: inline-block;
width: 70px;
line-height: 28px;
}
div {
width: 500px;
line-height: 28px;
margin-bottom: 10px;
}
input {
display: inline-block;
line-height: 28px;
}
input[type="button"] {
width: 80px;
height: 30px;
border: none;
line-height: 30px;
}
</style>
<script>
function login() {
var username = document.getElementById('username').value;
var password = document.getElementById('password').value;
fetch('/login', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username,
password,
hello: 'world'
})
})
.then((res) => {
return res.json()
})
.then((data) => {
if (!data.success) {
return alert(data.noteMsg);
}
window.location.href = data.redirect;
})
.catch(e => alert(e.message))
}
</script>
</head>
<body>
<div><span>用户名:</span><input type="text" value="lu" id="username"/></div>
<div><span>密码:</span><input type="password" value="fasthttp" id="password"/></div>
<div><input type="button" value="登录" onclick="login()"/></div>
</body>
</html>
Binary file added example/static/login/index.html.fasthttp.gz
Binary file not shown.

0 comments on commit 26eb993

Please sign in to comment.