谷歌第三方登录后用户头像显示异常问题求助
问题说明
已实现登录页面及谷歌第三方登录功能,普通注册登录流程正常,用户登录后头像可正常显示。但谷歌登录存在异常:用户能完成登录,个人信息已存入数据库,但头像显示错误。
后端谷歌登录回调代码
[Route("google-response")] public async Task<ActionResult> GoogleResponse() { var google_csrf_name = "g_csrf_token"; var cookie = Request.Cookies[google_csrf_name]; if (cookie == null) return StatusCode((int)HttpStatusCode.BadRequest); var requestbody = Request.Form[google_csrf_name]; if (requestbody != cookie) return StatusCode((int)HttpStatusCode.BadRequest); var idtoken = Request.Form["credential"]; GoogleJsonWebSignature.Payload payload = await GoogleJsonWebSignature.ValidateAsync(idtoken).ConfigureAwait(false); byte[] y = System.Text.Encoding.UTF8.GetBytes(payload.Picture); var user = new ApplicationUser { UserName = payload.Email, Email = payload.Email , firstName = payload.GivenName, lastName = payload.FamilyName, PictureSource = y, EmailConfirmed=true }; await _userManager.CreateAsync(user).ConfigureAwait(false); await _signManager.SignInAsync(user, isPersistent: false).ConfigureAwait(false); return RedirectToAction("Index","Dashboard"); }
前端侧边栏代码
@* 根据登录状态切换 *@ @if (!SignInManager.IsSignedIn(User)) { <div class="profile-wrapper"> <img class="profile-pic" src="~/profile.jpg" /> <div class="titles d-flex flex-column ps-3"> <h6 class="mb-0">Expense Tracher</h6> <span class="text-muted">Guest</span> </div> </div> } else { <div class="profile-wrapper"> <img style="width:40px;height:40px; object-fit:cover; border-radius:30px" src="data:image/*;base64,@(Convert.ToBase64String(UserManager.GetUserAsync(User)?.Result.PictureSource))"> <div class="titles d-flex flex-column ps-3"> <h6 class="mb-0">Expense Tracher</h6> <span class="text-muted">@User.Identity?.Name</span> </div> </div> }
问题根源
代码错误地将谷歌返回的头像URL字符串直接转成UTF8字节数组存入数据库,而前端尝试将这个URL的字节数据解码为图片的base64格式,自然无法正确显示图片。
解决方案
修改后端代码,通过HTTP请求下载谷歌头像URL对应的图片二进制数据,再存入数据库:
[Route("google-response")] public async Task<ActionResult> GoogleResponse() { var google_csrf_name = "g_csrf_token"; var cookie = Request.Cookies[google_csrf_name]; if (cookie == null) return StatusCode((int)HttpStatusCode.BadRequest); var requestbody = Request.Form[google_csrf_name]; if (requestbody != cookie) return StatusCode((int)HttpStatusCode.BadRequest); var idtoken = Request.Form["credential"]; GoogleJsonWebSignature.Payload payload = await GoogleJsonWebSignature.ValidateAsync(idtoken).ConfigureAwait(false); byte[] imageBytes = null; // 下载谷歌头像图片 if (!string.IsNullOrEmpty(payload.Picture)) { using var httpClient = new HttpClient(); try { imageBytes = await httpClient.GetByteArrayAsync(payload.Picture).ConfigureAwait(false); } catch (HttpRequestException) { // 图片下载失败时可设置默认头像字节,示例:读取项目内默认头像 // imageBytes = await System.IO.File.ReadAllBytesAsync("wwwroot/profile.jpg").ConfigureAwait(false); } } var user = new ApplicationUser { UserName = payload.Email, Email = payload.Email, firstName = payload.GivenName, lastName = payload.FamilyName, PictureSource = imageBytes, EmailConfirmed = true }; await _userManager.CreateAsync(user).ConfigureAwait(false); await _signManager.SignInAsync(user, isPersistent: false).ConfigureAwait(false); return RedirectToAction("Index","Dashboard"); }
补充说明
- 生产环境建议注入
IHttpClientFactory替代直接实例化HttpClient,避免套接字耗尽问题。 - 处理图片下载异常,设置默认头像可提升用户体验。
- 前端代码无需修改,只要
PictureSource存储的是图片二进制数据,Convert.ToBase64String就能生成可正常显示的base64图片数据。
内容的提问来源于stack exchange,提问作者Rami Taher Wahdan
相关产品推荐
相关产品推荐

