Вопрос

I tried to use google federated login function to retrieve user info in order to implement an one-click registration functionality for my website.

I have retrieved all the information on the client side. I used several hidden input fields to store the values for the parameters like name,email, etc. However, when I accessed these fields from code behind, I got empty values.

Here are the steps I took to inspect the problem: 1. I have made sure that each input field has the [runat="server"] tag and have made sure that all the values are correctly returned from google. 2. I have made sure that all the input fields are inside the form

I am wondering if it is because I did not submit the form once I clicked the google+ login button, the button is as the following:

<div id="signin-button" class="slidingDiv">
 <div class="g-signin" data-callback="loginFinishedCallback"
  data-approvalprompt="force"
  data-clientid="....."
  data-scope="  https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/plus.me "
  data-height="short"
  data-cookiepolicy="single_host_origin"
  >
</div>
</div>

This button will lead me to other functions that verify about my credentials and return the parameters I request. I am wondering how I could modify it so that I could make the form be submitted once I click on this button?

If it is not caused by this issue, could anyone think of other possible reasons why I could not get the hidden input value from code behind?

Here is my callback function

 function loginFinishedCallback(authResult) {
      if (authResult) {
          if (authResult['error'] == undefined) {
              gapi.auth.setToken(authResult); 
              toggleElement('signin-button'); /
              getInfo();

              document.getElementById('Button').click();
          } else {
              console.log('An error occurred');
          }
      } else {
          console.log('Empty authResult');  
      }
  }

getInfo will get all the google plus information , and button.click() is supposed to retrieve the information from the client side to the server side

Это было полезно?

Решение

The Google+ Sign-In button currently does not POST form data but instead passes the authorization code and access token back to the page in the callback function configured in the button. You might be able to do something clever like use JavaScript to update a hidden field with the content (which you might already be doing?) and then use the data from that hidden field for OAuth 2 code exchange on your server side.

An alternate approach is used in the Google+ C# Quick Start sample. What that sample does is use an API endpoint to POST the authorization code that later is exchanged server-side for the OAuth 2 credentials.

I have thrown together some code that will pass the authorization code for authorizing your backend. It consists of the form frontend:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="fedLogin.aspx.cs"     Inherits="GPlusQuickstartCsharp.fedLogin" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <script type="text/javascript">
        var confirms = 0;
        function loginFinishedCallback(result) {
            console.log(result);
            if (result.access_token != null) {
              gapi.client.load('plus', 'v1', function(){
                gapi.client.load('oauth2', 'v2', function () {
                  gapi.client.plus.people.get({ userId: 'me' }).execute(
                    function (resp) {
                        document.getElementById('name').value = resp.displayName;
                        confirms += 1;
                        if (confirms > 1) {
                            document.getElementById('form1').submit();
                        }
                    });
              });
              gapi.client.load('oauth2', 'v2', function () {
                gapi.client.oauth2.userinfo.get().execute(
                    function (resp) {
                        document.getElementById('email').value = resp.email;
                        confirms += 1;
                        if (confirms > 1) {
                            document.getElementById('form1').submit();
                    }
                    });
                  });
                });
                document.getElementById('code').value = result.code;
            }
        }
    </script>
    <div id="signin-button" class="slidingDiv">
        <div class="g-signin" data-callback="loginFinishedCallback"
            data-clientid="....apps.googleusercontent.com"
            data-scope="https://www.googleapis.com/auth/userinfo.email"
            data-height="short"
            data-cookiepolicy="single_host_origin"
        >
    </div>
    </div>

    <form id="form1" runat="server" method="post">
    <div>
        <input type="hidden" name="code" id="code" />
        <input type="hidden" name="email" id="email" />
        <input type="hidden" name="name" id="name" />
    </div>
    </form>
</body>
<script type="text/javascript">
  (function () {
    var po = document.createElement('script');
    po.type = 'text/javascript'; po.async = true;
    po.src = 'https://plus.google.com/js/client:plusone.js';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(po, s);
  })();
</script>
</html>

And the code behind [C#]:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace GPlusQuickstartCsharp
{
    public partial class fedLogin : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request["code"] != null)
            {
                // Perform code exchange here
                var result = ManualCodeExchanger.ExchangeCode(Request["code"]);
            }

        }
    }
}

If you put a breakpoint at the var result = ... line, you can see the request variables in your immediate window, e.g.:

Request["code"]
"4/xUgz-_zWFAgpq4Kbfas66pV0oWJ8........."
Request["email"]
"gguuss@gmail.com"
Request["name"]
"Gus Class (Gus)"

Hope this helps!

Note: Although you need the client ID and client secret to exchange the one-time-code as demonstrated in the code, it's a best practice to protect it as best you can. I'm using a POST in an effort to protect the code in the form to help but you should also use https whenever you are passing around credentials.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top