Commit a6140d63 authored by k1350's avatar k1350
Browse files

[update] #14 パスワード閲覧のブログは一定時間はパスワードを再入力しなくていいようにする

- redis を使えるようにする
- session を使えるようにする
parent f7f0cd66
......@@ -31,6 +31,7 @@ services:
command: sh -c "go mod tidy && air && /bin/sh"
depends_on:
- "db"
- "redis"
db:
container_name: gql_sololog_db
image: mysql:8.0
......@@ -52,6 +53,13 @@ services:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
redis:
container_name: gql_sololog_redis
build:
context: ./redis
ports:
- "6379:6379"
command: redis-server /usr/local/etc/redis/redis.conf --requirepass ${REDIS_PASSWORD}
volumes:
gql_sololog_backend_data:
gql_sololog_db_data:
\ No newline at end of file
......@@ -2,4 +2,5 @@ UID=1000
GID=1000
MYSQL_ROOT_PASSWORD=db_root
MYSQL_USER=db_user
MYSQL_PASSWORD=db_pass
\ No newline at end of file
MYSQL_PASSWORD=db_pass
REDIS_PASSWORD=redis_password
\ No newline at end of file
FROM redis:7.0-alpine
COPY redis.conf /usr/local/etc/redis/redis.conf
\ No newline at end of file
This diff is collapsed.
......@@ -2,4 +2,6 @@ DB_HOST=db
MYSQL_USER=db_user
MYSQL_PASSWORD=db_pass
FRONT_ORIGIN=http://localhost:3000
FIREBASE_JSON_PATH=/app/private/xxx-firebase-adminsdk-xxx-xxx.json
\ No newline at end of file
FIREBASE_JSON_PATH=/app/private/xxx-firebase-adminsdk-xxx-xxx.json
SESSION_KEY=session_key
REDIS_PASSWORD=redis_password
\ No newline at end of file
......@@ -9,12 +9,14 @@ require (
github.com/go-sql-driver/mysql v1.6.0
github.com/golang/mock v1.6.0
github.com/google/uuid v1.3.0
github.com/gorilla/sessions v1.2.1
github.com/graph-gophers/dataloader v5.0.0+incompatible
github.com/joho/godotenv v1.4.0
github.com/pkg/errors v0.9.1
github.com/vektah/gqlparser/v2 v2.4.6
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064
google.golang.org/api v0.73.0
gopkg.in/boj/redistore.v1 v1.0.0-20160128113310-fc113767cd6b
)
require (
......@@ -25,10 +27,12 @@ require (
cloud.google.com/go/storage v1.21.0 // indirect
github.com/agnivade/levenshtein v1.1.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
github.com/garyburd/redigo v1.6.3 // indirect
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-cmp v0.5.7 // indirect
github.com/googleapis/gax-go/v2 v2.1.1 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/mitchellh/mapstructure v1.3.1 // indirect
......
......@@ -107,6 +107,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/garyburd/redigo v1.6.3 h1:HCeeRluvAgMusMomi1+6Y5dmFOdYV/JzoRrrbFlkGIc=
github.com/garyburd/redigo v1.6.3/go.mod h1:rTb6epsqigu3kYKBnaF028A7Tf/Aw5s0cqA47doKKqw=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
......@@ -192,6 +194,10 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU=
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI=
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug=
......@@ -677,6 +683,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/boj/redistore.v1 v1.0.0-20160128113310-fc113767cd6b h1:U/Uqd1232+wrnHOvWNaxrNqn/kFnr4yu4blgPtQt0N8=
gopkg.in/boj/redistore.v1 v1.0.0-20160128113310-fc113767cd6b/go.mod h1:fgfIZMlsafAHpspcks2Bul+MWUNw/2dyQmjC2faKjtg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
......
......@@ -5,15 +5,20 @@ package graph
import (
"context"
"fmt"
"net/http"
"time"
"github.com/gorilla/sessions"
"github.com/graph-gophers/dataloader"
"gitlab.com/k1350/sololog_gql/graph/generated"
"gitlab.com/k1350/sololog_gql/graph/model"
customError "gitlab.com/k1350/sololog_gql/internal/errors"
clog "gitlab.com/k1350/sololog_gql/internal/log"
authMiddleware "gitlab.com/k1350/sololog_gql/internal/middleware/auth"
dataLoaderMiddleware "gitlab.com/k1350/sololog_gql/internal/middleware/dataloader"
sessionMiddleware "gitlab.com/k1350/sololog_gql/internal/middleware/session"
)
// Links is the resolver for the links field.
......@@ -179,11 +184,39 @@ func (r *queryResolver) BlogByID(ctx context.Context, id string) (*model.Blog, e
func (r *queryResolver) BlogByBlogKey(ctx context.Context, input model.BlogByBlogKeyInput) (*model.Blog, error) {
userId, _ := authMiddleware.GetUserId(ctx)
// TODO: ダミー実装を直す
s, err := sessionMiddleware.GetSession(ctx, "blog-session")
if err != nil {
clog.Error(err)
return nil, err
}
passwordInputTime := s.Values["testkey"]
if passwordInputTime == nil {
fmt.Println("no data")
} else {
intTime := passwordInputTime.(string)
fmt.Println(intTime)
}
result, err := r.BlogUsecase.GetBlogByBlogKey(input, userId)
if err != nil {
clog.Error(err)
return nil, customError.RecreateError(err)
}
// TODO: ダミー実装を直す
s.Values["testkey"] = "test"
s.Options = &sessions.Options{
Path: "/",
MaxAge: 3600,
HttpOnly: true,
SameSite: http.SameSiteLaxMode,
Secure: true,
}
err = sessionMiddleware.SaveSession(ctx, s)
if err != nil {
clog.Error(err)
return nil, err
}
return result, nil
}
......
......@@ -9,6 +9,7 @@ func Cors(origin string, next http.Handler) http.Handler {
w.Header().Set("Access-Control-Allow-Origin", origin)
w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "content-type, Authorization")
w.Header().Set("Access-Control-Allow-Credentials", "true")
next.ServeHTTP(w, r)
})
}
package session
import (
"context"
"net/http"
"github.com/gorilla/sessions"
redistore "gopkg.in/boj/redistore.v1"
)
type SessionContext struct {
req *http.Request
resp *http.ResponseWriter
store *redistore.RediStore
}
func Session(redis *redistore.RediStore, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), sessionKey, &SessionContext{
req: r,
resp: &w,
store: redis,
})
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
})
}
type ctxKey int
const (
sessionKey ctxKey = iota
)
func GetSession(ctx context.Context, name string) (*sessions.Session, error) {
store := ctx.Value(sessionKey).(*SessionContext).store
req := ctx.Value(sessionKey).(*SessionContext).req
return store.Get(req, name)
}
func SaveSession(ctx context.Context, s *sessions.Session) error {
sessionContext := ctx.Value(sessionKey).(*SessionContext)
return s.Save(sessionContext.req, *sessionContext.resp)
}
......@@ -12,6 +12,8 @@ import (
"github.com/99designs/gqlgen/graphql/playground"
_ "github.com/go-sql-driver/mysql"
"github.com/joho/godotenv"
redistore "gopkg.in/boj/redistore.v1"
"gitlab.com/k1350/sololog_gql/graph"
"gitlab.com/k1350/sololog_gql/graph/generated"
"gitlab.com/k1350/sololog_gql/internal/directive"
......@@ -19,6 +21,7 @@ import (
"gitlab.com/k1350/sololog_gql/internal/middleware/auth"
"gitlab.com/k1350/sololog_gql/internal/middleware/cors"
"gitlab.com/k1350/sololog_gql/internal/middleware/dataloader"
"gitlab.com/k1350/sololog_gql/internal/middleware/session"
ar "gitlab.com/k1350/sololog_gql/internal/repository/article"
authr "gitlab.com/k1350/sololog_gql/internal/repository/auth"
br "gitlab.com/k1350/sololog_gql/internal/repository/blog"
......@@ -46,6 +49,8 @@ func main() {
dbusername := os.Getenv("MYSQL_USER")
dbpassword := os.Getenv("MYSQL_PASSWORD")
firebasepath := os.Getenv("FIREBASE_JSON_PATH")
sessionKey := os.Getenv("SESSION_KEY")
redisPassword := os.Getenv("REDIS_PASSWORD")
db, err := connectDb(dbhostsip, dbusername, dbpassword)
if err != nil {
......@@ -53,6 +58,12 @@ func main() {
}
defer db.Close()
rs, err := connectRedis(sessionKey, redisPassword)
if err != nil {
clog.Emergency(err)
}
defer rs.Close()
client, err := setupFirebase(firebasepath)
if err != nil {
clog.Emergency(err)
......@@ -87,12 +98,14 @@ func main() {
http.Handle("/", playground.Handler("GraphQL playground", "/query"))
http.Handle("/query",
auth.Auth(au,
dataloader.Dataloader(
&dataloader.Repository{
BlogRepository: b,
},
cors.Cors(origin, srv),
session.Session(rs,
auth.Auth(au,
dataloader.Dataloader(
&dataloader.Repository{
BlogRepository: b,
},
cors.Cors(origin, srv),
),
),
),
)
......@@ -118,3 +131,11 @@ func setupFirebase(path string) (*firebaseAuth.Client, error) {
}
return app.Auth(context.Background())
}
func connectRedis(sessionKey string, redisPassword string) (*redistore.RediStore, error) {
rs, err := redistore.NewRediStore(100, "tcp", "gql_sololog_redis:6379", redisPassword, []byte(sessionKey))
if err != nil {
return nil, err
}
return rs, nil
}
......@@ -28,6 +28,7 @@ export const requireAuthFetchData = <TData, TVariables>(
Authorization: `Bearer ${token}`,
...options,
},
credentials: 'include',
body: JSON.stringify({
query,
variables,
......@@ -57,6 +58,7 @@ export const guestFetchData = <TData, TVariables>(
'Content-Type': 'application/json',
...options,
},
credentials: 'include',
body: JSON.stringify({
query,
variables,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment