Передача токена Google на сервер не работаетJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Передача токена Google на сервер не работает

Сообщение Anonymous »

У меня есть тестерное приложение Android Jetpack Compose Kotlin. Это одностраничное приложение, в котором есть кнопка входа в Google, и когда вы входите в систему с помощью Google, оно должно запускать главный экран и отображать имена пользователей.
Однако поскольку я пытаюсь отправить токен входа в Google на свой внутренний сервер (весенняя загрузка) для аутентификации, которая не работает, если проверить мою базу данных на стороне сервера, которая является sqlite, и я не вижу никаких записей для имени пользователя или идентификатора Google, я чувствую, что токен отправляется неправильно, я думаю, проблема в Android.
Вот мои классы Android и классы загрузки Spring.
Классы Android:

Код: Выделить всё

interface ApiService {
@POST("api/auth/google-signin")
suspend fun sendIdToken(@Body idTokenRequest: IdTokenRequest): Response
}

data class IdTokenRequest(
val idToken: String
)

Код: Выделить всё

@Composable
fun HomeScreen() {
val context = LocalContext.current
val account = GoogleSignIn.getLastSignedInAccount(context)
Text(text = account?.givenName!!, fontSize = 20.sp)
}

Код: Выделить всё

object RetrofitClient {
private const val BASE_URL = "baseUrl"

val instance: Retrofit by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
}

Код: Выделить всё

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
HomeNavigation()
}
}
}

@Composable
fun LoginScreen(navController: NavController) {
val context = LocalContext.current
val gso = remember {
GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestIdToken("CLIENT_ID") // Replace with your client ID
.build()
}

val signInLauncher = rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) { result ->
Log.d("GoogleSignInLauncher", "SignInLauncher result received")
if (result.resultCode == Activity.RESULT_OK) {
val task = GoogleSignIn.getSignedInAccountFromIntent(result.data)

handleSignInResult(task, context, navController)
}
}

val googleSignInClient = remember {
GoogleSignIn.getClient(context, gso)
}

Button(onClick = {
val intent = googleSignInClient.signInIntent
signInLauncher.launch(intent)
}) {
Icon(
painter = painterResource(id = R.drawable.googleicon),
contentDescription = "Google",
modifier = Modifier.size(ButtonDefaults.IconSize)
)
Spacer(modifier = Modifier.width(4.dp))
Text(text = "Sign in with Google")
}
}

fun handleSignInResult(task: Task, context: Context, navController: NavController) {
try {
val account = task.getResult(ApiException::class.java)
val idToken = account.idToken

if (idToken != null) {
Log.d("Google Token", "ID Token: $idToken")
sendIdTokenToBackend(idToken, context, navController)
} else {
Toast.makeText(context, "Failed to get ID token", Toast.LENGTH_SHORT).show()
}
} catch (e: ApiException) {
Toast.makeText(context, "Google sign in failed", Toast.LENGTH_SHORT).show()
}
}

fun sendIdTokenToBackend(idToken: String, context: Context, navController: NavController) {
CoroutineScope(Dispatchers.IO).launch {
val apiService = RetrofitClient.instance.create(ApiService::class.java)
try {
val response = apiService.sendIdToken(IdTokenRequest(idToken))
withContext(Dispatchers.Main) {
if (response.isSuccessful) {
navController.navigate("home_screen")
} else {
Toast.makeText(context, "Failed to authenticate with backend", Toast.LENGTH_SHORT).show()
}
}
} catch (e: HttpException) {
withContext(Dispatchers.Main) {
Toast.makeText(context, "Error:  ${e.message}", Toast.LENGTH_SHORT).show()
}
}
}
}

@Composable
fun HomeNavigation() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "login_screen") {
composable("login_screen") {
LoginScreen(navController)
}
composable("home_screen") {
HomeScreen()
}
}
}

Приложение Spring Boot:

Код: Выделить всё

@RestController
//This defines the base path for all request mappings in this controller
@RequestMapping("/api/auth")
public class AuthController {

// Autowired injects the AppUserRepository dependency
@Autowired
private AppUserRepository userRepository;

@Autowired
private GoogleTokenVerifierService googleTokenVerifierService;

private final JwtService jwtService = new JwtService();
// Creates a logger instance for this class
private static final Logger logger = LoggerFactory.getLogger(AuthController.class);

// Autowired injects the PasswordEncoder dependency
@Autowired
private PasswordEncoder passwordEncoder;

// This method handles POST requests to /api/auth/signup
@PostMapping("/signup")
public ResponseEntity registerUser(@RequestBody SignupRequest signupRequest) {
// Checks if a user with the provided username already exists
if (userRepository.findByUsername(signupRequest.getUsername()).isPresent()) {
return ResponseEntity.badRequest().body("Error: Username is already taken!");
}

// It creates a new AppUser object with the provided username,
//encoded password, and default role
AppUser user = new AppUser(
signupRequest.getUsername(),
passwordEncoder.encode(signupRequest.getPassword()),
"USER" // Default role
);

// Saves the new user to the database
userRepository.save(user);

logger.info("Received signup request for username: {}", signupRequest.getUsername());

return ResponseEntity.ok("User registered successfully!");
}

@PostMapping("/login")
public ResponseEntity loginUser(@RequestBody LoginRequest loginRequest) {
// Find user by username
AppUser user = userRepository.findByUsername(loginRequest.getUsername()).orElse(null);

// Check if user exists and password matches
if (user != null && passwordEncoder.matches(loginRequest.getPassword(), user.getPassword())) {
// Generate JWT token using JwtService
String jwtToken = jwtService.generateToken(user); // Assuming JwtService has a generateToken method
return ResponseEntity.ok(new LoginResponse(jwtToken)); // Create a LoginResponse with the token
} else {
return ResponseEntity.badRequest().body("Invalid username or password");
}
}

@PostMapping("/google-signin")
public ResponseEntity googleSignIn(@RequestBody GoogleSignInRequest googleSignInRequest) {
try {
logger.info("Received Google Sign-In request with token: {}", googleSignInRequest.getIdToken());

GoogleIdToken idToken = googleTokenVerifierService.verifyToken(googleSignInRequest.getIdToken());
if (idToken == null) {
logger.error("Invalid ID token: {}", googleSignInRequest.getIdToken());
return ResponseEntity.badRequest().body("Invalid ID token");
}

GoogleIdToken.Payload payload = idToken.getPayload();
String firstName = (String) payload.get("given_name");
String googleId = payload.getSubject();

logger.info("Google Sign-In payload - First Name: {}, Google ID: {}", firstName, googleId);

AppUser user = userRepository.findByGoogleId(googleId).orElseGet(() ->  {
logger.info("Creating new user with Google ID: {}", googleId);
AppUser newUser = new AppUser();
newUser.setFirstName(firstName);
newUser.setGoogleId(googleId);
newUser.setRole("USER");
return userRepository.save(newUser);
});

boolean updated = false;
if (!firstName.equals(user.getFirstName())) {
user.setFirstName(firstName);
updated = true;
}
if (user.getGoogleId() == null || !user.getGoogleId().equals(googleId)) {
user.setGoogleId(googleId);
updated = true;
}
if (updated) {
logger.info("Updating user information for Google ID: {}", googleId);
user = userRepository.save(user);
}

String jwtToken = jwtService.generateToken(user);
logger.info("Successfully processed Google Sign-In for user: {}", user.getFirstName());
return ResponseEntity.ok(new LoginResponse(jwtToken));
} catch (Exception e) {
logger.error("Error processing Google Sign-In", e);
return ResponseEntity.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).body("Error processing Google Sign-In");
}
}
}

Код: Выделить всё

@Service
public class GoogleTokenVerifierService {

private final String CLIENT_ID = "CLIENT_ID";

public GoogleIdToken verifyToken(String idTokenString) {
@SuppressWarnings("deprecation")
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(new NetHttpTransport(), jsonFactory)
.setAudience(Collections.singletonList(CLIENT_ID))
.build();

try {
return verifier.verify(idTokenString);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

Код: Выделить всё

public class GoogleSignInRequest {
private String idToken;

// Getters and setters
public String getIdToken() {
return idToken;
}

public void setIdToken(String idToken) {
this.idToken = idToken;
}
}

Код: Выделить всё

@Entity
public class AppUser {

// Marks this field as the primary key of the entity
@Id
// Specifies that the primary key value will be generated automatically using the AUTO strategy
@GeneratedValue(strategy = GenerationType.AUTO)
// Specifies that this column is not nullable and cannot be updated
@Column(nullable = false, updatable = false)
private Long id;

// Specifies that this column is not nullable and must be unique
@Column(nullable = false, unique = true)
private String username;

// Specifies that this column is not nullable
@Column(nullable = false)
private String password;

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private Set  favorites = new HashSet();

@Column(nullable = true)
private String googleId;

@Column(nullable = true)
private String firstName;

@Column(nullable = false)
private String role;

// Default constructor required by JPA
public AppUser() {
}

// Constructor to initialize the entity with username, password, and role
public AppUser(String username, String password,  String role) {
this.username = username;
this.password = password;
this.role = role;
this.firstName = "";
this.googleId = "";
}

public String getFirstName()
{
return firstName;
}

public void setFirstName(String firstName)
{
this.firstName = firstName;
}

public String getRole() {
return role;
}

public void setRole(String role) {
this.role = role;
}

// Getter method for the primary key field
public Long getId() {
return id;
}

// Setter method for the primary key field
public void setId(Long id) {
this.id = id;
}

//Getter method for the primary key field
public String getGoogleId() {
return googleId;
}

// Setter method for the primary key field
public void setGoogleId(String googleId) {
this.googleId = googleId;
}

// Getter method for the username field
public String getUsername() {
return username;
}

// Setter method for the username field
public void setUsername(String username) {
this.username = username;
}

// Getter method for the password field
public String getPassword() {
return password;
}

// Setter method for the password field
public void setPassword(String password) {
this.password = password;
}

// New methods for managing favorites
public Set getFavorites() {
return favorites;
}

public void setFavorites(Set favorites) {
this.favorites = favorites;
}

public void addFavorite(Favorite favorite) {
favorites.add(favorite);
favorite.setUser(this);
}

public void removeFavorite(Favorite favorite) {
favorites.remove(favorite);
favorite.setUser(null);
}

}

Я пробовал так много вещей, лол, я пытался зарегистрировать проблему, я пытался изменить и удалить некоторый код, я пытался создать новый проект. В моем приложении также есть регистрация и вход с именем пользователя и пароль, который я могу отправить на внутренний сервер и войти в систему. Я просто не могу войти в систему с помощью Google, чтобы пройти аутентификацию на серверной стороне.

Подробнее здесь: https://stackoverflow.com/questions/788 ... ot-working
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»