2

I am trying to link to the account :

Here is my google cloud function

var AuthHandler = function() {
    this.googleSignIn = googleSignIn;
    this.googleSignInCallback = googleSignInCallback;

}

function googleSignIn(req, res, next) {
    passport = req._passport.instance;

    passport.authenticate('google',{scope: 'https://www.googleapis.com/auth/userinfo.email',
    state:"google",response_type:"token"},

    function(err, user, info) {
console.log(user);
    })(req,res,next);

};

function googleSignInCallback(req, res, next) {
    passport = req._passport.instance;
    passport.authenticate('google',function(err, user, info) {
        if(err) {
            return next(err);
        }
        if(!user) {
            return res.redirect('http://localhost:8000');
        }
        console.log(user._json.token);
        // /res.redirect('/');
       res.redirect('https://oauth-redirect.googleusercontent.com/r/xxxxxx#access_token=' + user._json.token + '&token_type=bearer&state=google')


    })(req,res,next);
};

module.exports = AuthHandler; 

In google Action Console :

I have created the implicit flow and gave my authorisation url as follows:

https://[region]-[projectid].cloudfunctions.net/[functionname]/auth/google

Error :

this is the browser Url

https://assistant.google.com/services/auth/handoffs/auth/complete?state=xxxx&code=xxxxxx

on which the following error is displayed

The parameter "state" must be set in the query string.

Update 1

Before starting this implementation , i have followed this Solution to create the Authentication.

Problems in this Approach :

1.As stated in the Documentation it is not redirecting to google.com and i'm unable to access the token using the APIAI SDK in javascript. but still i can see the Access token in emulator . for better understanding adding images

Unable to redirect to the Google

Here is my simulator O/P

{

  "response": {

  "debug": {
    "agentToAssistantDebug": {

    "assistantToAgentDebug": {
      "assistantToAgentJson": "{"accessToken\":\"xxxxxx\""
    }
  },
  "errors": []
}

Update 2 :

So i have started creating with implicit flow and here is my complete repo

Krsna Kishore
  • 8,233
  • 4
  • 32
  • 48
  • I'm not clear what these functions are or what is calling them. Are they supposed to be an OAuth2 server? Are they supposed to be called as the Action webhook? – Prisoner Sep 25 '17 at 16:02
  • @Prisoner , yes, i'm trying to create the Oauth server , i have followed your previous answer [this](https://stackoverflow.com/questions/44288981/how-to-authenticate-user-with-just-a-google-account-on-actions-on-google) , let me update these details in question so that you can go through them easily – Krsna Kishore Sep 25 '17 at 16:05

2 Answers2

2

After battling with it i have achieved it , as there is no proper articles about creation of own Oauth Server that implements the Google Action , this might helpful for future users.

Authorization Endpoint

  app.get('/authorise', function(req, res) {
     req.headers.Authorization = 'Bearer xxxxxxxxxxx';
      // with your own mechanism after successful
        //login you need to create a access token for the generation of 
     //authorization code and append it to this header;

    var request = new Request(req);
    var response = new Response(res);

     oauth.authorize(request, response).then(function(success) {     
     // https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID?
      //code=AUTHORIZATION_CODE&state=STATE_STRING
      var toredirect = success.redirectUri +"?code="+success.code 
            +"&state="+request.query.state ;
      return res.redirect(toredirect);  
    }).catch(function(err){
      res.status(err.code || 500).json(err)
    }) });

Token Endpoint :

 app.all('/oauth/token', function(req,res,next){
    var request = new Request(req);
    var response = new Response(res);

    oauth
      .token(request,response)
      .then(function(token) {
        // Todo: remove unnecessary values in response
        return res.json(token)
      }).catch(function(err){
        return res.status(500).json(err)
      })
  });

After creation of this endpoints publish to the Google Cloud functions . I have used MYSQL as the DB using SEQUELIZE and Oauth-Server , if anyone need those models , will share it through repo .

With this you can able to link account using your own Server which implements Auth tokens and Access Tokens

Krsna Kishore
  • 8,233
  • 4
  • 32
  • 48
  • you refer to AUTHORIZATION_CODE - but where does this come from? – Jason Silver Feb 02 '18 at 05:05
  • 1
    @JasonSilver this is auto generated by the resource serve – Krsna Kishore Feb 02 '18 at 05:44
  • I think this really needs to mention that the secret sauce is that the "access_token" parameter should be called "code" instead, as well as the # being ? to denote the query start (but this last bit is actually fixed in their latest docs, it's jsut the access-token bit that's wrong) – Force Gaia Jul 18 '19 at 13:33
1

I think the problem is that the URL on this line isn't sending the parameters as query parameters, they're sending them as part of the anchor:

res.redirect('https://oauth-redirect.googleusercontent.com/r/xxxxxx#access_token=' + user._json.token + '&token_type=bearer&state=google')

You should replace the # with a ?, as illustrated here:

res.redirect('https://oauth-redirect.googleusercontent.com/r/xxxxxx?access_token=' + user._json.token + '&token_type=bearer&state=google')
Prisoner
  • 49,922
  • 7
  • 53
  • 105
  • now a different error message `Accounts failed to link. Please close your browser and try again` – Krsna Kishore Sep 25 '17 at 15:39
  • Please update the original question to add what you change and what the results are after changes. You may also want to clarify what, exactly, you are doing to generate each error. – Prisoner Sep 25 '17 at 16:01
  • @Prisioner i have updated my question with the changes what i have done , and created a demo_app what i am trying to do .. thanks – Krsna Kishore Sep 25 '17 at 16:46