Merge pull request #1153 from trheyi/main
Refactor login cookie handling to improve security and organization
This commit is contained in:
commit
ad57e18d1b
4 changed files with 152 additions and 18 deletions
|
|
@ -214,15 +214,8 @@ func authback(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// Authorize Cookie
|
||||
accessToken := fmt.Sprintf("%s %s", loginResponse.TokenType, loginResponse.AccessToken)
|
||||
refreshToken := fmt.Sprintf("%s %s", loginResponse.TokenType, loginResponse.RefreshToken)
|
||||
|
||||
// Send Cookie
|
||||
expires := time.Now().Add(time.Duration(loginResponse.ExpiresIn) * time.Second)
|
||||
refreshExpires := time.Now().Add(time.Duration(loginResponse.RefreshTokenExpiresIn) * time.Second)
|
||||
response.SendAccessTokenCookieWithExpiry(c, accessToken, expires)
|
||||
response.SendRefreshTokenCookieWithExpiry(c, refreshToken, refreshExpires)
|
||||
// Send all login cookies (access token, refresh token, and session ID)
|
||||
SendLoginCookies(c, loginResponse, sid)
|
||||
|
||||
// Send IDToken to the client
|
||||
response.RespondWithSuccess(c, response.StatusOK, map[string]interface{}{"id_token": loginResponse.IDToken})
|
||||
|
|
@ -673,3 +666,28 @@ func isPrivateIPv6(ip net.IP) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// SendLoginCookies sends all necessary cookies for a successful login
|
||||
// This includes access token, refresh token, and session ID cookies with appropriate security settings
|
||||
func SendLoginCookies(c *gin.Context, loginResponse *LoginResponse, sessionID string) {
|
||||
// Format tokens with Bearer prefix
|
||||
accessToken := fmt.Sprintf("%s %s", loginResponse.TokenType, loginResponse.AccessToken)
|
||||
refreshToken := fmt.Sprintf("%s %s", loginResponse.TokenType, loginResponse.RefreshToken)
|
||||
|
||||
// Calculate expiration times
|
||||
expires := time.Now().Add(time.Duration(loginResponse.ExpiresIn) * time.Second)
|
||||
refreshExpires := time.Now().Add(time.Duration(loginResponse.RefreshTokenExpiresIn) * time.Second)
|
||||
|
||||
// Send access token cookie
|
||||
response.SendAccessTokenCookieWithExpiry(c, accessToken, expires)
|
||||
|
||||
// Send refresh token cookie
|
||||
response.SendRefreshTokenCookieWithExpiry(c, refreshToken, refreshExpires)
|
||||
|
||||
// Send session ID cookie with the same expiration as access token
|
||||
// Using HTTP-only flag for security
|
||||
options := response.NewSecureCookieOptions().
|
||||
WithExpires(expires).
|
||||
WithSameSite("Strict")
|
||||
response.SendSecureCookieWithOptions(c, "session_id", sessionID, options)
|
||||
}
|
||||
|
|
|
|||
96
openapi/user/TODO.md
Normal file
96
openapi/user/TODO.md
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
# User Module TODO
|
||||
|
||||
## ✅ Implemented (5/80)
|
||||
|
||||
### Authentication
|
||||
|
||||
- ✅ GET `/user/login` - Get login page configuration
|
||||
- ✅ POST `/user/login` - User login
|
||||
|
||||
### OAuth & Third-Party Integration
|
||||
|
||||
- ✅ GET `/user/oauth/:provider/authorize` - Get OAuth authorization URL
|
||||
- ✅ POST `/user/oauth/:provider/authorize/prepare` - Handle OAuth POST callback (Apple, WeChat)
|
||||
- ✅ POST `/user/oauth/:provider/callback` - Handle OAuth GET callback (Google, GitHub)
|
||||
|
||||
## ❌ TODO (75/80)
|
||||
|
||||
### Authentication
|
||||
|
||||
- ❌ POST `/user/register` - User registration
|
||||
- ❌ POST `/user/logout` - User logout
|
||||
|
||||
### Profile Management
|
||||
|
||||
- ❌ GET `/user/profile` - Get user profile
|
||||
- ❌ PUT `/user/profile` - Update user profile
|
||||
|
||||
### Account Security (13 endpoints)
|
||||
|
||||
- ❌ Password management (3 endpoints)
|
||||
- ❌ Email management (5 endpoints)
|
||||
- ❌ Mobile management (5 endpoints)
|
||||
|
||||
### Multi-Factor Authentication (12 endpoints)
|
||||
|
||||
- ❌ TOTP management (7 endpoints)
|
||||
- ❌ SMS MFA management (5 endpoints)
|
||||
|
||||
### OAuth & Third-Party Integration
|
||||
|
||||
- ❌ GET `/user/oauth/providers` - Get linked OAuth providers
|
||||
- ❌ DELETE `/user/oauth/:provider` - Unlink OAuth provider
|
||||
- ❌ GET `/user/oauth/providers/available` - Get available OAuth providers
|
||||
- ❌ POST `/user/oauth/:provider/connect` - Connect OAuth provider
|
||||
|
||||
### API Keys Management (6 endpoints)
|
||||
|
||||
- ❌ CRUD operations and regeneration for API keys
|
||||
|
||||
### Credits & Top-up (6 endpoints)
|
||||
|
||||
- ❌ Credits info, history, and top-up management
|
||||
|
||||
### Subscription Management (2 endpoints)
|
||||
|
||||
- ❌ Subscription info and updates
|
||||
|
||||
### Usage Statistics (2 endpoints)
|
||||
|
||||
- ❌ Usage statistics and history
|
||||
|
||||
### Billing & Invoices (2 endpoints)
|
||||
|
||||
- ❌ Billing history and invoice list
|
||||
|
||||
### Referral & Invitations (4 endpoints)
|
||||
|
||||
- ❌ Referral codes, statistics, history, commissions
|
||||
|
||||
### Team Management (15 endpoints)
|
||||
|
||||
- ❌ Team CRUD (5 endpoints)
|
||||
- ❌ Member management (5 endpoints)
|
||||
- ❌ Invitation management (5 endpoints)
|
||||
|
||||
### Invitation Response (3 endpoints)
|
||||
|
||||
- ❌ Cross-module invitation handling
|
||||
|
||||
### User Preferences (3 endpoints)
|
||||
|
||||
- ❌ User preference settings
|
||||
|
||||
### Privacy Settings (3 endpoints)
|
||||
|
||||
- ❌ Privacy settings
|
||||
|
||||
### User Management (Admin) (5 endpoints)
|
||||
|
||||
- ❌ User CRUD operations
|
||||
|
||||
## Progress Summary
|
||||
|
||||
- **Completion**: 6.25% (5/80)
|
||||
- **Core Features**: Authentication and OAuth completed
|
||||
- **Next Steps**: Recommend implementing basic user management (register, logout, profile) first
|
||||
|
|
@ -2,7 +2,9 @@ package user
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/yaoapp/gou/session"
|
||||
|
|
@ -179,3 +181,28 @@ func LoginByUserID(userid string, ip string) (*LoginResponse, error) {
|
|||
func generateSessionID() string {
|
||||
return session.ID()
|
||||
}
|
||||
|
||||
// SendLoginCookies sends all necessary cookies for a successful login
|
||||
// This includes access token, refresh token, and session ID cookies with appropriate security settings
|
||||
func SendLoginCookies(c *gin.Context, loginResponse *LoginResponse, sessionID string) {
|
||||
// Format tokens with Bearer prefix
|
||||
accessToken := fmt.Sprintf("%s %s", loginResponse.TokenType, loginResponse.AccessToken)
|
||||
refreshToken := fmt.Sprintf("%s %s", loginResponse.TokenType, loginResponse.RefreshToken)
|
||||
|
||||
// Calculate expiration times
|
||||
expires := time.Now().Add(time.Duration(loginResponse.ExpiresIn) * time.Second)
|
||||
refreshExpires := time.Now().Add(time.Duration(loginResponse.RefreshTokenExpiresIn) * time.Second)
|
||||
|
||||
// Send access token cookie
|
||||
response.SendAccessTokenCookieWithExpiry(c, accessToken, expires)
|
||||
|
||||
// Send refresh token cookie
|
||||
response.SendRefreshTokenCookieWithExpiry(c, refreshToken, refreshExpires)
|
||||
|
||||
// Send session ID cookie with the same expiration as access token
|
||||
// Using HTTP-only flag for security
|
||||
options := response.NewSecureCookieOptions().
|
||||
WithExpires(expires).
|
||||
WithSameSite("Strict")
|
||||
response.SendSecureCookieWithOptions(c, "session_id", sessionID, options)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -184,15 +184,8 @@ func authback(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// Authorize Cookie
|
||||
accessToken := fmt.Sprintf("%s %s", loginResponse.TokenType, loginResponse.AccessToken)
|
||||
refreshToken := fmt.Sprintf("%s %s", loginResponse.TokenType, loginResponse.RefreshToken)
|
||||
|
||||
// Send Cookie
|
||||
expires := time.Now().Add(time.Duration(loginResponse.ExpiresIn) * time.Second)
|
||||
refreshExpires := time.Now().Add(time.Duration(loginResponse.RefreshTokenExpiresIn) * time.Second)
|
||||
response.SendAccessTokenCookieWithExpiry(c, accessToken, expires)
|
||||
response.SendRefreshTokenCookieWithExpiry(c, refreshToken, refreshExpires)
|
||||
// Send all login cookies (access token, refresh token, and session ID)
|
||||
SendLoginCookies(c, loginResponse, sid)
|
||||
|
||||
// Send IDToken to the client
|
||||
response.RespondWithSuccess(c, response.StatusOK, map[string]interface{}{"id_token": loginResponse.IDToken})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue