Skip to content

a1div0/oauth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Статья на 1div0.ru

Общее описание

Данный модуль содержит механизм авторизации некоторого веб-приложения с получением данных о пользователе с помощью протокола OAuth2 через различные сервисы, поддерживающие этот протокол. В дальнейшем формируются куки с информацией о пользователе и CSRF-токеном. CSRF-токен простого типа, действует в пределах работы программы на сервере. Основу всего механизма составляет объект типа OAuthCollect, который содержит экземпляры интерфейсов OAuthorizator. Интерфейс OAuthorizator описывает каждый отдельный сервис авторизации (Yandex, Google и т. д.). Смысл в том, чтобы получить данные о пользователе (его идентификатор в сервисе, поддерживающим OAuth, его имя и адрес электронной почты). Записать их в базу данных и выдать некоторый токен. Пока есть токен - считать, что пользователь авторизован. Если токена нет - повторно его авторизовывать через OAuth.

Использование OAuthCollect

OAuthCollect содержит функцию инициализации Init(). Её нужно вызвать в первую очередь. Эта функция имеет следующие параметры:

  • VerificationCodeCallbackURL - тип string, в данном аргументе необходимо указать, по какому адресу сервер авторизации должен передать код авторизации.
  • DoneAuthUrl - тип string, в данном аргументе необходимо указать, какую страницу показать пользователю по окончании авторизации.
  • OnlyHttps - данный аргумент указывает, нужно ли передавать куки только по защищённому протоколу или нет.

Для добавления конкретных сервисов авторизации необходимо вызывать функцию AddService(). В качестве аргумента в неё передаётся объект соответствующий интерфейсу OAuthorizator.

Точкой старта процедуры инициализации является один из адресов (страница входа), который присваивается кнопке или ссылке. Эти адреса, принадлежащие каждому определённому сервису передаются в один из JS-скриптов в виде констант. Текст объявления констант получаем с помощью третьей функции GetSettingsJS(). Текст объявления адреса входа каждого сервиса имеет вид:
const OAUTH_%1_URL = "%2"; , где

  • %1 - имя сервиса капсом (YANDEX, GOOGLE и т. п.)
  • %2 - сам адрес (URL)

Полный пример использования выглядит так:

package main

// Раздел импорта
import (
    "fmt"
    "net/http"
    "bitbucket.org/aaklenov/oauth"
    "bitbucket.org/aaklenov/oauth_google"
)

var g_oauth oauth.OAuthCollect

func main() {

    err := g_oauth.Init("http://example.com:9000/oauth_verification_code", "http://example.com:9000", true)

    oauth_go := OAuthGoogle { // oauth_google.
        ClientId: "xxx.apps.googleusercontent.com",
        ClientSecret: "yyy",
    }
    g_oauth.AddService(&oauth_go)

    http.HandleFunc("/", HomeRouterHandler)
    err = http.ListenAndServe(":9000", nil)
    if err != nil {
        fmt.Println("ListenAndServe: ", err)
    }

}

func HomeRouterHandler(w http.ResponseWriter, r *http.Request) {

    if (r.URL.Path == "/js/settings.js") {
        oauth_settings := g_oauth.GetSettingsJS()
        fmt.Fprintf(w, oauth_settings)
    }

}

Интерфейс OAuthorizator

Объект интерфейса должен содержать три функции:

type OAuthorizator interface {
    ServiceName() (string)
    LoginURL(verification_code_callback_url string, state string) (string)
    OnRecieveVerificationCode(code string, u *UserData) (error)
}

Функция ServiceName() должна возвращать имя сервиса, например: google.

Функция LoginURL() должна возвращать адрес страницы, на которой пользователя спросят, разрешает он или нет такому-то веб-приложению доступ к имени и электронной почте. В ней передаётся адрес веб-приложения, куда нужно передать код авторизации. А также передаётся state - строка, которую нужно записать в одноимённый get-параметр адреса. В этой строке содержится имя сервиса и специальный токен, который помогает определить, что вызов по адресу verification_code_callback_url исходит именно от OAuth-сервиса, и соответственно параметры, передаваемые в нём, не нанесут вред (впрочем, значения параметров нигде не сохраняются и обычно передаются обратно в сервис "как есть").

Функция OnRecieveVerificationCode() вызывается, когда получен код авторизации и он проверен, что это именно он, а не посторонний вызов. При получении кода авторизации экземпля интерфейса должен запросить токен. А далее по токену - получить данные пользователя и передать их в структуру oauth.UserData. К заполнению требуется следующие поля:

  • ExtId, тип string - содержит идентификатор клиента в сервисе
  • Name, тип string - содержит имя пользователя
  • Email, тип string - содержит адрес электронной почты пользователя

Содержимое структуры:

type UserData struct {
    UserId int64
    Name string
    Email string
    ExtId string
    OAuthServiceName string
}

About

OAuth go-module

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages