需要帮助解决 redirect_uri_mismatch 错误

Need help resolving redirect_uri_mismatch error

我在 ASP.NET MVC 5 网站上使用 Google/Facebook/LinkedIn 身份验证。出于某种原因,每隔一段时间,一些用户抱怨无法登录,因为他们收到 redirect_uri_mismatch 错误。

正如我所说,奇怪的是错误似乎间歇性地发生并且只发生在某些用户身上。我在下面包含了我的代码,以便您指出我做错了什么。

这是Startup.cs文件代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Web;
using Owin;
using Owin.Security.Providers.LinkedIn;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Facebook;
using Microsoft.Owin.Security.Google;

namespace myWebSite
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Set up app to use cookies for authentication
            var cookieOptions = new CookieAuthenticationOptions
            {
                AuthenticationType = "Cookies",
                CookieSecure = CookieSecureOption.SameAsRequest,
                ExpireTimeSpan = TimeSpan.FromMinutes(60),
                SlidingExpiration = true,
                LoginPath = new Microsoft.Owin.PathString("/Account/Login")
            };
            app.UseCookieAuthentication(cookieOptions);

            // Set up external authentication
            var externalCookieOptions = new CookieAuthenticationOptions
            {
                AuthenticationType = "ExternalCookie",
                CookieSecure = CookieSecureOption.SameAsRequest,
                ExpireTimeSpan = TimeSpan.FromMinutes(10),
                AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive,
                CookieManager = new Helpers.SystemWebCookieManager()
            };
            app.UseCookieAuthentication(externalCookieOptions);

            #region Facebook Authentication

            var fbOptions = new FacebookAuthenticationOptions
            {
                AuthenticationType = "Facebook",
                AppId = "myFacebookAppIdGoesHere",
                AppSecret = "myFacebookAppSecretGoesHere",
                SignInAsAuthenticationType = "ExternalCookie",
                Provider = new FacebookAuthenticationProvider
                {
                    OnAuthenticated = async ctx =>
                    {
                        var token = ctx.AccessToken;

                        var id = ctx.Id;
                        var firstName = ctx.User["first_name"];
                        var middleName = ctx.User["middle_name"];
                        var lastName = ctx.User["last_name"];
                        var gender = ctx.User["gender"];
                        var birthday = ctx.User["birthday"];
                        var email = ctx.User["email"];
                        var username = ctx.User["username"];

                        ctx.Identity.AddClaim(new Claim("urn:myWebSite:AuthorityId", "1", ClaimValueTypes.String, "Facebook"));

                        if (id != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id.ToString(), ClaimValueTypes.String, "Facebook"));
                        }
                        if (firstName != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.GivenName, firstName.ToString(), ClaimValueTypes.String, "Facebook"));
                        }
                        if (middleName != null)
                        {
                            ctx.Identity.AddClaim(new Claim("urn:facebook:middle_name", middleName.ToString(), ClaimValueTypes.String, "Facebook"));
                        }
                        if (lastName != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Surname, lastName.ToString(), ClaimValueTypes.String, "Facebook"));
                        }
                        if (gender != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Gender, gender.ToString(), ClaimValueTypes.String, "Facebook"));
                        }
                        if (birthday != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.DateOfBirth, birthday.ToString(), ClaimValueTypes.String, "Facebook"));
                        }
                        if (email != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Email, email.ToString(), ClaimValueTypes.String, "Facebook"));
                        }

                        ctx.Identity.AddClaim(new Claim("fb.token", token));
                    },
                    OnReturnEndpoint = async ctx =>
                    {
                        if (ctx.Identity == null)
                        {
                            // User is not authenticated
                            throw new HttpException(403, "Unable to authenticate with Facebook...");
                        }
                        else
                        {
                            if (ctx.Properties.Dictionary.ContainsKey("returnUrl"))
                            {
                                ctx.RedirectUri += "?returnUrl=" + ctx.Properties.Dictionary["returnUrl"];
                            }
                        }
                    }
                }
            };
            fbOptions.Scope.Add("user_birthday");
            fbOptions.Scope.Add("email");
            app.UseFacebookAuthentication(fbOptions);

            #endregion

            #region Google Authentication

            var googleOptions = new GoogleOAuth2AuthenticationOptions
            {
                AuthenticationType = "Google",
                ClientId = "myGoogleClientIdGoesHere",
                ClientSecret = "myGoogleClientSecretGoesHere",
                SignInAsAuthenticationType = "ExternalCookie",
                Provider = new GoogleOAuth2AuthenticationProvider
                {
                    OnAuthenticated = async ctx =>
                    {
                        var token = ctx.AccessToken;

                        var id = ctx.Id;
                        var firstName = ctx.GivenName;
                        var middleName = ctx.User["middle_name"];
                        var lastName = ctx.FamilyName;
                        var gender = ctx.User["gender"];
                        var birthday = ctx.User["birthday"];
                        var email = ctx.Email;
                        var username = ctx.User["username"];

                        ctx.Identity.AddClaim(new Claim("urn:myWebSite:AuthorityId", "3", ClaimValueTypes.String, "Google"));

                        if (id != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id.ToString(), ClaimValueTypes.String, "Google"));
                        }
                        if (firstName != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.GivenName, firstName.ToString(), ClaimValueTypes.String, "Google"));
                        }
                        if (middleName != null)
                        {
                            ctx.Identity.AddClaim(new Claim("urn:google:middle_name", middleName.ToString(), ClaimValueTypes.String, "Google"));
                        }
                        if (lastName != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Surname, lastName.ToString(), ClaimValueTypes.String, "Google"));
                        }
                        if (gender != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Gender, gender.ToString(), ClaimValueTypes.String, "Google"));
                        }
                        if (birthday != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.DateOfBirth, birthday.ToString(), ClaimValueTypes.String, "Google"));
                        }
                        if (email != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Email, email.ToString(), ClaimValueTypes.String, "Google"));
                        }

                        ctx.Identity.AddClaim(new Claim("google.token", token));
                    },
                    OnReturnEndpoint = async ctx =>
                    {
                        if (ctx.Identity == null)
                        {
                            // User is not authenticated
                            throw new HttpException(403, "Unable to authenticate with Google...");
                        }
                        else
                        {
                            if (ctx.Properties.Dictionary.ContainsKey("returnUrl"))
                            {
                                ctx.RedirectUri += "?returnUrl=" + ctx.Properties.Dictionary["returnUrl"];
                            }
                        }
                    }
                }
            };
            googleOptions.Scope.Add("openid");
            googleOptions.Scope.Add("email");
            googleOptions.Scope.Add("profile");

            app.UseGoogleAuthentication(googleOptions);

            #endregion

            #region LinkedIn Authentication

            var linkedInOptions = new LinkedInAuthenticationOptions
            {
                AuthenticationType = "LinkedIn",
                ClientId = "myLinkedInClientIdGoesHere",
                ClientSecret = "myLinkedInClientSecretGoesHere",
                SignInAsAuthenticationType = "ExternalCookie",
                Provider = new LinkedInAuthenticationProvider
                {
                    OnAuthenticated = async ctx =>
                    {
                        var token = ctx.AccessToken;

                        var id = ctx.Id;
                        var firstName = ctx.User["first_name"];
                        var middleName = ctx.User["middle_name"];
                        var lastName = ctx.User["last_name"];
                        var gender = ctx.User["gender"];
                        var birthday = ctx.User["birthday"];
                        var email = ctx.Email;
                        var username = ctx.User["username"];

                        ctx.Identity.AddClaim(new Claim("urn:myWebSite:AuthorityId", "4", ClaimValueTypes.String, "LinkedIn"));

                        if (id != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id.ToString(), ClaimValueTypes.String, "LinkedIn"));
                        }
                        if (firstName != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.GivenName, firstName.ToString(), ClaimValueTypes.String, "LinkedIn"));
                        }
                        if (middleName != null)
                        {
                            ctx.Identity.AddClaim(new Claim("urn:linkedin:middle_name", middleName.ToString(), ClaimValueTypes.String, "LinkedIn"));
                        }
                        if (lastName != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Surname, lastName.ToString(), ClaimValueTypes.String, "LinkedIn"));
                        }
                        if (gender != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Gender, gender.ToString(), ClaimValueTypes.String, "LinkedIn"));
                        }
                        if (birthday != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.DateOfBirth, birthday.ToString(), ClaimValueTypes.String, "LinkedIn"));
                        }
                        if (email != null)
                        {
                            ctx.Identity.AddClaim(new Claim(ClaimTypes.Email, email.ToString(), ClaimValueTypes.String, "LinkedIn"));
                        }

                        ctx.Identity.AddClaim(new Claim("linkedin.token", token));
                    },
                    OnReturnEndpoint = async ctx =>
                    {
                        if (ctx.Identity == null)
                        {
                            // User is not authenticated
                            throw new HttpException(403, "Unable to authenticate with LinkedIn...");
                        }
                        else
                        {
                            if (ctx.Properties.Dictionary.ContainsKey("returnUrl"))
                            {
                                ctx.RedirectUri += "?returnUrl=" + ctx.Properties.Dictionary["returnUrl"];
                            }
                        }
                    }
                }
            };

            app.UseLinkedInAuthentication(linkedInOptions);

            #endregion
        }
    }
}

在我的 Google、Facebook 和 LinkedIn 设置中,我只有 http://www.yourdomain.com/signin-{socialsite} as the redirect uri. When I also added http://yourdomain.com/signin-{socialsite},它解决了这个问题。如果您遇到此问题,请确保您的 return uri 带有和不带 "www".