GIDProfileDataFetcher.m 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #import "GoogleSignIn/Sources/GIDProfileDataFetcher/Implementations/GIDProfileDataFetcher.h"
  2. #import "GoogleSignIn/Sources/GIDDataFetcher/API/GIDDataFetcher.h"
  3. #import "GoogleSignIn/Sources/GIDDataFetcher/Implementations/GIDDataFetcher.h"
  4. #import "GoogleSignIn/Sources/GIDProfileData_Private.h"
  5. #import "GoogleSignIn/Sources/GIDSignInPreferences.h"
  6. #ifdef SWIFT_PACKAGE
  7. @import AppAuth;
  8. @import GTMAppAuth;
  9. #else
  10. #import <AppAuth/AppAuth.h>
  11. #import <GTMAppAuth/GTMAppAuth.h>
  12. #endif
  13. NS_ASSUME_NONNULL_BEGIN
  14. // The URL template for the URL to get user info.
  15. static NSString *const kUserInfoURLTemplate = @"https://%@/oauth2/v3/userinfo?access_token=%@";
  16. // Basic profile (Fat ID Token / userinfo endpoint) keys
  17. static NSString *const kBasicProfileEmailKey = @"email";
  18. static NSString *const kBasicProfilePictureKey = @"picture";
  19. static NSString *const kBasicProfileNameKey = @"name";
  20. static NSString *const kBasicProfileGivenNameKey = @"given_name";
  21. static NSString *const kBasicProfileFamilyNameKey = @"family_name";
  22. @implementation GIDProfileDataFetcher {
  23. id<GIDDataFetcher> _dataFetcher;
  24. }
  25. - (instancetype)init {
  26. GIDDataFetcher *dataFetcher = [[GIDDataFetcher alloc] init];
  27. return [self initWithDataFetcher:dataFetcher];
  28. }
  29. - (instancetype)initWithDataFetcher: (id<GIDDataFetcher>)dataFetcher {
  30. self = [super init];
  31. if (self) {
  32. _dataFetcher = dataFetcher;
  33. }
  34. return self;
  35. }
  36. - (void)fetchProfileDataWithAuthState:(OIDAuthState *)authState
  37. completion:(void (^)(GIDProfileData *_Nullable profileData,
  38. NSError *_Nullable error))completion {
  39. OIDIDToken *idToken =
  40. [[OIDIDToken alloc] initWithIDTokenString: authState.lastTokenResponse.idToken];
  41. // If the profile data are present in the ID token, use them.
  42. if (idToken) {
  43. GIDProfileData *profileData = [self profileDataWithIDToken:idToken];
  44. completion(profileData, nil);
  45. return;
  46. }
  47. // If we can't retrieve profile data from the ID token, make a userInfo request to fetch them.
  48. NSURL *infoURL = [NSURL URLWithString:
  49. [NSString stringWithFormat:kUserInfoURLTemplate,
  50. [GIDSignInPreferences googleUserInfoServer],
  51. authState.lastTokenResponse.accessToken]];
  52. [_dataFetcher fetchURL:infoURL
  53. withComment:@"GIDSignIn: fetch basic profile info"
  54. completion:^(NSData *data, NSError *error) {
  55. if (error) {
  56. completion(nil, error);
  57. } else {
  58. NSError *jsonDeserializationError;
  59. NSDictionary<NSString *, NSString *> *profileDict =
  60. [NSJSONSerialization JSONObjectWithData:data
  61. options:NSJSONReadingMutableContainers
  62. error:&jsonDeserializationError];
  63. if (profileDict) {
  64. GIDProfileData *profileData = [[GIDProfileData alloc]
  65. initWithEmail:idToken.claims[kBasicProfileEmailKey]
  66. name:profileDict[kBasicProfileNameKey]
  67. givenName:profileDict[kBasicProfileGivenNameKey]
  68. familyName:profileDict[kBasicProfileFamilyNameKey]
  69. imageURL:[NSURL URLWithString:profileDict[kBasicProfilePictureKey]]];
  70. completion(profileData, nil);
  71. }
  72. else {
  73. completion(nil, jsonDeserializationError);
  74. }
  75. }
  76. }];
  77. }
  78. // Generates user profile from OIDIDToken.
  79. - (GIDProfileData *)profileDataWithIDToken:(OIDIDToken *)idToken {
  80. if (!idToken ||
  81. !idToken.claims[kBasicProfilePictureKey] ||
  82. !idToken.claims[kBasicProfileNameKey] ||
  83. !idToken.claims[kBasicProfileGivenNameKey] ||
  84. !idToken.claims[kBasicProfileFamilyNameKey]) {
  85. return nil;
  86. }
  87. return [[GIDProfileData alloc]
  88. initWithEmail:idToken.claims[kBasicProfileEmailKey]
  89. name:idToken.claims[kBasicProfileNameKey]
  90. givenName:idToken.claims[kBasicProfileGivenNameKey]
  91. familyName:idToken.claims[kBasicProfileFamilyNameKey]
  92. imageURL:[NSURL URLWithString:idToken.claims[kBasicProfilePictureKey]]];
  93. }
  94. @end
  95. NS_ASSUME_NONNULL_END