跨平台多客户oauth2 API设计

时间:2016-09-19 10:18:52

标签: oauth-2.0 asp.net-web-api2 cross-platform google-oauth

我正在使用ASP.NET Web API 2构建RESTfull后端。 FTM我有三个客户端:AngularJs Web应用程序,Android和iPhone应用程序。

我需要通过谷歌和Facebook为所有人建立登录,并需要你的帮助来设计它。

我的想法如下(以Google身份验证为例):

    Google Developer Console中的
  1. 我创建 4 “OAuth 2.0客户端ID”:

    • for AngularJS app(类型Web应用程序,允许来源)
    • for Android(Android版)
    • for IOs(type IOs)
    • 用于WEB API后端(输入没有任何允许来源的Web应用程序)
  2. 每个客户都会与Google联系并使用自己的库/ apis来授权并请求用户同意所需的范围以及离线使用。因此,来自Google的客户端会收到authorization_code。

  3. 每个客户端将调用Web后端GET方法ExternalLogin并将authorization_code作为输入参数发送。

  4. 网络后端会将(使用Google API)的authorization_code更改为access_token,并从Google(通过Google API)接收所有需要的用户信息。如果用户已经注册(如果没有 - 应用程序将创建一个帐户),则检查数据库,然后发出本地访问令牌,这些令牌应该用于所有对Web后端的进一步调用。

  5. 好处非常简单:

    • 简单流程,每个客户端
    • 都相同
    • 登录/注册每个客户端的单一方法
    • 收集用户数据的逻辑在一个地方(网络后端) - 所以如果我们需要从用户收集额外的数据,我们只需要在后端进行更改。 客户只需将范围添加到同意屏幕。

    我的问题是:

    • 以下流程是否正确且足够稳定?它也适用于Facebook身份验证吗?
    • FTM我陷入了第4步.AngularJs的ClientId获得了authorization_code。 Web后端正试图将access_token 的authorization_code与另一个ClientId 交换(web后端在Google开发者控制台中有自己的ClientId,如上所述)我收到错误:unauthorized_client。奇怪,导致谷歌开发者控制台中同一“项目”中的所有ClientID。有没有办法让它发挥作用?

2 个答案:

答案 0 :(得分:0)

流程非常好,但有一个例外:您需要为实际客户端应用程序(因此为Authorized JavaScript origins)设置客户端ID ,而不是为后端设置客户端ID

Facebook至少在后端方面几乎相同(只是一个不同的验证库),你应该没有问题抽象出一个通用的提供者接口。

至于验证server side上ID令牌的完整性 - 在Google的终端上进行GET验证此令牌,让他们了解验证算法: https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}

以下是这样的看法:

private const string GoogleApiTokenInfoUrl = "https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}";

public ProviderUserDetails GetUserDetails(string providerToken)
{
    var httpClient = new MonitoredHttpClient();
    var requestUri = new Uri(string.Format(GoogleApiTokenInfoUrl, providerToken));

    HttpResponseMessage httpResponseMessage;
    try
    {
        httpResponseMessage = httpClient.GetAsync(requestUri).Result;
    }
    catch (Exception ex)
    {
        return null;
    }

    if (httpResponseMessage.StatusCode != HttpStatusCode.OK)
    {
        return null;
    }

    var response = httpResponseMessage.Content.ReadAsStringAsync().Result;
    var googleApiTokenInfo = JsonConvert.DeserializeObject<GoogleApiTokenInfo>(response);

    if (!SupportedClientsIds.Contains(googleApiTokenInfo.aud))
    {
        Log.WarnFormat("Google API Token Info aud field ({0}) not containing the required client id", googleApiTokenInfo.aud);
        return null;
    }

    return new ProviderUserDetails
    {
        Email = googleApiTokenInfo.email,
        FirstName = googleApiTokenInfo.given_name,
        LastName = googleApiTokenInfo.family_name,
        Locale = googleApiTokenInfo.locale,
        Name = googleApiTokenInfo.name,
        ProviderUserId = googleApiTokenInfo.sub
    };
}

答案 1 :(得分:0)

您应该查看Firebase Auth(从Google Identity Toolkit重命名)。这将使您变得非常轻松,而您所要做的就是在您的后端接受一个令牌。

请注意,您不需要使用Firebase数据库来使用Firebase身份验证。