Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go client to access GAE login required apps

I wanted to authenticate myself (Google Account) using a golang client against protected apps on Google App Engine where login: required or login: admin is specified in app.yaml.

First I wrote a simple OAuth2 offline access client but it didn't work at all - the server just redirects clients to Google Account's sign in page. I've tried with various Google API scopes and currently no luck.

package main

import (
    "context"
    "fmt"
    "io"
    "log"
    "os"

    "golang.org/x/oauth2"
    "golang.org/x/oauth2/google"
)

const (
    AppURL           = "https://login-requried-app.appspot.com"
    AuthClientID     = "....."
    AuthClientSecret = "....."
    AuthRedirectURL  = "urn:ietf:wg:oauth:2.0:oob"
    AuthScope        = "https://www.googleapis.com/auth/cloud-platform"
)

func main() {
    ctx := context.Background()
    conf := &oauth2.Config{
        ClientID:     AuthClientID,
        ClientSecret: AuthClientSecret,
        Endpoint:     google.Endpoint,
        RedirectURL:  AuthRedirectURL,
        Scopes:       []string{AuthScope},
    }

    url := conf.AuthCodeURL("state", oauth2.AccessTypeOffline)
    fmt.Printf("Visit the URL for the auth dialog: %v\n", url)
    fmt.Printf("Enter authentication code: ")

    var code string
    if _, err := fmt.Scan(&code); err != nil {
        log.Fatal(err)
    }
    tok, err := conf.Exchange(ctx, code)
    if err != nil {
        log.Fatal(err)
    }

    client := conf.Client(ctx, tok)

    res, err := client.Get(AppURL)
    if err != nil {
        log.Fatal(err)
    }
    defer res.Body.Close()

    log.Println(res.Status)
    io.Copy(os.Stdout, res.Body)
}

I'm looking for the details of GAE's user authentication modes used in such apps to write a non web browser client. I feel it's something different than standard OAuth2 authentication/authorization after reading App Engine Users API docs and code that is receiving user information via HTTP headers like X-AppEngine-User-Email.

  • Users Go API Overview
  • google.golang.org/appengine/user package document
  • user.Current() implementation (it's for flex env but almost the same in standard env)

UPDATE: After some research it looks like the GAE frontend uses SACSID cookie for tracking authenticated sessions, which isn't related to the OAuth2 standard. Indeed as stated in Users Go API document:

Note that using OAuth to identify your users is completely orthogonal to the standard user authentication modes. For example, pages marked with login: required or login: admin will refuse to load if the user is only authenticated via OAuth.

Is there any supported way for a CLI application to acquire SACSID properly authorized by user's consent?

Related questions:

  • Access an App Engine app from command line using OAuth2?
  • On Google App Engine, can I relate a Google OAuth 2 Token and a SACSID token I got using Android's AccountManager?
like image 307
yaegashi Avatar asked Feb 09 '18 08:02

yaegashi


People also ask

What is authorized JavaScript origins Google?

An origin is a unique combination of protocol, hostname, and port. In the Authorized JavaScript origins field, enter the origin for your app. You can enter multiple origins to allow for your app to run on different protocols, domains, or subdomains. You cannot use wildcards.

Does Google support pkce?

Google's documentation for "Mobile and Desktop apps" does direct developers to use a PKCE Authorization Code flow. Clients using Google Android, iOS or windows store credential types with PKCE may omit the client_secret (see the note on the refresh token parameter table - and confirmed by Cristiano).

What is Go App Engine?

Google App Engine is a service and a platform where you can develop and host web applications. You can learn more about Google App Engine at the official Google App Engine site. With App Engine integration, you can run and debug Google App Engine applications. A new project already includes app.


1 Answers

Given the situation you explain here, I suggest using a remote API. This way you can access App Engine services from your Go app.

First you have to configure your app.yaml file by adding the following:

- url: /_ah/remote_api
  script: _go_app

You also have to add the following import to your .go source file:

import _ "google.golang.org/appengine/remote_api"

When this is done, deploy your updated app to App Engine:

gcloud app deploy app.yaml

The website I included here includes an example on how to use the remote API. You can try it and adapt your code if this works for you.

like image 159
Rodrigo C. Avatar answered Oct 22 '22 14:10

Rodrigo C.