Использование AppEngine / Go Users API с OAuth: пример кода, рабочий процесс, любая помощь? - PullRequest
6 голосов
/ 03 ноября 2011

Хотя у меня очень большой опыт работы со средой исполнения AppEngine / Python, я новичок в среде исполнения Go. Мое первое приложение почти готово к развертыванию, но мне все еще нужно предоставить пользователю возможность войти в систему. Я надеюсь использовать OpenID, так как я бы не хотел, чтобы у пользователя был Google Id.

Однако, похоже, что там нет или почти нет рабочих примеров, и в простоте документации AppEngine пропущено содержание функции, которую мне нужно реализовать:

func init() {
    http.HandleFunc("/_ah/login_required", openIdHandler)
}

func openIdHandler(w http.ResponseWriter, r *http.Request) {
    // ...
}

Что входит в openIdHandler функцию?

Я понимаю, что мне нужно предоставить страницу, которая позволит пользователю выбрать одного из множества поставщиков OpenId и ввести свой Id для этой системы. Я просто не знаю, что делать после этого. Каков рабочий процесс? Кто-нибудь знает какой-нибудь пример кода, на который я могу посмотреть, чтобы получить общее представление о том, что я должен делать и с какими данными я должен обрабатывать? Все мои отточенные гугл-фу ни к чему меня не привели.

Для ясности, я не собираюсь взаимодействовать с какими-либо услугами, предоставляемыми этими поставщиками OpenId; Я не хочу создавать твиты или Buzz. Я не хочу получать доступ к контактам, документам, сообщениям на стене или чему-либо еще. Я просто хотел иметь аутентифицированные учетные данные, которые я могу использовать внутри своего приложения, чтобы ограничить доступ пользователей только к его или ее собственным данным.

1 Ответ

10 голосов
/ 10 ноября 2011

Если я вас хорошо понял - вам нужно , а не .Я переписал пример Python ( Федеративный вход и выход ) для go-lang.Надеюсь, что это поможет.

package gae_go_openid_demo

import (
    "fmt"
    "os"
    "http"

    "appengine"
    "appengine/user"
)

func init() {
    http.HandleFunc("/", hello)
    http.HandleFunc("/_ah/login_required", openIdHandler)
}

func hello(w http.ResponseWriter, r *http.Request) {
    c := appengine.NewContext(r)
    u := user.Current(c)
    if u != nil {
        url, err := user.LogoutURL(c, "/")
        check(err);
        fmt.Fprintf(w, "Hello, %s! (<a href='%s'>Sign out</a>)", u, url)
    } else {
        fmt.Fprintf(w, "Please, <a href='/_ah/login_required'>login</a>.")
    }

}

func openIdHandler(w http.ResponseWriter, r *http.Request) {
    providers := map[string]string {
        "Google"   : "www.google.com/accounts/o8/id", // shorter alternative: "Gmail.com"
        "Yahoo"    : "yahoo.com",
        "MySpace"  : "myspace.com",
        "AOL"      : "aol.com",
        "MyOpenID" : "myopenid.com",
        // add more here
    }

    c := appengine.NewContext(r)
    fmt.Fprintf(w, "Sign in at: ")
    for name, url := range providers {
        login_url, err := user.LoginURLFederated(c, "/", url)
        check(err);
        fmt.Fprintf(w, "[<a href='%s'>%s</a>]", login_url, name)
    }
}

// check aborts the current execution if err is non-nil.
func check(err os.Error) {
    if err != nil {
        panic(err)
    }
}
...