ASP.Net MVC OWIN Identity:如何从HTTP头获取Google OAuth 2.0 code及用户封面照片
Hey there! Let's break down your question into two clear parts: grabbing the Google OAuth "code" in your Account Controller, and the proper way to fetch the user's cover photo using the Google People API.
1. How to get the Google OAuth "code" in your Account Controller
First off, a quick clarification: the OAuth "code" isn't sent in HTTP headers—it's passed as a query parameter to your callback URL after the user completes Google login.
In your AccountController, you can retrieve it from the Request.QueryString collection, typically in the ExternalLoginCallback action (the default callback set up by OWIN Identity):
public async Task<ActionResult> ExternalLoginCallback(string returnUrl) { // Pull the code directly from the query string var googleAuthCode = Request.QueryString["code"]; if (!string.IsNullOrWhiteSpace(googleAuthCode)) { // You've got the code here, but keep reading—you probably don't need to use it directly! } // Rest of your existing login logic var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); if (loginInfo == null) { return RedirectToAction("Login"); } // ... }
2. Is this the right way to get the user's Google profile cover photo?
Short answer: No, it's not the most efficient or framework-compliant approach.
Here's why: OWIN Identity already handles the heavy lifting of exchanging that "code" for an access token during the Google OAuth flow. Instead of manually handling the code, you can use the access token that OWIN already retrieves for you to call the Google People API directly.
Here's the step-by-step correct method:
Step 1: Update your Google OAuth scope in Startup.Auth.cs
First, ensure you request the necessary permissions to access the user's profile (including cover photos). Add the people.readonly scope to your Google OAuth configuration:
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions { ClientId = "YOUR_GOOGLE_CLIENT_ID", ClientSecret = "YOUR_GOOGLE_CLIENT_SECRET", Scope = new List<string> { "profile", "https://www.googleapis.com/auth/people.readonly" } });
Step 2: Retrieve the access token from the external identity
In your ExternalLoginCallback action (or any authenticated action), pull the Google access token from the external identity's claims:
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); var googleAccessToken = loginInfo.ExternalIdentity.Claims .FirstOrDefault(c => c.Type == "urn:google:access_token")?.Value;
Step 3: Call the Google People API to get the cover photo
Use the access token to make an HTTP request to the People API. You can use HttpClient for this:
if (!string.IsNullOrWhiteSpace(googleAccessToken)) { using (var httpClient = new HttpClient()) { httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", googleAccessToken); // Request only the cover photos field to keep the response lightweight var apiResponse = await httpClient.GetAsync( "https://people.googleapis.com/v1/people/me?personFields=coverPhotos"); if (apiResponse.IsSuccessStatusCode) { var responseContent = await apiResponse.Content.ReadAsStringAsync(); // Parse the JSON response (using Newtonsoft.Json or System.Text.Json) var personData = JsonConvert.DeserializeObject<dynamic>(responseContent); // Extract the cover photo URL (assuming the user has one) if (personData.coverPhotos != null && personData.coverPhotos.Count > 0) { var coverPhotoUrl = personData.coverPhotos[0].url; // Do something with the URL—save it to your ASPNetUsers table, display it, etc. } } } }
Why this approach is better
- OWIN manages the token exchange and handles edge cases like token expiration (if you set up refresh tokens).
- You avoid redundant work of manually exchanging the code for a token.
- It aligns with the OWIN Identity framework's design, making your code more maintainable and less error-prone.
内容的提问来源于stack exchange,提问作者Tim Tyler

