Refactor Steam login initialization to remove unnecessary response and add nonce handling
All checks were successful
CI - Build and Push / Build and Push Docker Image (push) Successful in 1m5s

This commit is contained in:
2025-10-08 12:11:06 +08:00
parent 8cd358fcda
commit 5afd712701
9 changed files with 67 additions and 21 deletions

View File

@@ -17,9 +17,7 @@ type (
type (
SteamLoginInitReq {}
SteamLoginInitResp {
RedirectUrl string `json:"redirectUrl"`
}
// No response needed - endpoint will redirect directly
)
type (
@@ -55,10 +53,10 @@ service Authenticator {
@doc (
summary: "Initiate Steam login"
description: "Redirects user to Steam OpenID login page"
description: "Redirects user to Steam OpenID login page with nonce for security"
)
@handler steamLoginInitHandler
get /steam/login (SteamLoginInitReq) returns (SteamLoginInitResp)
get /steam/login (SteamLoginInitReq)
@doc (
summary: "Steam login callback"

View File

@@ -4,3 +4,8 @@ Port: 8888
Steam:
CallbackURL: https://www.cialloo.com/api/authenticator/steam/callback
Redis:
Host: redis.production.svc.cluster.local:6379
Type: node
Pass: ""

View File

@@ -2,17 +2,20 @@ module src
go 1.24.4
require github.com/zeromicro/go-zero v1.9.1
require (
github.com/google/uuid v1.6.0
github.com/zeromicro/go-zero v1.9.1
)
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/grafana/pyroscope-go v1.2.7 // indirect
github.com/grafana/pyroscope-go/godeltaprof v0.1.9 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
@@ -26,6 +29,7 @@ require (
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.62.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/redis/go-redis/v9 v9.15.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect

View File

@@ -1,5 +1,11 @@
github.com/alicebob/miniredis/v2 v2.35.0 h1:QwLphYqCEAo1eu1TqPRN2jgVMPBweeQcR21jeqDCONI=
github.com/alicebob/miniredis/v2 v2.35.0/go.mod h1:TcL7YfarKPGDAthEtl5NBeHZfeUQj6OXMm/+iu5cLMM=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
@@ -7,6 +13,8 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@@ -59,6 +67,8 @@ github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/redis/go-redis/v9 v9.15.0 h1:2jdes0xJxer4h3NUZrZ4OGSntGlXp4WbXju2nOTRXto=
github.com/redis/go-redis/v9 v9.15.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
@@ -74,6 +84,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
github.com/zeromicro/go-zero v1.9.1 h1:GZCl4jun/ZgZHnSvX3SSNDHf+tEGmEQ8x2Z23xjHa9g=
github.com/zeromicro/go-zero v1.9.1/go.mod h1:bHOl7Xr7EV/iHZWEqsUNJwFc/9WgAMrPpPagYvOaMtY=
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=

View File

@@ -1,10 +1,14 @@
package config
import "github.com/zeromicro/go-zero/rest"
import (
"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/rest"
)
type Config struct {
rest.RestConf
Steam SteamConfig
Redis redis.RedisConf
}
type SteamConfig struct {

View File

@@ -3,10 +3,11 @@ package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"src/internal/logic"
"src/internal/svc"
"src/internal/types"
"github.com/zeromicro/go-zero/rest/httpx"
)
// Initiate Steam login
@@ -19,11 +20,10 @@ func steamLoginInitHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
}
l := logic.NewSteamLoginInitLogic(r.Context(), svcCtx)
resp, err := l.SteamLoginInit(&req)
err := l.SteamLoginInit(&req, w, r)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
// No response needed - redirect is handled in logic
}
}

View File

@@ -2,11 +2,15 @@ package logic
import (
"context"
"fmt"
"net/http"
"time"
"src/internal/svc"
"src/internal/types"
"src/internal/utils/steamauth"
"github.com/google/uuid"
"github.com/zeromicro/go-zero/core/logx"
)
@@ -16,6 +20,13 @@ type SteamLoginInitLogic struct {
svcCtx *svc.ServiceContext
}
const (
// Redis key prefix for storing nonces
nonceKeyPrefix = "steam:nonce:"
// Nonce expiration time (5 minutes)
nonceExpiration = 5 * time.Minute
)
// Initiate Steam login
func NewSteamLoginInitLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SteamLoginInitLogic {
return &SteamLoginInitLogic{
@@ -25,16 +36,28 @@ func NewSteamLoginInitLogic(ctx context.Context, svcCtx *svc.ServiceContext) *St
}
}
func (l *SteamLoginInitLogic) SteamLoginInit(req *types.SteamLoginInitReq) (resp *types.SteamLoginInitResp, err error) {
func (l *SteamLoginInitLogic) SteamLoginInit(req *types.SteamLoginInitReq, w http.ResponseWriter, r *http.Request) error {
// Generate a unique nonce (UUID) for this login attempt
nonce := uuid.New().String()
// Store the nonce in Redis with expiration
nonceKey := nonceKeyPrefix + nonce
err := l.svcCtx.Redis.Setex(nonceKey, "1", int(nonceExpiration.Seconds()))
if err != nil {
l.Logger.Errorf("Failed to store nonce in Redis: %v", err)
return fmt.Errorf("failed to initialize login session")
}
// Get the callback URL from config
callbackURL := l.svcCtx.Config.Steam.CallbackURL
// Build the Steam OpenID redirect URL
redirectURL := steamauth.GetRedirectURL(callbackURL)
l.Logger.Infof("Initiating Steam login with callback URL: %s", callbackURL)
l.Logger.Infof("Initiating Steam login with nonce: %s, callback URL: %s", nonce, callbackURL)
return &types.SteamLoginInitResp{
RedirectUrl: redirectURL,
}, nil
// Redirect user directly to Steam
http.Redirect(w, r, redirectURL, http.StatusFound)
return nil
}

View File

@@ -2,14 +2,18 @@ package svc
import (
"src/internal/config"
"github.com/zeromicro/go-zero/core/stores/redis"
)
type ServiceContext struct {
Config config.Config
Redis *redis.Redis
}
func NewServiceContext(c config.Config) *ServiceContext {
return &ServiceContext{
Config: c,
Redis: redis.MustNewRedis(c.Redis),
}
}

View File

@@ -31,7 +31,3 @@ type SteamLoginCallbackResp struct {
type SteamLoginInitReq struct {
}
type SteamLoginInitResp struct {
RedirectUrl string `json:"redirectUrl"`
}