Dark Mirea Login - авторизация через МИРЭА для ваших проектов

Представляем Dark Mirea Login :lock:

Привет! Мы создали oauth2 сервер, основанный на скрытой аутентификации, который позволяет студентам МИРЭА легко и безопасно авторизовывать пользователей в своих проектах.

Что такое OAuth 2.0? :thinking:

OAuth 2.0 - это стандарт авторизации, который позволяет выдавать ограниченный доступ к защищенным ресурсам пользователя на стороннем сервисе или приложении, без необходимости передавать логин и пароль. OAuth 2.0 широко используется такими компаниями как Google, Facebook, Microsoft и многими другими для организации процесса аутентификации.

Возможности Dark Mirea Login :bulb:

Наш “Dark Mirea Login” реализует этот протокол в обход login.mirea.ru (с использованием скрытых механизмов) и дает возможность студентам использовать единую учетную запись МИРЭА для входа в различные сервисы и приложения. Это упрощает процесс регистрации и входа для пользователей. А разработчикам больше не нужно реализовывать свою систему аутентификации в каждом проекте. :sunglasses:

Вот что можно с этим сделать (идеи):

  1. :robot: Чат-боты для студентов в Telegram или VK, которые будут ограничивать доступ к публичным чатам (пускать только студентов)

  2. :speech_balloon: Сервис для обмена приватными сообщениями между студентами с возможностью шифрования и ограничения доступа.

  3. :ballot_box: Платформа для проведения опросов, голосований среди студентов с возможностью ограничения участников по различным критериям.

  4. :books: Сервис обмена учебными материалами, где студенты могут делиться конспектами, книгами, решениями задач с доступом только для своей группы или курса.

  5. :handshake: Платформа для поиска команды для проектов или стартапов среди студентов МИРЭА с верификацией профилей через Dark Mirea Login.

  6. :art: Онлайн-галерея творческих работ студентов МИРЭА (дизайн, фото, видео) с возможностью комментирования и оценки только для авторизованных пользователей.

  7. :briefcase: Доска объявлений о стажировках и вакансиях, доступная только для студентов МИРЭА определенных специальностей и курсов.

  8. :iphone: Различные мобильные приложения для студентов университета.

Технические особенности :hammer_and_wrench:

Одна из особенностей нашего решения - публичные oauth-клиенты. Это значит, что параметры client_id и client_secret для всех приложений имеют одинаковое значение 'public'. Таким образом упрощается процесс интеграции, не нужно запрашивать и хранить уникальные ключи.

  • Base URL - https://login.mirea.ninja
  • Login URL - https://login.mirea.ninja/login

Endpoints:

  • /oauth/authorize - запрос авторизации
  • /oauth/token - получение access токена
  • /oauth/userinfo - получение информации о пользователе

Формат userinfo:

{
  "id": 12345,
  "name": "Иванов Иван",
  "email": "ivanov@mirea.ru",
  "group": "ИКБО-01-20",
  "personal_number": "12345678",
  "full_name": "Иванов Иван Иванович"
}

Пример реализации клиента на Go

  1. Запустите файл с помощью go run ...
  2. Откройте http://localhost:9094/
package main

import (
  "context"
  "crypto/sha256"
  "encoding/base64"
  "encoding/json"
  "fmt"
  "io"
  "log"
  "net/http"
  "time"

  "golang.org/x/oauth2"
  "golang.org/x/oauth2/clientcredentials"
)

const (
  authServerURL = "https://login.mirea.ninja"
)

var (
  config = oauth2.Config{
    ClientID:     "public",
    ClientSecret: "public",
    Scopes:       []string{"all"},
    RedirectURL:  "http://localhost:9094/oauth2",
    Endpoint: oauth2.Endpoint{
      AuthURL:  authServerURL + "/oauth/authorize",
      TokenURL: authServerURL + "/oauth/token",
    },
  }
  globalToken *oauth2.Token
)

func main() {
  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    u := config.AuthCodeURL("xyz",
      oauth2.SetAuthURLParam("code_challenge", genCodeChallengeS256("s256example")),
      oauth2.SetAuthURLParam("code_challenge_method", "S256"))

    w.Header().Set("Content-Type", "text/html")
    fmt.Fprintf(w, `<html><body><a href="%s">Login with MIREA</a></body></html>`, u)
  })

  http.HandleFunc("/oauth2", func(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()
    state := r.Form.Get("state")
    if state != "xyz" {
      http.Error(w, "State invalid", http.StatusBadRequest)
      return
    }
    code := r.Form.Get("code")
    if code == "" {
      http.Error(w, "Code not found", http.StatusBadRequest)
      return
    }
    token, err := config.Exchange(context.Background(), code, oauth2.SetAuthURLParam("code_verifier", "s256example"))
    if err != nil {
      http.Error(w, err.Error(), http.StatusInternalServerError)
      return
    }
    globalToken = token

    e := json.NewEncoder(w)
    e.SetIndent("", "  ")
    e.Encode(token)
  })

  http.HandleFunc("/refresh", func(w http.ResponseWriter, r *http.Request) {
    if globalToken == nil {
      http.Redirect(w, r, "/", http.StatusFound)
      return
    }

    globalToken.Expiry = time.Now()
    token, err := config.TokenSource(context.Background(), globalToken).Token()
    if err != nil {
      http.Error(w, err.Error(), http.StatusInternalServerError)
      return
    }

    globalToken = token
    e := json.NewEncoder(w)
    e.SetIndent("", "  ")
    e.Encode(token)
  })

  http.HandleFunc("/userinfo", func(w http.ResponseWriter, r *http.Request) {
    if globalToken == nil {
      http.Redirect(w, r, "/", http.StatusFound)
      return
    }

    req, err := http.NewRequest("GET", authServerURL+"/oauth/userinfo", nil)
    if err != nil {
      http.Error(w, err.Error(), http.StatusInternalServerError)
      return
    }

    req.Header.Set("Authorization", "Bearer "+globalToken.AccessToken)
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
      http.Error(w, err.Error(), http.StatusInternalServerError)
      return
    }

    defer resp.Body.Close()
    io.Copy(w, resp.Body)
  })

  log.Println("Started...")
  log.Fatal(http.ListenAndServe(":9094", nil))
}

func genCodeChallengeS256(s string) string {
  s256 := sha256.Sum256([]byte(s))
  return base64.URLEncoding.EncodeToString(s256[:])
}

Безопасность превыше всего :shield:

Мы со всей ответственностью подходим к вопросам безопасности и приватности пользовательских данных. Мы не храним логи и пароли пользователей, а также любые другие данные.

https://login.mirea.ninja/login

4 Likes