thêm lưu token

This commit is contained in:
nguyennt1 2025-11-17 23:20:27 +07:00
parent d5b7fdf853
commit 4558b1e97d
11 changed files with 55 additions and 21 deletions

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="JpaBuddyIdeaProjectConfig"> <component name="JpaBuddyIdeaProjectConfig">
<option name="reLastEntityCreationPackage" value="vega-hrm-core/src/main/java/entity" /> <option name="reLastEntityCreationPackage" value="vega-hrm-core/src/main/java/com/vega/hrm/core/entities" />
<option name="reverseEngineeringLastDbConnectionId" value="969b293b-2aa0-4985-a23b-19e0a8b311f0" /> <option name="reverseEngineeringLastDbConnectionId" value="969b293b-2aa0-4985-a23b-19e0a8b311f0" />
</component> </component>
</project> </project>

View File

@ -4,6 +4,7 @@
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/.idea/modules/vega-hrm-auth/VegaHRM.Backend.vega-hrm-auth.main.iml" filepath="$PROJECT_DIR$/.idea/modules/vega-hrm-auth/VegaHRM.Backend.vega-hrm-auth.main.iml" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/vega-hrm-auth/VegaHRM.Backend.vega-hrm-auth.main.iml" filepath="$PROJECT_DIR$/.idea/modules/vega-hrm-auth/VegaHRM.Backend.vega-hrm-auth.main.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/vega-hrm-core/VegaHRM.Backend.vega-hrm-core.main.iml" filepath="$PROJECT_DIR$/.idea/modules/vega-hrm-core/VegaHRM.Backend.vega-hrm-core.main.iml" /> <module fileurl="file://$PROJECT_DIR$/.idea/modules/vega-hrm-core/VegaHRM.Backend.vega-hrm-core.main.iml" filepath="$PROJECT_DIR$/.idea/modules/vega-hrm-core/VegaHRM.Backend.vega-hrm-core.main.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/vega-hrm-report/VegaHRM.Backend.vega-hrm-report.main.iml" filepath="$PROJECT_DIR$/.idea/modules/vega-hrm-report/VegaHRM.Backend.vega-hrm-report.main.iml" />
</modules> </modules>
</component> </component>
</project> </project>

View File

@ -34,5 +34,11 @@ redis.password=VegaHrm@2025
redis.database=0 redis.database=0
cors.allowed-origins=* cors.allowed-origins=*
google.client.client-id = 719251949807-0jqbsmlh0a116cm8vm47oknmc5vpi19q.apps.googleusercontent.com
google.client.client-secret = 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
google.client.redirect-uri=http://localhost:8089/api/google/user/callback
#vcb-lounge.redis.time-to-live=600 #vcb-lounge.redis.time-to-live=600
#spring.cache.type=simple #spring.cache.type=simple

View File

@ -23,15 +23,14 @@ dependencies {
implementation 'de.mkammerer:argon2-jvm:2.1' implementation 'de.mkammerer:argon2-jvm:2.1'
implementation "com.google.apis:google-api-services-youtube:v3-rev182-1.22.0" implementation "com.google.apis:google-api-services-youtube:v3-rev182-1.22.0"
implementation("com.google.collections:google-collections:1.0") implementation("com.google.collections:google-collections:1.0")
implementation("com.google.guava:guava:20.0") implementation("com.google.guava:guava:31.1-jre")
implementation("com.google.apis:google-api-services-youtubeAnalytics:v2-rev272-1.25.0") implementation("com.google.apis:google-api-services-youtubeAnalytics:v2-rev272-1.25.0")
implementation "com.google.http-client:google-http-client-jackson2:1.20.0" implementation "com.google.http-client:google-http-client-jackson2:1.20.0"
// OAuth Client // OAuth Client
implementation "com.google.oauth-client:google-oauth-client-jetty:1.20.0"
implementation 'com.google.apis:google-api-services-oauth2:v2-rev157-1.25.0' implementation 'com.google.apis:google-api-services-oauth2:v2-rev157-1.25.0'
implementation 'com.google.oauth-client:google-oauth-client-jetty:1.34.1' implementation 'com.google.oauth-client:google-oauth-client-jetty:1.34.1'
implementation 'com.google.api-client:google-api-client:2.3.0' implementation 'com.google.api-client:google-api-client:1.32.1'
// Google Collections // Google Collections
implementation "com.google.collections:google-collections:1.0" implementation "com.google.collections:google-collections:1.0"
implementation 'com.google.code.gson:gson:2.11.0' implementation 'com.google.code.gson:gson:2.11.0'
@ -48,5 +47,13 @@ configurations {
// Loại bỏ logging mặc đnh // Loại bỏ logging mặc đnh
exclude group: 'ch.qos.logback', module: 'logback-classic' exclude group: 'ch.qos.logback', module: 'logback-classic'
exclude group: 'com.google.guava', module: 'guava-jdk5'
exclude group: 'com.google.collections', module: 'google-collections' // very old
resolutionStrategy {
// bắt buộc dùng guava hiện đi
force "com.google.guava:guava:32.1.3-jre"
}
} }
} }

View File

@ -1,14 +1,21 @@
package com.vega.hrm.dto; package com.vega.hrm.dto;
import com.google.api.client.auth.oauth2.TokenResponse; import com.google.api.client.auth.oauth2.TokenResponse;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.util.Key; import com.google.api.client.util.Key;
import com.google.api.client.util.Preconditions;
public class CustomTokenResponse extends TokenResponse { public class CustomTokenResponse extends GoogleTokenResponse {
@Key("refresh_token_expires_in") @Key("refresh_token_expires_in")
private Long refreshTokenExpiresIn; private Long refreshTokenExpiresIn;
public Long getRefreshTokenExpiresIn() { public Long getRefreshTokenExpiresIn() {
return refreshTokenExpiresIn; return this.refreshTokenExpiresIn;
}
public TokenResponse setRefreshTokenExpiresIn(Long refreshTokenExpiresIn) {
this.refreshTokenExpiresIn = Preconditions.checkNotNull(refreshTokenExpiresIn);
return this;
} }
} }

View File

@ -9,6 +9,7 @@ import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.auth.oauth2.TokenResponse; import com.google.api.client.auth.oauth2.TokenResponse;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets; import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory; import com.google.api.client.json.JsonFactory;
@ -36,8 +37,8 @@ public class GoogleService {
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private final TokenStore tokenStore; private final TokenStore tokenStore;
private final UserGoogleTokenRepository userGoogleTokenRepository; private final UserGoogleTokenRepository userGoogleTokenRepository;
private final GoogleOAuthConfig googleOAuthConfig;
public BaseResponse<String> getGoogleAuthUrl() { public BaseResponse<String> getGoogleAuthUrl() {
var googleOAuthConfig = GoogleOAuthConfig.builder().build();
NetHttpTransport httpTransport = null; NetHttpTransport httpTransport = null;
try { try {
httpTransport = GoogleNetHttpTransport.newTrustedTransport(); httpTransport = GoogleNetHttpTransport.newTrustedTransport();
@ -59,7 +60,6 @@ public class GoogleService {
} }
public BaseResponse<Boolean> googleCallback(String code) { public BaseResponse<Boolean> googleCallback(String code) {
var googleOAuthConfig = GoogleOAuthConfig.builder().build();
NetHttpTransport httpTransport = null; NetHttpTransport httpTransport = null;
try { try {
@ -77,9 +77,9 @@ public class GoogleService {
.setAccessType("offline") .setAccessType("offline")
.setApprovalPrompt("force") .setApprovalPrompt("force")
.build(); .build();
CustomTokenResponse tokenResponse = null; GoogleTokenResponse tokenResponse = null;
try { try {
tokenResponse = (CustomTokenResponse) flow.newTokenRequest(code).setRedirectUri(googleOAuthConfig.redirectUri).execute(); tokenResponse = (GoogleTokenResponse) flow.newTokenRequest(code).setRedirectUri(googleOAuthConfig.redirectUri).execute();
} catch (IOException e) { } catch (IOException e) {
return BaseResponse.invalid(e.getMessage()); return BaseResponse.invalid(e.getMessage());
} }
@ -109,9 +109,13 @@ public class GoogleService {
userGoogleToken.setRefreshToken(tokenResponse.getRefreshToken()); userGoogleToken.setRefreshToken(tokenResponse.getRefreshToken());
userGoogleToken.setScope(tokenResponse.getScope()); userGoogleToken.setScope(tokenResponse.getScope());
userGoogleToken.setExpiresIn(tokenResponse.getExpiresInSeconds()); userGoogleToken.setExpiresIn(tokenResponse.getExpiresInSeconds());
userGoogleToken.setRefreshTokenExpiresIn(tokenResponse.getRefreshTokenExpiresIn()); userGoogleToken.setRefreshTokenExpiresIn(tokenResponse.getExpiresInSeconds());
userGoogleToken.setCreatedAt(Instant.now().plusSeconds(tokenResponse.getExpiresInSeconds())); userGoogleToken.setExpiresAt(Instant.now().plusSeconds(tokenResponse.getExpiresInSeconds()));
userGoogleToken.setRefreshTokenExpiresAt(Instant.now().plusSeconds(tokenResponse.getRefreshTokenExpiresIn())); userGoogleToken.setTokenType(tokenResponse.getTokenType());
userGoogleToken.setRefreshTokenExpiresAt(Instant.now().plusSeconds(tokenResponse.get("refresh_token_expires_in") != null
? Long.valueOf(tokenResponse.get("refresh_token_expires_in").toString())
: null));
userGoogleToken.setCreatedAt(Instant.now()); userGoogleToken.setCreatedAt(Instant.now());
userGoogleTokenRepository.save(userGoogleToken); userGoogleTokenRepository.save(userGoogleToken);
} }

View File

@ -9,6 +9,9 @@ public class CommonConst {
public static final List<String> SCOPES = Arrays.asList( public static final List<String> SCOPES = Arrays.asList(
"https://www.googleapis.com/auth/youtube.readonly", "https://www.googleapis.com/auth/youtube.readonly",
"https://www.googleapis.com/auth/yt-analytics.readonly", "https://www.googleapis.com/auth/yt-analytics.readonly",
"https://www.googleapis.com/auth/yt-analytics-monetary.readonly" "https://www.googleapis.com/auth/yt-analytics-monetary.readonly",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/userinfo.profile"
); );
} }

View File

@ -1,14 +1,21 @@
package com.vega.hrm.core.dto; package com.vega.hrm.core.dto;
import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Getter @Getter
@Setter @Setter
@Builder @Component
public class GoogleOAuthConfig { public class GoogleOAuthConfig {
@Value("${google.client.client-id}")
public String clientId; public String clientId;
@Value("${google.client.client-secret}")
public String clientSecret; public String clientSecret;
@Value("${google.client.redirect-uri}")
public String redirectUri; public String redirectUri;
} }

View File

@ -28,7 +28,7 @@ import org.springframework.web.filter.OncePerRequestFilter;
@RequiredArgsConstructor @RequiredArgsConstructor
public class AuthorizationFilter extends OncePerRequestFilter { public class AuthorizationFilter extends OncePerRequestFilter {
private static final List<String> EXCLUDE_URIS = List.of("api/auth/user/login","api/google/user/callback"); private static final List<String> EXCLUDE_URIS = List.of("/api/auth/user/login","/api/google/user/callback");
private final RedisService redisService; private final RedisService redisService;
@Override @Override

View File

@ -1,4 +1,4 @@
google.client.clientId = 719251949807-0jqbsmlh0a116cm8vm47oknmc5vpi19q.apps.googleusercontent.com google.client.clientId = 719251949807-0jqbsmlh0a116cm8vm47oknmc5vpi19q.apps.googleusercontent.com
google.client.clientSecret = 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 google.client.clientSecret = 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
google.redirect.uri=https://localhost:8443/api/auth/google/callback google.client.redirect.uri=http://localhost:8089/api/google/user/callback

View File

@ -21,11 +21,10 @@ import org.springframework.web.bind.annotation.RestController;
public class ReportGoogleController { public class ReportGoogleController {
private final CreateReportingJobService createReportingJob; private final CreateReportingJobService createReportingJob;
private final GoogleOAuthConfig googleOAuthConfig;
@GetMapping("/youtube/demo") @GetMapping("/youtube/demo")
public ResponseEntity<BaseResponse<Boolean>> getRevenue(GetDragRevenueRequest getDragRevenueRequest) public ResponseEntity<BaseResponse<Boolean>> getRevenue(GetDragRevenueRequest getDragRevenueRequest)
throws GeneralSecurityException, IOException { throws GeneralSecurityException, IOException {
var googleOAuthConfig = GoogleOAuthConfig.builder().build();
var tokenStore = new TokenStore(); var tokenStore = new TokenStore();
createReportingJob.createJobWithStoredCredential( createReportingJob.createJobWithStoredCredential(
tokenStore, tokenStore,