Files
the-way-to-go_ZH_CN/eBook/20.5.md
Haigang Zhou 1573212775 第二十章和第二十一章的翻译 (#831)
Co-authored-by: Joe Chen <jc@unknwon.io>
2022-05-19 20:05:42 +08:00

89 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 20.5 使用用户服务和探索其 API
GAE 提供了几个基于 Google 基础设施的有用服务。正如[第 20.1 节](20.1.md)中提到的GAE 提供了一个 Users 服务,它可以让你的应用程序与 Google 用户账户集成。有了用户服务,您的用户可以使用他们已经拥有的谷歌账户来登录您的应用程序。用户服务使您可以轻松地对该应用程序的问候语进行个性化处理。
编辑 helloworld2.go 文件,用以下 Go 代码替换它:
<u>[Listing 20.3 helloworld2_version2.go](examples/chapter_20/helloapp/hello/helloworld2_version2.go)</u>:
```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 账户的登录页面,然后在成功登录或创建账户后,会被重定向到你的应用程序。
<u>用户API</u>
为了访问这个,我们需要导入一些专门针对 GAE 的 Go 包,即一般的 `appengine``appengine/user`
在处理程序中我们首先需要制作一个与当前请求r相关联的Context对象这在一行中完成
```go
c := appengine.NewContext(r)
```
`appengine.NewContext()` 函数在这里返回一个名为 `c``appengine.Context` 值:这是 Go App Engine SDK 中许多函数用来与 App Engine 服务通信的值。然后我们从这个上下文中测试是否已经有一个用户在此时登录,方法是:
```go
u := user.Current(c)
```
如果是这样的话,`user.Current` 会返回一个指向用户的 `user.User` 值的指针;否则会返回 `nil`。如果用户还没有登录,即 `u == nil` 时,通过调用用户的浏览器重定向到谷歌账户的登录界面。
```go
url, err := user.LoginURL(c, r.URL.String())
```
第 2 个参数 `r.URL.String()` 是当前请求的 url这样谷歌账户登录机制可以在成功登录后进行*重定向*:它将在用户登录或注册新账户后将其送回这里。登录界面的发送是通过设置一个 Location 数据头并返回一个 HTTP 状态代码 302“Found”来完成的。
`LoginURL()` 函数返回一个 error 值作为其第二个参数。尽管这里不太可能发生错误,但检查它并在适当的时候向用户显示错误是很好的做法(在这种情况下,用 http.Error helper
```go
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
```
当用户登录后,我们使用与用户账户相关的名字显示一条个性化的信息:
```go
fmt.Fprintf(w, "Hello, %v!", u)
```
在这种情况下,`fmt.Fprintf()` 函数调用 `*user.User``String()` 方法来获得字符串形式的用户名称。更多信息可以在这个参考资料中找到http://code.google.com/appengine/docs/go/users/
## 链接
- [目录](directory.md)
- 上一节:[建造你自己的 Hello world 应用](20.4.md)
- 下一节:[处理窗口](20.6.md)