English ▼
Skip to page content Skip to main navigation
e.g. "templates" or "datastore"

# Using the Users Service

Google App Engine provides several useful services based on Google infrastructure. One example is the Users service, which lets your application integrate with Google user accounts. With the Users service, your users can employ the Google accounts they already have to sign in to your application.

The Users service makes it easy to personalize this application's greeting.

## Using Users

Edit `myapp/hello/hello.go` again, and replace its contents with the following:

    package hello

    import (
        "appengine"
        "appengine/user"
        "fmt"
        "http"
    )

    func init() {
        http.HandleFunc("/", handler)
    }

    func handler(w http.ResponseWriter, r *http.Request) {
        c := appengine.NewContext(r)
        u := user.Current(c)
        if u == nil {
            url, err := user.LoginURL(c, r.URL.String())
            if err != nil {
                http.Error(w, err.String(), http.StatusInternalServerError)
                return
            }
            w.Header().Set("Location", url)
            w.WriteHeader(http.StatusFound)
            return
        }
        fmt.Fprintf(w, "Hello, %v!", u)
    }

Reload the page in your browser. Your application presents you with a link that, when followed, will redirect you to the local version of the Google sign-in page suitable for testing your application. You can enter any username you'd like in this screen, and your application will see a fake `user.User` value based on that username.

When your application is running on App Engine, users will be directed to the Google Accounts sign-in page, then redirected back to your application after successfully signing in or creating an account.

## The Users API

Let's take a closer look at the new pieces:

    c := appengine.NewContext(r)

The `appengine.NewContext` function returns an `appengine.Context` value associated with the current request. This is an opaque value used by many functions in the Go App Engine SDK to communicate with the App Engine service.

    u := user.Current(c)

If the user is already signed in to your application, `user.Current` returns a pointer to a `user.User` value for the user. Otherwise, it returns `nil`.

    if u == nil {
        url, err := user.LoginURL(c, r.URL.String())
        if err != nil {
            http.Error(w, err.String(), http.StatusInternalServerError)
            return
        }
        w.Header().Set("Location", url)
        w.WriteHeader(http.StatusFound)
        return
    }

If the user has not signed in, redirect the user's browser to the Google account sign-in screen by setting a `Location` header and returning an HTTP status code of 302 "Found". The redirection includes the URL to this page (`r.URL.String()`) so the Google account sign-in mechanism will send the user back here after signing in or registering for a new account.

The `user.LoginURL` function returns an `os.Error` value as its second argument. Though an error is unlikely to occur here, it is good practice to check it and display an error user, if appropriate (in this case, with the `http.Error` helper).

    fmt.Fprintf(w, "Hello, %v!", u)

If the user has signed in, display a personalized message using the name associated with the user's account. In this case, the `fmt.Fprintf` function calls `*user.User`'s `String` method to get the user's name in string form.

For more information about the Users API, see the Users reference.

Note: for specific paths that should be served only to logged in users, use the `login: required` directive in the `app.yaml` file. See the the app.yaml reference for details.

## Next...

Our application can now greet visiting users by name. Let's add a feature that will let users greet each other.

Continue to Handling Forms.