没有“ Access-Control-Allow-Origin”(访问控制允许原点),仅在首次呼叫时出现错误,但随后会起作用

约书亚·奥哈娜(Joshua Ohana)

我有一个AngularJS应用,正在尝试通过Web Api进行身份验证。如果数据库中不存在该用户,则在第一次调用服务器时收到以下错误,但是一旦该用户存在于我的数据库中,则对该相同方法的后续调用也不会发生该错误。(相关代码在底部)

请求的资源上不存在“ Access-Control-Allow-Origin”标头。因此,不允许访问源' http:// localhost:1378 '。响应的HTTP状态码为500。

逻辑流程为:

  1. 当用户单击登录时,AngularJS使用Facebook进行身份验证
  2. 应用程序将$ http.post传递到我的服务器以通过身份验证进行登录/登录
  3. 服务器轮询Facebook API以获取用户详细信息
  4. 如果用户存在,请更新其个人资料并进行身份验证
  5. 否则,创建新的成员资格用户,使用FB详细信息进行更新,并进行身份验证

如果它们不存在于数据库中(即发生缺陷时),唯一不同的是login方法异步调用createUser方法然后返回数据。不会进行其他外部呼叫。

启用CORS的API启动方法:

public void Configuration(IAppBuilder app)
{
    HttpConfiguration config = new HttpConfiguration();
    var cors = new EnableCorsAttribute("*","*","*");
    config.EnableCors(cors);

    ConfigureOAuth(app);

    app_start.WebApiConfig.Register(config);
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

    app.UseWebApi(config);
}

API控制器:

[Route("Login")]
[HttpPost]
[AllowAnonymous]
public async Task<FacebookUserModel> Login(FacebookUserRequest user)
{
    FacebookUserModel fbUser = new FacebookUserModel();

    // Build FacebookUser object
    try  {
        // Grab basic user details
        string profileRequestUri = "https://graph.facebook.com/" + user.fbID + "?access_token=" + user.access_token;
        HttpWebRequest profileRequest = (HttpWebRequest)WebRequest.Create(profileRequestUri);
        profileRequest.Method = WebRequestMethods.Http.Get;
        profileRequest.Accept = "application/json";
        HttpWebResponse profileResponse = (HttpWebResponse)profileRequest.GetResponse();
        Stream profileResponseStream = profileResponse.GetResponseStream();
        StreamReader profileStreamReader = new StreamReader(profileResponseStream);
        fbUser = JsonConvert.DeserializeObject<FacebookUserModel>(profileStreamReader.ReadToEnd());
    } catch (Exception) ...

    try {
        // Grab profile picture
        string pictureRequestUri = "https://graph.facebook.com/" + user.fbID + "/picture";
        HttpWebRequest pictureRequest = (HttpWebRequest)WebRequest.Create(pictureRequestUri);
        pictureRequest.Method = WebRequestMethods.Http.Get;
        HttpWebResponse pictureResponse = (HttpWebResponse)pictureRequest.GetResponse();
        fbUser.profilePictureUri = pictureResponse.ResponseUri.ToString();
    } catch (Exception) ...

    // If user exists, change password to new token and return)
    if(userExists)
    {
        try {
            IdentityUser identityUser = _repo.FindUser(ID, pass).Result;
            FacebookUserModel dbUser = db.FacebookUserObjects.First(u => u.identityUserID == identityUser.Id);

            db.Entry(dbUser).CurrentValues.SetValues(fbUser);
            db.SaveChangesAsync();

            fbUser.identityUserID = identityUser.Id;
            return fbUser;
        }
        catch (Exception e)
        { return null; }
    }
    // Else, create the new user using same scheme
    else
    {
        UserModel newUser = new UserModel
        {
            UserName = ID,
            Password = pass,
            ConfirmPassword = pass
        };

        // Create user in Identity & linked Facebook record
        createUser(newUser, fbUser);

        return fbUser;
    }
}

private async void createUser(UserModel newUser, FacebookUserModel fbUser)
{
    IdentityResult result = await _repo.RegisterUser(newUser);
    var identityUser = await _repo.FindUser(newUser.UserName, newUser.Password);
    fbUser.identityUserID = identityUser.Id;

    db.FacebookUserObjects.Add(fbUser);
    db.SaveChangesAsync();
}

AngularJS调用我的服务器:

var _login = function (fbID, fbToken) {
    $http.post(serviceBase + 'auth/login', { "fbID": fbID, "access_token": fbToken }).then(function (response) {

        var data = "grant_type=password&username=" + fbID + "&password=" + pass;

        $http.post(serviceBase + 'auth/token', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
            .success(function (tokenResponse) {

                authServiceFactory.bearerToken = tokenResponse.access_token;
            })
            .error(function (err) {
                console.log("token error:", err);
            });

        authServiceFactory.userObject = response.data;
        window.localStorage['userObject'] = JSON.stringify(authServiceFactory.userObject);
    })
};

为什么只在第一个电话上出现“ Access-Control-Allow-Origin”错误,而后一个电话却没有?

更新

我有一个可行的解决方法,但是我不太喜欢。仅当从我的登录控制器调用第二种方法时才出现此问题,因此,如果我将该代码移到登录控制器中而不是第二种方法中,那么它将起作用而不会出现CORS错误。这确实使我感到困扰,并且效率很低,我很想知道一种更好的解决方法。

埃夫兰福德

如果您正在使用angularjs,则可能需要检出satellizer它使身份验证过程非常简单,并且内置了一些很棒的窗口弹出控件。

就Access-Control-Allow-Origin调用而言,可能会发生这种情况,因为您在一个调用上显式设置了标头,而另一个则回退到默认的http提供程序?查看$ http,看看提供这些默认设置是否可以解决。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档