Code Monkey home page Code Monkey logo

oauth-google's Introduction

oauth-google

web.config:

<appSettings>
  <add key="GoogleAuth.ClientId" value="YOUR_CLIENT_ID" />
  <add key="GoogleAuth.VerifyUrl" value="https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={token}" />
</appSettings>

index.cshtml:

<script src="https://apis.google.com/js/api:client.js"></script>
<script src="/location/to/scripts/oauth-google.js"></script>

<script>
    var clientId = '@ConfigurationManager.AppSettings["GoogleAuth.ClientId"]';
    var validationUrl = '/Account/LoginExternal';
    
    function initExternalLogin() {
        var googleLogin = new GoogleLogin(clientId, validationUrl);
        googleLogin.attachButton(document.getElementById('loginGoogle'));
    }
    
    $(function() {
      initExternalLogin();
    });
</script>

<a href="#" id="loginGoogle">
    Login with Google Account
</a>

oauth-google.js:

function GoogleLogin(clientId, validationUrl) {
    var self = this;

    this.validationUrl = validationUrl;
    
    gapi.load('auth2', function () {
        self.auth2 = gapi.auth2.init({
            client_id: clientId,
            cookiepolicy: 'single_host_origin',
            scope: 'email'
        });
    });
}

GoogleLogin.prototype.attachButton = function(element) {
    var self = this;

    $(element).on('click', function () {
        self.auth2.signIn().then(function (googleUser) {
            var user = googleUser.getBasicProfile();

            var request = $.ajax({
                url: self.validationUrl,
                type: 'post',
                data: JSON.stringify({
                    token: googleUser.getAuthResponse().id_token,
                    email: user.getEmail(),
                    name: user.getName(),
                    imageUrl: user.getImageUrl(),
                    provider: 'google'
                }),
                dataType: 'json',
                contentType: 'application/json; charset=utf-8'
            });

            request.done(function (response) {
                console.log('User logged in!');
                window.location.href = response.redirectUrl;
            });
        }, function (message) {
            alert('Error');
            console.log(message);
        });
    });
}

AccountsService.cs:

public async Task<User> LoginExternal(LoginExternal model)
{
    if (model.Provider == "google")
    {
        await LoginExternalGoogleValidate(model);
    }
    else
    {
        throw new InvalidOperationException("Provider not supported");
    }

    // add user if doesn't exists or get existing
    var user = ...;

    // set auth cookies or generate a token

    return user;
}

private async Task LoginExternalGoogleValidate(LoginExternal model)
{
    using (var httpClient = new HttpClient())
    {
        var googleApiUrl = ConfigurationManager.AppSettings["GoogleAuth.VerifyUrl"]
            .Replace("{token}", model.Token);

        var message = await httpClient.GetAsync(googleApiUrl);

        var result = await message.Content.ReadAsAsync<UserLoginExternalGoogleResult>();

        if (!result.EmailVerified || result.Email != model.Email 
              || result.Audience != ConfigurationManager.AppSettings["GoogleAuth.ClientId"])
        {
            throw new InvalidOperationException("Validation error");
        }
    }
}

LoginExternal.cs:

public class LoginExternal
{
    public string Provider { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string ImageUrl { get; set; }
    public string Token { get; set; }
}

LoginExternalModel.cs

public class LoginExternalModel
{
    public string Provider { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string ImageUrl { get; set; }
    public string Token { get; set; }
}

UserLoginExternalGoogleResult.cs:

public class UserLoginExternalGoogleResult
{
    public string Email { get; set; }

    [JsonProperty("email_verified")]
    public bool EmailVerified { get; set; }

    [JsonProperty("aud")]
    public string Audience { get; set; }
}

AccountController.cs:

[HttpPost]
public async Task<JsonResult> LoginExternal(LoginExternalModel model)
{
  var loginData = new LoginExternal
  {
      Name = model.Name,
      Email = model.Email,
      ImageUrl = model.ImageUrl,
      Provider = model.Provider,
      Token = model.Token
  };
  
  User user;

  try
  {
      user = await _accountsService.LoginExternal(loginData);
  }
  catch (Exception)
  {
      // failure
  }

  // success
  return Json(new { redirectUrl: "/" });
}

oauth-google's People

Contributors

kjeske avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.