Skip to content

Commit c2d361c

Browse files
authored
feat: add session (#37)
* feat: add session Signed-off-by: HominSu <[email protected]> * fix: error Signed-off-by: HominSu <[email protected]> --------- Signed-off-by: HominSu <[email protected]>
1 parent e972bf4 commit c2d361c

File tree

10 files changed

+775
-0
lines changed

10 files changed

+775
-0
lines changed

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ require (
2626
github.com/google/wire v0.5.0
2727
github.com/gorilla/handlers v1.5.1
2828
github.com/gorilla/mux v1.8.0
29+
github.com/gorilla/securecookie v1.1.1
2930
github.com/gorilla/websocket v1.4.2
3031
github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0
3132
github.com/hashicorp/consul/api v1.12.0

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,8 @@ github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
381381
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
382382
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
383383
github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
384+
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
385+
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
384386
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
385387
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
386388
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=

http/session/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# session
2+
3+
Implement [gorilla/sessions](https://github.com/gorilla/sessions) with kratos `http.Transport` and uses [go-redis/v8](https://github.com/redis/go-redis/tree/v8) to implement `sessions.Store` interface

http/session/main.go

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/go-kratos/kratos/v2"
8+
"github.com/go-kratos/kratos/v2/errors"
9+
"github.com/go-kratos/kratos/v2/log"
10+
"github.com/go-kratos/kratos/v2/transport"
11+
"github.com/go-kratos/kratos/v2/transport/http"
12+
"github.com/go-redis/redis/v8"
13+
14+
"github.com/go-kratos/examples/helloworld/helloworld"
15+
"github.com/go-kratos/examples/http/session/sessions"
16+
)
17+
18+
// go build -ldflags "-X main.Version=x.y.z"
19+
var (
20+
// Name is the name of the compiled software.
21+
Name = "session"
22+
// Version is the version of the compiled software.
23+
// Version = "v1.0.0"
24+
)
25+
26+
// server is used to implement helloworld.GreeterServer.
27+
type server struct {
28+
helloworld.UnimplementedGreeterServer
29+
30+
store *sessions.RedisStore
31+
}
32+
33+
// SayHello implements helloworld.GreeterServer
34+
func (s *server) SayHello(ctx context.Context, in *helloworld.HelloRequest) (*helloworld.HelloReply, error) {
35+
if tr, ok := transport.FromServerContext(ctx); ok {
36+
if ht, ok := tr.(*http.Transport); ok {
37+
// get a session
38+
session, err := s.store.Get(ht, "session")
39+
if err != nil {
40+
return nil, errors.InternalServer("INTERNAL_ERROR", "get session error")
41+
}
42+
43+
// modified the value of the key, and save
44+
session.Values["key"] = "value"
45+
if err = session.Save(ht); err != nil {
46+
return nil, errors.InternalServer("INTERNAL_ERROR", "save session error")
47+
}
48+
49+
// delete session
50+
//session.Options.MaxAge = -1
51+
//if err = session.Save(ht); err != nil {
52+
// return nil, errors.InternalServer("INTERNAL_ERROR", "save session error")
53+
//}
54+
}
55+
}
56+
57+
return &helloworld.HelloReply{Message: fmt.Sprintf("Hello %+v", in.Name)}, nil
58+
}
59+
60+
func main() {
61+
rdCmd := redis.NewClient(&redis.Options{
62+
Addr: "127.0.0.1:6379",
63+
})
64+
store, err := sessions.NewRedisStore(rdCmd, []byte("secret"))
65+
store.SetMaxAge(10 * 24 * 3600)
66+
if err != nil {
67+
log.Fatal(err)
68+
}
69+
70+
httpSrv := http.NewServer(
71+
http.Address(":8000"),
72+
)
73+
74+
s := &server{store: store}
75+
helloworld.RegisterGreeterHTTPServer(httpSrv, s)
76+
77+
app := kratos.New(
78+
kratos.Name(Name),
79+
kratos.Server(
80+
httpSrv,
81+
),
82+
)
83+
84+
if err := app.Run(); err != nil {
85+
log.Fatal(err)
86+
}
87+
}

http/session/sessions/LICENSE

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Copyright (c) 2012-2018 The Gorilla Authors. All rights reserved.
2+
3+
Redistribution and use in source and binary forms, with or without
4+
modification, are permitted provided that the following conditions are
5+
met:
6+
7+
* Redistributions of source code must retain the above copyright
8+
notice, this list of conditions and the following disclaimer.
9+
* Redistributions in binary form must reproduce the above
10+
copyright notice, this list of conditions and the following disclaimer
11+
in the documentation and/or other materials provided with the
12+
distribution.
13+
* Neither the name of Google Inc. nor the names of its
14+
contributors may be used to endorse or promote products derived from
15+
this software without specific prior written permission.
16+
17+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

http/session/sessions/cookie.go

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package sessions
2+
3+
import "net/http"
4+
5+
// newCookieFromOptions returns an http.Cookie with the options set.
6+
func newCookieFromOptions(name, value string, options *Options) *http.Cookie {
7+
return &http.Cookie{
8+
Name: name,
9+
Value: value,
10+
Path: options.Path,
11+
Domain: options.Domain,
12+
MaxAge: options.MaxAge,
13+
Secure: options.Secure,
14+
HttpOnly: options.HttpOnly,
15+
SameSite: options.SameSite,
16+
}
17+
}

http/session/sessions/lex.go

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package sessions
2+
3+
import "strings"
4+
5+
var isTokenTable = [127]bool{
6+
'!': true,
7+
'#': true,
8+
'$': true,
9+
'%': true,
10+
'&': true,
11+
'\'': true,
12+
'*': true,
13+
'+': true,
14+
'-': true,
15+
'.': true,
16+
'0': true,
17+
'1': true,
18+
'2': true,
19+
'3': true,
20+
'4': true,
21+
'5': true,
22+
'6': true,
23+
'7': true,
24+
'8': true,
25+
'9': true,
26+
'A': true,
27+
'B': true,
28+
'C': true,
29+
'D': true,
30+
'E': true,
31+
'F': true,
32+
'G': true,
33+
'H': true,
34+
'I': true,
35+
'J': true,
36+
'K': true,
37+
'L': true,
38+
'M': true,
39+
'N': true,
40+
'O': true,
41+
'P': true,
42+
'Q': true,
43+
'R': true,
44+
'S': true,
45+
'T': true,
46+
'U': true,
47+
'W': true,
48+
'V': true,
49+
'X': true,
50+
'Y': true,
51+
'Z': true,
52+
'^': true,
53+
'_': true,
54+
'`': true,
55+
'a': true,
56+
'b': true,
57+
'c': true,
58+
'd': true,
59+
'e': true,
60+
'f': true,
61+
'g': true,
62+
'h': true,
63+
'i': true,
64+
'j': true,
65+
'k': true,
66+
'l': true,
67+
'm': true,
68+
'n': true,
69+
'o': true,
70+
'p': true,
71+
'q': true,
72+
'r': true,
73+
's': true,
74+
't': true,
75+
'u': true,
76+
'v': true,
77+
'w': true,
78+
'x': true,
79+
'y': true,
80+
'z': true,
81+
'|': true,
82+
'~': true,
83+
}
84+
85+
func isToken(r rune) bool {
86+
i := int(r)
87+
return i < len(isTokenTable) && isTokenTable[i]
88+
}
89+
90+
func isNotToken(r rune) bool {
91+
return !isToken(r)
92+
}
93+
94+
func isCookieNameValid(raw string) bool {
95+
if raw == "" {
96+
return false
97+
}
98+
return strings.IndexFunc(raw, isNotToken) < 0
99+
}

0 commit comments

Comments
 (0)