跳到主要内容

20.5 使用用户服务和探索其 API

GAE 提供了几个基于 Google 基础设施的有用服务。正如第 20.1 节中提到的:GAE 提供了一个 Users 服务,它可以让你的应用程序与 Google 用户账户集成。有了用户服务,您的用户可以使用他们已经拥有的谷歌账户来登录您的应用程序。用户服务使您可以轻松地对该应用程序的问候语进行个性化处理。

编辑 helloworld2.go 文件,用以下 Go 代码替换它:

Listing 20.3 helloworld2_version2.go:

package hello

import (
"appengine"
"appengine/user"
"fmt"
"net/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)
}

通过在浏览器中重新加载页面来测试它。你的应用程序会给你一个链接,当你遵循这个链接时,会把你重定向到适合测试你的应用程序的本地版本的谷歌登录页面。你可以在这个页面中输入任何你喜欢的用户名,你的应用程序将看到一个基于该用户名的假的 user.User 值。当你的应用程序在 App Engine 上运行时,用户将被引导到 Google 账户的登录页面,然后在成功登录或创建账户后,会被重定向到你的应用程序。

用户API:

为了访问这个,我们需要导入一些专门针对 GAE 的 Go 包,即一般的 appengineappengine/user

在处理程序中,我们首先需要制作一个与当前请求r相关联的Context对象,这在一行中完成:

c := appengine.NewContext(r)

appengine.NewContext() 函数在这里返回一个名为 cappengine.Context 值:这是 Go App Engine SDK 中许多函数用来与 App Engine 服务通信的值。然后我们从这个上下文中测试是否已经有一个用户在此时登录,方法是:

 u := user.Current(c)

如果是这样的话,user.Current 会返回一个指向用户的 user.User 值的指针;否则会返回 nil。如果用户还没有登录,即 u == nil 时,通过调用用户的浏览器重定向到谷歌账户的登录界面。

url, err := user.LoginURL(c, r.URL.String())

第 2 个参数 r.URL.String() 是当前请求的 url,这样谷歌账户登录机制可以在成功登录后进行重定向:它将在用户登录或注册新账户后将其送回这里。登录界面的发送是通过设置一个 Location 数据头并返回一个 HTTP 状态代码 302“Found”来完成的。

LoginURL() 函数返回一个 error 值作为其第二个参数。尽管这里不太可能发生错误,但检查它并在适当的时候向用户显示错误是很好的做法(在这种情况下,用 http.Error helper):

if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

当用户登录后,我们使用与用户账户相关的名字显示一条个性化的信息:

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

在这种情况下,fmt.Fprintf() 函数调用 *user.UserString() 方法来获得字符串形式的用户名称。更多信息可以在这个参考资料中找到:http://code.google.com/appengine/docs/go/users/