fix: fix google oauth

This commit is contained in:
Sosokker 2025-04-20 17:20:17 +07:00
parent 8219c93ceb
commit f4bc48c337
7 changed files with 82 additions and 21 deletions

View File

@ -390,7 +390,7 @@ func (h *ApiHandler) HandleGoogleCallback(w http.ResponseWriter, r *http.Request
SameSite: parseSameSite(h.cfg.JWT.CookieSameSite),
})
redirectURL := "/dashboard"
redirectURL := fmt.Sprintf("%s/oauth/callback#access_token=%s", h.cfg.Frontend.Url, url.QueryEscape(token))
h.logger.InfoContext(ctx, "Google OAuth login successful", "userId", user.ID, "email", user.Email, "redirectingTo", redirectURL)
http.Redirect(w, r, redirectURL, http.StatusTemporaryRedirect)
}

View File

@ -14,14 +14,11 @@ import (
// GoogleUserInfo holds user details fetched from Google.
type GoogleUserInfo struct {
ID string `json:"id"` // The unique Google ID
Email string `json:"email"` // The user's email address
VerifiedEmail bool `json:"verified_email"` // Whether Google has verified the email
Name string `json:"name"` // User's full name
GivenName string `json:"given_name"` // First name
FamilyName string `json:"family_name"` // Last name
Picture string `json:"picture"` // URL to profile picture
Locale string `json:"locale"` // User's locale (e.g., "en")
ID string `json:"sub"`
Email string `json:"email"`
VerifiedEmail bool `json:"email_verified"`
Name string `json:"name"`
Picture string `json:"picture"`
}
// OAuthProvider defines the interface for OAuth operations.

View File

@ -16,6 +16,7 @@ type Config struct {
OAuth OAuthConfig
Cache CacheConfig
Storage StorageConfig
Frontend FrontendConfig
}
type ServerConfig struct {
@ -79,6 +80,10 @@ type CacheConfig struct {
CleanupInterval time.Duration `mapstructure:"cleanupInterval"`
}
type FrontendConfig struct {
Url string `mapstructure:"url"`
}
func LoadConfig(path string) (*Config, error) {
viper.SetConfigName("config") // name of config file (without extension)
viper.SetConfigType("yaml") // or viper.SetConfigType("YAML")
@ -103,6 +108,7 @@ func LoadConfig(path string) (*Config, error) {
viper.SetDefault("cache.cleanupInterval", 10*time.Minute)
viper.SetDefault("storage.type", "local") // Default to local storage
viper.SetDefault("storage.local.path", "./uploads")
viper.SetDefault("frontend.url", "http://localhost:3000")
err := viper.ReadInConfig()
if err != nil {

View File

@ -199,15 +199,17 @@ export default function LoginPage() {
Or continue with
</span>
</div>
<div className="grid grid-cols-1 gap-4">
<Button
type="button"
variant="outline"
className="w-full border-gray-300 text-gray-900 hover:bg-gray-100"
onClick={() =>
toast.info("Google signup would be implemented here")
}
onClick={() => {
const apiBaseUrl =
process.env.NEXT_PUBLIC_API_BASE_URL ||
"http://127.0.0.1:8080/api/v1";
window.location.href = `${apiBaseUrl}/auth/google/login`;
}}
>
<Icons.google className="mr-2 h-4 w-4" />
Google

View File

@ -0,0 +1,55 @@
"use client";
import { useEffect } from "react";
import { useRouter } from "next/navigation";
import { useAuth } from "@/hooks/use-auth";
import { getCurrentUser } from "@/services/api-auth";
import { toast } from "sonner";
export default function OAuthCallbackPage() {
const router = useRouter();
const { login } = useAuth();
useEffect(() => {
let token: string | null = null;
if (typeof window !== "undefined") {
const urlParams = new URLSearchParams(window.location.search);
token = urlParams.get("access_token");
// If not in query, check hash fragment
if (!token && window.location.hash) {
const hashParams = new URLSearchParams(
window.location.hash.substring(1)
);
token = hashParams.get("access_token");
}
}
if (token) {
localStorage.setItem("access_token", token);
async function fetchUser() {
try {
const user = await getCurrentUser(token!);
login(token!, user);
toast.success("Logged in with Google!");
router.replace("/todos");
} catch (err) {
console.error(err);
toast.error("Google login failed");
router.replace("/login");
}
}
fetchUser();
} else {
toast.error("No access token found");
router.replace("/login");
}
}, [login, router]);
return (
<div className="flex items-center justify-center min-h-screen">
<span>Logging you in...</span>
</div>
);
}

View File

@ -218,15 +218,17 @@ export default function SignupPage() {
Or register with
</span>
</div>
<div className="grid grid-cols-1 gap-4">
<Button
type="button"
variant="outline"
className="w-full border-gray-300 text-gray-900 hover:bg-gray-100"
onClick={() =>
toast.info("Google signup would be implemented here")
}
onClick={() => {
const apiBaseUrl =
process.env.NEXT_PUBLIC_API_BASE_URL ||
"http://127.0.0.1:8080/api/v1";
window.location.href = `${apiBaseUrl}/auth/google/login`;
}}
>
<Icons.google className="mr-2 h-4 w-4" />
Google

View File

@ -28,7 +28,6 @@ export default function TodosLayout({
}
if (!isAuthenticated) {
router.push("/login");
return null;
}